diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index 8975cd787b12..67e834c899b0 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -197,7 +197,7 @@ func runStart(cmd *cobra.Command, args []string) { machine.MaybeDisplayAdvice(err, ds.Name) if specified { // If the user specified a driver, don't fallback to anything else - exit.Error(reason.GuestProvision, "error provisioning host", err) + exitGuestProvision(err) } else { success := false // Walk down the rest of the options @@ -224,7 +224,7 @@ func runStart(cmd *cobra.Command, args []string) { } } if !success { - exit.Error(reason.GuestProvision, "error provisioning host", err) + exitGuestProvision(err) } } } @@ -248,7 +248,7 @@ func runStart(cmd *cobra.Command, args []string) { stopProfile(existing.Name) starter, err = provisionWithDriver(cmd, ds, existing) if err != nil { - exit.Error(reason.GuestProvision, "error provisioning host", err) + exitGuestProvision(err) } } } @@ -1263,3 +1263,10 @@ func exitIfNotForced(r reason.Kind, message string, v ...out.V) { } out.Error(r, message, v...) } + +func exitGuestProvision(err error) { + if errors.Cause(err) == oci.ErrInsufficientDockerStorage { + exit.Message(reason.RsrcInsufficientDockerStorage, "preload extraction failed: \"No space left on device\"") + } + exit.Error(reason.GuestProvision, "error provisioning host", err) +} diff --git a/pkg/drivers/kic/kic.go b/pkg/drivers/kic/kic.go index 120d64a9b646..8a896118b30b 100644 --- a/pkg/drivers/kic/kic.go +++ b/pkg/drivers/kic/kic.go @@ -137,6 +137,7 @@ func (d *Driver) Create() error { var waitForPreload sync.WaitGroup waitForPreload.Add(1) + var pErr error go func() { defer waitForPreload.Done() // If preload doesn't exist, don't bother extracting tarball to volume @@ -147,11 +148,18 @@ func (d *Driver) Create() error { glog.Infof("Starting extracting preloaded images to volume ...") // Extract preloaded images to container if err := oci.ExtractTarballToVolume(d.NodeConfig.OCIBinary, download.TarballPath(d.NodeConfig.KubernetesVersion, d.NodeConfig.ContainerRuntime), params.Name, d.NodeConfig.ImageDigest); err != nil { + if strings.Contains(err.Error(), "No space left on device") { + pErr = oci.ErrInsufficientDockerStorage + return + } glog.Infof("Unable to extract preloaded tarball to volume: %v", err) } else { glog.Infof("duration metric: took %f seconds to extract preloaded images to volume", time.Since(t).Seconds()) } }() + if pErr == oci.ErrInsufficientDockerStorage { + return pErr + } if err := oci.CreateContainerNode(params); err != nil { return errors.Wrap(err, "create kic node") diff --git a/pkg/drivers/kic/oci/errors.go b/pkg/drivers/kic/oci/errors.go index f8e65b7b1bb6..e44d4d556371 100644 --- a/pkg/drivers/kic/oci/errors.go +++ b/pkg/drivers/kic/oci/errors.go @@ -48,6 +48,9 @@ var ErrExitedUnexpectedly = errors.New("container exited unexpectedly") // ErrDaemonInfo is thrown when docker/podman info is failing or not responding var ErrDaemonInfo = errors.New("daemon info not responding") +// ErrInsufficientDockerStorage is thrown when there is not more storage for docker +var ErrInsufficientDockerStorage = &FailFastError{errors.New("insufficient docker storage, no space left on device")} + // ErrNetworkSubnetTaken is thrown when a subnet is taken by another network var ErrNetworkSubnetTaken = errors.New("subnet is taken") diff --git a/pkg/minikube/node/start.go b/pkg/minikube/node/start.go index c00aa6cadca3..9328f0bbb32a 100644 --- a/pkg/minikube/node/start.go +++ b/pkg/minikube/node/start.go @@ -383,7 +383,7 @@ func startHost(api libmachine.API, cc *config.ClusterConfig, n *config.Node, del } } - if _, ff := err.(*oci.FailFastError); ff { + if err, ff := errors.Cause(err).(*oci.FailFastError); ff { glog.Infof("will skip retrying to create machine because error is not retriable: %v", err) return host, exists, err }