1. 程式人生 > >Docker Toolbox建立虛擬機器時 --virtualbox-share-folder 共享目錄引數的正確用法

Docker Toolbox建立虛擬機器時 --virtualbox-share-folder 共享目錄引數的正確用法

Docker Toolbox建立虛擬機器時 --virtualbox-share-folder 共享目錄引數的正確用法

引數用途:

在使用docker-machine 建立虛擬機器時,帶上引數 --virtualbox-share-folder,實現宿主機和虛擬機器之間共享目錄,進而實現宿主機、虛擬機器、容器三者之間共享目錄。比如,將Windows7上的網站頁面檔案放到C:\www目錄下,建立虛機,啟動httpd容器,釋出一個Web網站。在Windows7上更新網站頁面後,自動更新網站的內容。DockerToolbox的版本必須要17.05.0版本以後才行,字串中兩個冒號的Bug在machine 0.10版中才得到修復。

正確用法:

docker-machine create \

-d virtualbox \

--virtualbox-share-folder "c:\www:c/www" \

test

  

相關說明:

1、預設不帶引數時,宿主機會自動將c:\Users目錄共享到虛擬機器的/c/Users目錄。

2、使用該引數後,預設共享被替換,最終虛擬機器只有一個/c/www共享目錄。

3、虛擬機器執行容器時,加上-v /c/www:/www,即可將宿主機的目錄掛載到容器中。

4、如需要使用多個目錄,可以使用vboxmanager.exe 程式實現自動建立。

5、字串中兩個冒號導致的問題(碟符冒號和分隔符冒號沒有得到很好處理)

0.10版的machine中得到修復,(2017227).我使用的Dockertoolbox 17.03.0版本,剛剛釋出,內建的machine 還是0.9版的,bug依然存在,後來更換17.05.0版本後,內建的machine 0.11版本的,問題已經得到修復。


踩坑過程:

1、在建立虛擬機器的命令中,嘗試了以下字串,由於我使用的Dockertoolbox是17.03.0,內建的machine 版本是0.9版,存在Bug,所有無論怎麼嘗試,都沒成功。

"c:\www:/www"

"\\?\c:\html:html"

"html:\\\\?\\c"    

"\\\\?\\c:\\html:html"    

"c/html:\\\\?\\c"

"\\\\?\\c:c:rw"     

"\\\\?\\c:c"     

"\\\\?\\c::c"

"/c:c"     

"/c/html:c/html"

2、獲取宿主機路徑和虛擬機器共享名的函式,第94行:

https://github.com/docker/machine/blob/e1a03348ad83d8e8adb19d696bc7bcfb18ccd770/drivers/virtualbox/virtualbox_windows.go#L94

func getShareDriveAndName() (string, string) {

return "c/Users", "\\\\?\\c:\\Users"

}

3、虛擬機器共享目錄和宿主機共享路徑的獲取函式程式碼段,453行:

https://github.com/docker/machine/blob/master/drivers/virtualbox/virtualbox.go#L453

shareName, shareDir := getShareDriveAndName()

4、對字串中兩個冒號進行處理的函式程式碼位置(virtualbox.go中的第486行):

https://github.com/docker/machine/blob/master/drivers/virtualbox/virtualbox.go#L486

func parseShareFolder(shareFolder string) (string, string) {

split := strings.Split(shareFolder, ":")

shareDir := strings.Join(split[:len(split)-1], ":")

shareName := split[len(split)-1]

return shareDir, shareName

}

 

5、相關程式碼段:

shareName, shareDir :=getShareDriveAndName()

if d.ShareFolder != "" {

shareDir, shareName = parseShareFolder(d.ShareFolder)

}

if shareDir != "" && !d.NoShare {

log.Debugf("setting up shareDir '%s' -> '%s'", shareDir, shareName)

if _, err := os.Stat(shareDir); err != nil && !os.IsNotExist(err) {

return err

} elseif !os.IsNotExist(err) {

if shareName == "" {

// parts of the VBox internal code are buggy with share names that start with "/"

shareName = strings.TrimLeft(shareDir, "/")

// TODO do some basic Windows -> MSYS path conversion

// ie, s!^([a-z]+):[/\\]+!\1/!; s!\\!/!g

}

// woo, shareDir exists! let's carry on!

if err := d.vbm("sharedfolder", "add", d.MachineName, "--name", shareName, "--hostpath", shareDir, "--automount"); err != nil {

return err

}

// enable symlinks

if err := d.vbm("setextradata", d.MachineName, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/"+shareName, "1"); err != nil {

return err

}

}

}

funcparseShareFolder(shareFolderstring) (string, string) {

split := strings.Split(shareFolder, ":")

shareDir := strings.Join(split[:len(split)-1], ":")

shareName := split[len(split)-1]

return shareDir, shareName

}