diff --git a/cmd/minikube/cmd/delete.go b/cmd/minikube/cmd/delete.go index 8ce08f8d8582..7d4fa537036a 100644 --- a/cmd/minikube/cmd/delete.go +++ b/cmd/minikube/cmd/delete.go @@ -309,7 +309,7 @@ func deleteProfile(profile *config.Profile) error { return DeletionError{Err: delErr, Errtype: MissingProfile} } - if err == nil && driver.BareMetal(cc.Driver) { + if err == nil && (driver.BareMetal(cc.Driver) || driver.IsGeneric(cc.Driver)) { if err := uninstallKubernetes(api, *cc, cc.Nodes[0], viper.GetString(cmdcfg.Bootstrapper)); err != nil { deletionError, ok := err.(DeletionError) if ok { diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index 5f3062b7704d..2dc8a3e41bdb 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -304,7 +304,7 @@ func provisionWithDriver(cmd *cobra.Command, ds registry.DriverState, existing * os.Exit(0) } - if driver.IsVM(driverName) { + if driver.IsVM(driverName) && !driver.IsGeneric(driverName) { url, err := download.ISO(viper.GetStringSlice(isoURL), cmd.Flags().Changed(isoURL)) if err != nil { return node.Starter{}, errors.Wrap(err, "Failed to cache ISO") diff --git a/cmd/minikube/cmd/start_flags.go b/cmd/minikube/cmd/start_flags.go index 52d557789d6b..69c031079011 100644 --- a/cmd/minikube/cmd/start_flags.go +++ b/cmd/minikube/cmd/start_flags.go @@ -22,6 +22,7 @@ import ( "time" "github.com/blang/semver" + "github.com/docker/machine/libmachine/drivers" "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -109,6 +110,10 @@ const ( ports = "ports" startNamespace = "namespace" trace = "trace" + genericIPAddress = "generic-ip-address" + genericSSHUser = "generic-ssh-user" + genericSSHKey = "generic-ssh-key" + genericSSHPort = "generic-ssh-port" ) var ( @@ -219,6 +224,12 @@ func initNetworkingFlags() { startCmd.Flags().String(serviceCIDR, constants.DefaultServiceCIDR, "The CIDR to be used for service cluster IPs.") startCmd.Flags().StringArrayVar(&config.DockerEnv, "docker-env", nil, "Environment variables to pass to the Docker daemon. (format: key=value)") startCmd.Flags().StringArrayVar(&config.DockerOpt, "docker-opt", nil, "Specify arbitrary flags to pass to the Docker daemon. (format: key=value)") + + // generic + startCmd.Flags().String(genericIPAddress, "", "IP address (generic)") + startCmd.Flags().String(genericSSHUser, drivers.DefaultSSHUser, "SSH user (generic)") + startCmd.Flags().String(genericSSHKey, "", "SSH key (generic)") + startCmd.Flags().Int(genericSSHPort, drivers.DefaultSSHPort, "SSH port (generic)") } // ClusterFlagValue returns the current cluster name based on flags @@ -328,6 +339,10 @@ func generateClusterConfig(cmd *cobra.Command, existing *config.ClusterConfig, k NatNicType: viper.GetString(natNicType), StartHostTimeout: viper.GetDuration(waitTimeout), ExposedPorts: viper.GetStringSlice(ports), + GenericIPAddress: viper.GetString(genericIPAddress), + GenericSSHUser: viper.GetString(genericSSHUser), + GenericSSHKey: viper.GetString(genericSSHKey), + GenericSSHPort: viper.GetInt(genericSSHPort), KubernetesConfig: config.KubernetesConfig{ KubernetesVersion: k8sVersion, ClusterName: ClusterFlagValue(), diff --git a/pkg/minikube/cluster/ip.go b/pkg/minikube/cluster/ip.go index 891705e60c73..6a3522e67a61 100644 --- a/pkg/minikube/cluster/ip.go +++ b/pkg/minikube/cluster/ip.go @@ -40,6 +40,12 @@ func HostIP(host *host.Host, clusterName string) (net.IP, error) { return oci.RoutableHostIPFromInside(oci.Docker, clusterName, host.Name) case driver.Podman: return oci.RoutableHostIPFromInside(oci.Podman, clusterName, host.Name) + case driver.Generic: + ip, err := host.Driver.GetIP() + if err != nil { + return []byte{}, errors.Wrap(err, "Error getting VM/Host IP address") + } + return net.ParseIP(ip), nil case driver.KVM2: return net.ParseIP("192.168.39.1"), nil case driver.HyperV: diff --git a/pkg/minikube/config/types.go b/pkg/minikube/config/types.go index d95e9f7c85f4..059e56d436fb 100644 --- a/pkg/minikube/config/types.go +++ b/pkg/minikube/config/types.go @@ -66,6 +66,10 @@ type ClusterConfig struct { HostDNSResolver bool // Only used by virtualbox HostOnlyNicType string // Only used by virtualbox NatNicType string // Only used by virtualbox + GenericIPAddress string // Only used by generic + GenericSSHUser string // Only used by generic + GenericSSHKey string // Only used by generic + GenericSSHPort int // Only used by generic KubernetesConfig KubernetesConfig Nodes []Node Addons map[string]bool diff --git a/pkg/minikube/driver/driver.go b/pkg/minikube/driver/driver.go index b890ce0e4500..95d1dabca1a3 100644 --- a/pkg/minikube/driver/driver.go +++ b/pkg/minikube/driver/driver.go @@ -39,6 +39,8 @@ const ( Mock = "mock" // None driver None = "none" + // Generic driver + Generic = "generic" // KVM2 driver KVM2 = "kvm2" // VirtualBox driver @@ -97,6 +99,10 @@ func MachineType(name string) string { return "container" } + if IsGeneric(name) { + return "bare metal machine" + } + if IsVM(name) { return "VM" } @@ -144,6 +150,16 @@ func BareMetal(name string) bool { return name == None || name == Mock } +// IsGeneric checks if the driver is generic +func IsGeneric(name string) bool { + return name == Generic +} + +// NeedsRoot returns true if driver needs to run with root privileges +func NeedsRoot(name string) bool { + return name == None +} + // NeedsPortForward returns true if driver is unable provide direct IP connectivity func NeedsPortForward(name string) bool { if !IsKIC(name) { diff --git a/pkg/minikube/driver/driver_darwin.go b/pkg/minikube/driver/driver_darwin.go index f951177677c2..24a6e56d6c3d 100644 --- a/pkg/minikube/driver/driver_darwin.go +++ b/pkg/minikube/driver/driver_darwin.go @@ -26,7 +26,7 @@ var supportedDrivers = []string{ HyperKit, VMware, Docker, - Podman, + Generic, } func VBoxManagePath() string { diff --git a/pkg/minikube/driver/driver_linux.go b/pkg/minikube/driver/driver_linux.go index 16e7b5e706de..05784f946e08 100644 --- a/pkg/minikube/driver/driver_linux.go +++ b/pkg/minikube/driver/driver_linux.go @@ -29,6 +29,7 @@ var supportedDrivers = []string{ None, Docker, Podman, + Generic, } // VBoxManagePath returns the path to the VBoxManage command diff --git a/pkg/minikube/driver/driver_test.go b/pkg/minikube/driver/driver_test.go index 1f6ab86f7446..79e6b77893e2 100644 --- a/pkg/minikube/driver/driver_test.go +++ b/pkg/minikube/driver/driver_test.go @@ -65,6 +65,7 @@ func TestMachineType(t *testing.T) { Docker: "container", Mock: "bare metal machine", None: "bare metal machine", + Generic: "bare metal machine", KVM2: "VM", VirtualBox: "VM", HyperKit: "VM", diff --git a/pkg/minikube/driver/driver_windows.go b/pkg/minikube/driver/driver_windows.go index 80ff83b825b2..8a2f5a6a2a5f 100644 --- a/pkg/minikube/driver/driver_windows.go +++ b/pkg/minikube/driver/driver_windows.go @@ -33,6 +33,7 @@ var supportedDrivers = []string{ HyperV, VMware, Docker, + Generic, } // TODO: medyagh add same check for kic docker diff --git a/pkg/minikube/machine/fix.go b/pkg/minikube/machine/fix.go index 8e0eeb7f77e4..58e09eb8ee1e 100644 --- a/pkg/minikube/machine/fix.go +++ b/pkg/minikube/machine/fix.go @@ -129,6 +129,15 @@ func recreateIfNeeded(api libmachine.API, cc *config.ClusterConfig, n *config.No } } + if driver.IsGeneric(h.Driver.DriverName()) { + if s == state.Running { + out.Step(style.Running, `Using the {{.driver_name}} "{{.cluster}}" {{.machine_type}} ...`, out.V{"driver_name": cc.Driver, "cluster": cc.Name, "machine_type": machineType}) + } else { + return h, errors.Errorf("not running") + } + return h, nil + } + if serr != constants.ErrMachineMissing { klog.Warningf("unexpected machine state, will restart: %v", serr) } diff --git a/pkg/minikube/machine/machine.go b/pkg/minikube/machine/machine.go index d382041f6a04..2fdf60ba693a 100644 --- a/pkg/minikube/machine/machine.go +++ b/pkg/minikube/machine/machine.go @@ -104,7 +104,7 @@ func fastDetectProvisioner(h *host.Host) (libprovision.Provisioner, error) { switch { case driver.IsKIC(d): return provision.NewUbuntuProvisioner(h.Driver), nil - case driver.BareMetal(d): + case driver.BareMetal(d), driver.IsGeneric(d): return libprovision.DetectProvisioner(h.Driver) default: return provision.NewBuildrootProvisioner(h.Driver), nil diff --git a/pkg/minikube/machine/start.go b/pkg/minikube/machine/start.go index 9314ec703a4a..9079162089a2 100644 --- a/pkg/minikube/machine/start.go +++ b/pkg/minikube/machine/start.go @@ -175,6 +175,12 @@ func createHost(api libmachine.API, cfg *config.ClusterConfig, n *config.Node) ( return h, errors.Wrap(err, "post-start") } + if driver.IsGeneric(h.Driver.DriverName()) { + if _, err := h.RunSSHCommand(fmt.Sprintf("sudo usermod -aG docker %s", h.Driver.GetSSHUsername())); err != nil { + return h, errors.Wrap(err, "usermod") + } + } + if err := saveHost(api, h, cfg, n); err != nil { return h, err } @@ -290,7 +296,7 @@ func postStartSetup(h *host.Host, mc config.ClusterConfig) error { if driver.BareMetal(mc.Driver) { showLocalOsRelease() } - if driver.IsVM(mc.Driver) || driver.IsKIC(mc.Driver) { + if driver.IsVM(mc.Driver) || driver.IsKIC(mc.Driver) || driver.IsGeneric(mc.Driver) { logRemoteOsRelease(r) } return syncLocalAssets(r) diff --git a/pkg/minikube/machine/stop.go b/pkg/minikube/machine/stop.go index 3984f2e9aa0e..56623d353526 100644 --- a/pkg/minikube/machine/stop.go +++ b/pkg/minikube/machine/stop.go @@ -55,6 +55,10 @@ func stop(h *host.Host) error { } } + if driver.IsGeneric(h.DriverName) { + return nil + } + if err := h.Stop(); err != nil { klog.Infof("stop err: %v", err) st, ok := err.(mcnerror.ErrHostAlreadyInState) diff --git a/pkg/minikube/registry/drvs/generic/generic.go b/pkg/minikube/registry/drvs/generic/generic.go new file mode 100644 index 000000000000..93afecc13355 --- /dev/null +++ b/pkg/minikube/registry/drvs/generic/generic.go @@ -0,0 +1,62 @@ +/* +Copyright 2019 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package generic + +import ( + "fmt" + + "github.com/docker/machine/drivers/generic" + "github.com/docker/machine/libmachine/drivers" + "github.com/pkg/errors" + + "k8s.io/minikube/pkg/minikube/config" + "k8s.io/minikube/pkg/minikube/driver" + "k8s.io/minikube/pkg/minikube/localpath" + "k8s.io/minikube/pkg/minikube/registry" +) + +func init() { + err := registry.Register(registry.DriverDef{ + Name: driver.Generic, + Config: configure, + Status: status, + Priority: registry.Fallback, + Init: func() drivers.Driver { return generic.NewDriver("", "") }, + }) + if err != nil { + panic(fmt.Sprintf("unable to register: %v", err)) + } +} + +func configure(cc config.ClusterConfig, n config.Node) (interface{}, error) { + d := generic.NewDriver(driver.MachineName(cc, n), localpath.MiniPath()) + + if cc.GenericIPAddress == "" { + return nil, errors.Errorf("please provide an IP address") + } + + d.(*generic.Driver).IPAddress = cc.GenericIPAddress + d.(*generic.Driver).SSHUser = cc.GenericSSHUser + d.(*generic.Driver).SSHKey = cc.GenericSSHKey + d.(*generic.Driver).SSHPort = cc.GenericSSHPort + + return d, nil +} + +func status() registry.State { + return registry.State{Installed: true, Healthy: true} +} diff --git a/pkg/minikube/registry/drvs/init.go b/pkg/minikube/registry/drvs/init.go index bca12775c3ff..2bd36761e79c 100644 --- a/pkg/minikube/registry/drvs/init.go +++ b/pkg/minikube/registry/drvs/init.go @@ -19,6 +19,7 @@ package drvs import ( // Register all of the drvs we know of _ "k8s.io/minikube/pkg/minikube/registry/drvs/docker" + _ "k8s.io/minikube/pkg/minikube/registry/drvs/generic" _ "k8s.io/minikube/pkg/minikube/registry/drvs/hyperkit" _ "k8s.io/minikube/pkg/minikube/registry/drvs/hyperv" _ "k8s.io/minikube/pkg/minikube/registry/drvs/kvm2" diff --git a/site/content/en/docs/commands/start.md b/site/content/en/docs/commands/start.md index 797fccacace2..41c84096c3b8 100644 --- a/site/content/en/docs/commands/start.md +++ b/site/content/en/docs/commands/start.md @@ -51,6 +51,10 @@ minikube start [flags] --feature-gates string A set of key=value pairs that describe feature gates for alpha/experimental features. --force Force minikube to perform possibly dangerous operations --force-systemd If set, force the container runtime to use sytemd as cgroup manager. Currently available for docker and crio. Defaults to false. + --generic-ip-address string IP address (generic) + --generic-ssh-key string SSH key (generic) + --generic-ssh-port int SSH port (generic) (default 22) + --generic-ssh-user string SSH user (generic) (default "root") --host-dns-resolver Enable host resolver for NAT DNS requests (virtualbox driver only) (default true) --host-only-cidr string The CIDR to be used for the minikube VM (virtualbox driver only) (default "192.168.99.1/24") --host-only-nic-type string NIC Type used for host only network. One of Am79C970A, Am79C973, 82540EM, 82543GC, 82545EM, or virtio (virtualbox driver only) (default "virtio")