diff --git a/pkg/minikube/machine/cache_images.go b/pkg/minikube/machine/cache_images.go index 706240ae7f..5b6e15f6c2 100644 --- a/pkg/minikube/machine/cache_images.go +++ b/pkg/minikube/machine/cache_images.go @@ -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")