文章目錄
- 目標
- 注意
- exec.Command
- tar
- 代碼
- 結果
目標
piveroot切換工作目錄到/merged后,通過docker commit將此時工作目錄的文件系統保存下來,使用tar包將該文件系統打包為tar文件
命令類似 ./mydocker commit myimage
然后當前目錄下會得到myimage.tar
注意
- 執行commit操作是在另一個終端執行的,也就是說容器已啟動并運行,此時在另一個終端執行commit操作的時候不需要在掛載或啟動子進程等操作,直接是設置一個位置來存,而不是像之前一樣聯合掛載后再得到具體的工作目錄地址了
exec.Command
exec.Command("tar", "-czf", imageTar, "-C", mntPath, ".").CombinedOutput()
這段代碼是使用Go語言的標準庫os/exec
來執行一個外部命令,具體是調用tar
命令來創建一個壓縮的歸檔文件。這里是逐部分解釋:
-
exec.Command
: 這是Go語言中用于創建并運行外部命令的對象。它接受一個可變數量的字符串參數,第一個參數是命令名,后面的參數是傳遞給該命令的各個選項和參數。 -
"tar"
: 這是命令本身,tar
是一個用于創建、讀取、更新和管理歸檔文件的工具。 -
"-czf"
: 這些是傳遞給tar
命令的選項。-c
表示創建一個新的歸檔文件。這意味著你要使用 tar 命令來打包當前目錄下一系列文件和目錄成為一個單一的歸檔文件(通常是以 .tar 結尾)。這個過程不會對文件進行壓縮,只是簡單地將它們收集在一起形成一個歸檔文件,便于管理和傳輸。-z
表示在創建歸檔文件時進行gzip壓縮。結合-c
,這會創建一個.tar.gz
格式的壓縮歸檔文件。-f
后面跟歸檔文件的名稱。注意,由于-f
需要直接跟著文件名,所以在參數列表中,imageTar
變量將會作為此選項的值。
-
imageTar
: 這是一個變量,代表要創建的歸檔文件的名稱(包括路徑)。例如,如果imageTar
的值為/path/to/image.tar.gz
,那么這個歸檔文件就會被創建在指定路徑,并命名為image.tar.gz
。 -
"-C"
: 這個選項告訴tar
在執行操作前先切換到指定的目錄。這里的指定目錄由接下來的參數決定。 -
mntPath
: 這也是一個變量,代表一個目錄路徑。結合-C
選項,它指定了tar
執行操作前應先切換到的目錄。例如,如果mntPath
的值為/mnt/mydir
,則會在執行打包操作前進入該目錄。 -
"."
: 這是一個點字符,代表當前目錄。在tar
命令的上下文中,它意味著打包當前目錄下的所有內容。由于之前使用了-C
指定了目錄,這里的“當前目錄”就是mntPath
所指的目錄。 -
.CombinedOutput()
: 這個方法用來執行上述構造的命令,并捕獲其標準輸出和標準錯誤的組合輸出。返回的是一個字節切片,包含命令執行后的輸出文本。這在調試或需要處理命令輸出的場景中非常有用。
綜上所述,這段代碼的功能是:在Go程序中執行一個命令,使用tar
工具將mntPath
目錄下的所有內容打包成一個gzip壓縮的歸檔文件,并保存為imageTar
變量指定的路徑和文件名。
tar
tar
: 是 tape archive 的縮寫,是一個用于創建、提取和查看 tarball(.tar 文件)的工具。-t
選項:表示列出(list)tar 文件內的內容。當你對一個 .tar 文件使用-t
選項時,tar 命令將會輸出該歸檔文件中所有文件和目錄的列表,但并不解壓或提取它們。-f
選項:后面跟需要操作的 tar 文件名。-f
是 file 的縮寫,用來指定要處理的歸檔文件。
所以,當你運行 tar -tf somefile.tar
命令時,它會列出 somefile.tar
這個歸檔文件內部的所有文件和目錄結構,每一項占一行,但并不會展開或提取這個歸檔文件的實際內容。這對于快速檢查一個 tar 文件包含哪些內容而不需要真正提取它非常有用。
代碼
https://github.com/FULLK/llkdocker/tree/main/commit_docker
增加一個command
func main(){//定義相關命令app:=cli.NewApp()app.Name="llkdocker"app.Usage="my simple docker -llkdocker "app.Commands=[]cli.Command{runcommand,initcommand,commitcommand,}//Commands 屬性是一個 []cli.Command 類型的切片app.Before=func(context *cli.Context)error{log.SetFormatter(&log.JSONFormatter{})log.SetOutput(os.Stdout)return nil} //在處理命令參數之前先進行的函數if err:=app.Run(os.Args);err!=nil{log.Fatal(err)}
}
判斷參數個數,并最后做出相應執行
var commitcommand = cli.Command{Name: "commit",Usage: "commit image",Action: func(context *cli.Context)error {args := context.Args()//commit后參數的作為這里if len(args)<1 {log.Fatal("missing the image name you want to save ")}log.Info(args)contain.Contain_commit(args)return nil},
}
這里注意tar打包好像最后只能生成一個tar文件
func Contain_commit(imagename []string){mnturl:="/home/llk/Desktop/llkdocker/commit_docker/merged"rooturl:="/home/llk/Desktop/llkdocker/commit_docker"/*var params stringfor i := 0; i < len(imagename); i++ {param := rooturl+"/"+imagename[i]+".tar "params =params+param } //得到參數log.Info(params) //類似 路徑/1.tar 路徑/2.tar 但一次只能生成一個鏡像*/imagetar:=rooturl+"/"+imagename[0]+".tar"log.Info(imagetar)if len(imagename)>1{log.Infof("too many image name ,we only can tar the first")}if _,err:=exec.Command("tar","-czf",imagetar,"-C",mnturl,".").CombinedOutput();err!=nil{log.Info(err)log.Fatal("tar error !!!") //好像一次只能生成一個tar包 }log.Info("commit finish") //tar需要一定時間,這里做最后結束的回現}
結果
先在一個終端啟動
然后再啟動另一個終端commit