@@ -24,6 +24,7 @@ import (
24
24
"math"
25
25
"net"
26
26
"os/exec"
27
+ "path"
27
28
"path/filepath"
28
29
"regexp"
29
30
"strconv"
@@ -46,6 +47,7 @@ import (
46
47
"github.com/shirou/gopsutil/mem"
47
48
"github.com/spf13/viper"
48
49
50
+ "k8s.io/minikube/pkg/minikube/command"
49
51
"k8s.io/minikube/pkg/minikube/config"
50
52
cfg "k8s.io/minikube/pkg/minikube/config"
51
53
"k8s.io/minikube/pkg/minikube/constants"
@@ -54,6 +56,8 @@ import (
54
56
"k8s.io/minikube/pkg/minikube/localpath"
55
57
"k8s.io/minikube/pkg/minikube/out"
56
58
"k8s.io/minikube/pkg/minikube/registry"
59
+ "k8s.io/minikube/pkg/minikube/sshutil"
60
+ "k8s.io/minikube/pkg/minikube/vmpath"
57
61
"k8s.io/minikube/pkg/util/lock"
58
62
"k8s.io/minikube/pkg/util/retry"
59
63
)
67
71
// The maximum the guest VM clock is allowed to be ahead and behind. This value is intentionally
68
72
// large to allow for inaccurate methodology, but still small enough so that certificates are likely valid.
69
73
maxClockDesyncSeconds = 2.1
74
+
75
+ // requiredDirectories are directories to create on the host during setup
76
+ requiredDirectories = []string {
77
+ vmpath .GuestAddonsDir ,
78
+ vmpath .GuestManifestsDir ,
79
+ vmpath .GuestEphemeralDir ,
80
+ vmpath .GuestPersistentDir ,
81
+ vmpath .GuestCertsDir ,
82
+ path .Join (vmpath .GuestPersistentDir , "images" ),
83
+ path .Join (vmpath .GuestPersistentDir , "binaries" ),
84
+ }
70
85
)
71
86
72
87
// This init function is used to set the logtostderr variable to false so that INFO level log info does not clutter the CLI
@@ -497,6 +512,10 @@ func createHost(api libmachine.API, config cfg.MachineConfig) (*host.Host, error
497
512
return nil , errors .Wrap (err , "create" )
498
513
}
499
514
515
+ if err := createRequiredDirectories (h ); err != nil {
516
+ return h , errors .Wrap (err , "required directories" )
517
+ }
518
+
500
519
if driver .BareMetal (config .VMDriver ) {
501
520
showLocalOsRelease ()
502
521
} else if ! driver .BareMetal (config .VMDriver ) && ! driver .IsKIC (config .VMDriver ) {
@@ -646,3 +665,41 @@ func IsMinikubeRunning(api libmachine.API) bool {
646
665
}
647
666
return true
648
667
}
668
+
669
+ // createRequiredDirectories creates directories expected by minikube to exist
670
+ func createRequiredDirectories (h * host.Host ) error {
671
+ if h .DriverName == driver .Mock {
672
+ glog .Infof ("skipping createRequiredDirectories" )
673
+ return nil
674
+ }
675
+ glog .Infof ("creating required directories: %v" , requiredDirectories )
676
+ r , err := commandRunner (h )
677
+ if err != nil {
678
+ return errors .Wrap (err , "command runner" )
679
+ }
680
+
681
+ args := append ([]string {"mkdir" , "-p" }, requiredDirectories ... )
682
+ if _ , err := r .RunCmd (exec .Command ("sudo" , args ... )); err != nil {
683
+ return errors .Wrapf (err , "sudo mkdir (%s)" , h .DriverName )
684
+ }
685
+ return nil
686
+ }
687
+
688
+ // commandRunner returns best available command runner for this host
689
+ func commandRunner (h * host.Host ) (command.Runner , error ) {
690
+ if h .DriverName == driver .Mock {
691
+ glog .Errorf ("commandRunner: returning unconfigured FakeCommandRunner, commands will fail!" )
692
+ return & command.FakeCommandRunner {}, nil
693
+ }
694
+ if driver .BareMetal (h .Driver .DriverName ()) {
695
+ return & command.ExecRunner {}, nil
696
+ }
697
+ if h .Driver .DriverName () == driver .Docker {
698
+ return command .NewKICRunner (h .Name , "docker" ), nil
699
+ }
700
+ client , err := sshutil .NewSSHClient (h .Driver )
701
+ if err != nil {
702
+ return nil , errors .Wrap (err , "getting ssh client for bootstrapper" )
703
+ }
704
+ return command .NewSSHRunner (client ), nil
705
+ }
0 commit comments