Enable cache image for Windows

pull/2000/head
Hiroshi Nomura 2017-09-23 19:08:35 +09:00
parent 93f6eb2378
commit 6ee6a82d0a
1 changed files with 39 additions and 7 deletions

View File

@ -19,6 +19,7 @@ package machine
import (
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
@ -122,6 +123,32 @@ func hasWindowsDriveLetter(s string) bool {
return false
}
func getWindowsVolumeName(d string) (string, error) {
cmd := exec.Command("wmic", "volume", "where", "DriveLetter = '"+d+":'", "get", "DeviceID")
stdout, err := cmd.Output()
if err != nil {
return "", err
}
outs := strings.Split(strings.Replace(string(stdout), "\r", "", -1), "\n")
var vname string
for _, l := range outs {
s := strings.TrimSpace(l)
if strings.HasPrefix(s, `\\?\Volume{`) && strings.HasSuffix(s, `}\`) {
vname = s
break
}
}
if vname == "" {
return "", errors.New("failed to get a volume GUID")
}
return vname, nil
}
func LoadFromCacheBlocking(cmd bootstrapper.CommandRunner, src string) error {
glog.Infoln("Loading image from cache at ", src)
filename := filepath.Base(src)
@ -162,6 +189,18 @@ func getSrcRef(image string) (types.ImageReference, error) {
}
func getDstRef(image, dst string) (types.ImageReference, error) {
if hasWindowsDriveLetter(dst) {
// ParseReference does not support a Windows drive letter.
// Therefore, will change the drive letter to a volume name.
vname, err := getWindowsVolumeName(dst[:1])
if err != nil {
return nil, errors.Wrap(err, "parsing docker archive dst ref: get Windows volume name")
}
dst = vname + dst[3:]
if _, err := os.Stat(filepath.Dir(dst)); err != nil {
return nil, errors.Wrap(err, "parsing docker archive dst ref: get Windows volume name")
}
}
dstRef, err := archive.ParseReference(dst + ":" + image)
if err != nil {
return nil, errors.Wrap(err, "parsing docker archive dst ref")
@ -179,13 +218,6 @@ func CacheImage(image, dst string) error {
return errors.Wrapf(err, "making cache image directory: %s", dst)
}
// TODO: support Windows drive letter.
// L:164 ParseReference does not support Windows drive letter.
// If contains Windows drive letter, it disable cache image for now.
if hasWindowsDriveLetter(dst) {
return nil
}
srcRef, err := getSrcRef(image)
if err != nil {
return errors.Wrap(err, "creating docker image src ref")