提交 a7c2ff3e 编写于 作者: A Aaron Prindle 提交者: GitHub

Merge pull request #1173 from aaron-prindle/minikube-no-vm

None driver
......@@ -36,7 +36,7 @@ func TestDisableUnknownAddon(t *testing.T) {
}
}
func TestDisableValidAddonNoVM(t *testing.T) {
func TestDisableValidAddonLocal(t *testing.T) {
tempDir := tests.MakeTempDir()
defer os.RemoveAll(tempDir)
......@@ -60,7 +60,7 @@ func TestDisableValidAddonNoVM(t *testing.T) {
}
}
func TestDeleteAddonViaDriver(t *testing.T) {
func TestDeleteAddonSSH(t *testing.T) {
s, _ := tests.NewSSHServer()
port, err := s.Start()
if err != nil {
......@@ -76,7 +76,7 @@ func TestDeleteAddonViaDriver(t *testing.T) {
}
dashboard := assets.Addons["dashboard"]
if err := deleteAddonViaDriver(dashboard, d); err != nil {
if err := deleteAddonSSH(dashboard, d); err != nil {
t.Fatalf("Unexpected error %s deleting addon", err)
}
// check command(s) were run
......
......@@ -36,7 +36,7 @@ func TestEnableUnknownAddon(t *testing.T) {
}
}
func TestEnableValidAddonNoVM(t *testing.T) {
func TestEnableValidAddonLocal(t *testing.T) {
tempDir := tests.MakeTempDir()
defer os.RemoveAll(tempDir)
......@@ -59,7 +59,7 @@ func TestEnableValidAddonNoVM(t *testing.T) {
}
}
func TestTransferAddonViaDriver(t *testing.T) {
func TestTransferAddonSSH(t *testing.T) {
s, _ := tests.NewSSHServer()
port, err := s.Start()
if err != nil {
......@@ -75,7 +75,7 @@ func TestTransferAddonViaDriver(t *testing.T) {
}
dashboard := assets.Addons["dashboard"]
if err := transferAddonViaDriver(dashboard, d); err != nil {
if err := transferAddonSSH(dashboard, d); err != nil {
t.Fatalf("Unexpected error %s transferring addon", err)
}
// check contents
......
......@@ -19,6 +19,7 @@ package config
import (
"fmt"
"os"
"path/filepath"
"strconv"
"github.com/docker/machine/libmachine/drivers"
......@@ -110,18 +111,18 @@ func EnableOrDisableAddon(name string, val string) error {
}
host, err := cluster.CheckIfApiExistsAndLoad(api)
if enable {
if err = transferAddonViaDriver(addon, host.Driver); err != nil {
if err = transferAddon(addon, host.Driver); err != nil {
return errors.Wrapf(err, "Error transferring addon %s to VM", name)
}
} else {
if err = deleteAddonViaDriver(addon, host.Driver); err != nil {
if err = deleteAddon(addon, host.Driver); err != nil {
return errors.Wrapf(err, "Error deleting addon %s from VM", name)
}
}
return nil
}
func deleteAddonViaDriver(addon *assets.Addon, d drivers.Driver) error {
func deleteAddonSSH(addon *assets.Addon, d drivers.Driver) error {
client, err := sshutil.NewSSHClient(d)
if err != nil {
return err
......@@ -132,7 +133,30 @@ func deleteAddonViaDriver(addon *assets.Addon, d drivers.Driver) error {
return nil
}
func transferAddonViaDriver(addon *assets.Addon, d drivers.Driver) error {
func deleteAddon(addon *assets.Addon, d drivers.Driver) error {
if d.DriverName() == "none" {
if err := deleteAddonLocal(addon, d); err != nil {
return err
}
} else {
if err := deleteAddonSSH(addon, d); err != nil {
return err
}
}
return nil
}
func deleteAddonLocal(addon *assets.Addon, d drivers.Driver) error {
var err error
for _, f := range addon.Assets {
if err = os.Remove(filepath.Join(f.GetTargetDir(), f.GetTargetName())); err != nil {
return err
}
}
return err
}
func transferAddonSSH(addon *assets.Addon, d drivers.Driver) error {
client, err := sshutil.NewSSHClient(d)
if err != nil {
return err
......@@ -158,3 +182,26 @@ func EnableOrDisableDefaultStorageClass(name, val string) error {
}
return EnableOrDisableAddon(name, val)
}
func transferAddon(addon *assets.Addon, d drivers.Driver) error {
if d.DriverName() == "none" {
if err := transferAddonLocal(addon, d); err != nil {
return err
}
} else {
if err := transferAddonSSH(addon, d); err != nil {
return err
}
}
return nil
}
func transferAddonLocal(addon *assets.Addon, d drivers.Driver) error {
var err error
for _, f := range addon.Assets {
if err = assets.CopyFileLocal(f); err != nil {
return err
}
}
return err
}
......@@ -292,6 +292,15 @@ var dockerEnvCmd = &cobra.Command{
os.Exit(1)
}
defer api.Close()
host, err := cluster.CheckIfApiExistsAndLoad(api)
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting host: %s\n", err)
os.Exit(1)
}
if host.Driver.DriverName() == "none" {
fmt.Println(`'none' driver does not support 'minikube docker-env' command`)
os.Exit(0)
}
var shellCfg *ShellConfig
......
......@@ -97,6 +97,10 @@ var mountCmd = &cobra.Command{
glog.Errorln("Error loading api: ", err)
os.Exit(1)
}
if host.Driver.DriverName() == "none" {
fmt.Println(`'none' driver does not support 'minikube mount' command`)
os.Exit(0)
}
var ip net.IP
if mountIP == "" {
ip, err = cluster.GetVMHostIP(host)
......
......@@ -39,6 +39,15 @@ var sshCmd = &cobra.Command{
os.Exit(1)
}
defer api.Close()
host, err := cluster.CheckIfApiExistsAndLoad(api)
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting host: %s\n", err)
os.Exit(1)
}
if host.Driver.DriverName() == "none" {
fmt.Println(`'none' driver does not support 'minikube ssh' command`)
os.Exit(0)
}
err = cluster.CreateSSHShell(api, args)
if err != nil {
glog.Errorln(errors.Wrap(err, "Error attempting to ssh/run-ssh-command"))
......
......@@ -18,6 +18,7 @@ package cmd
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
......@@ -30,9 +31,6 @@ import (
"github.com/golang/glog"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"io/ioutil"
cmdUtil "k8s.io/minikube/cmd/util"
"k8s.io/minikube/pkg/minikube/cluster"
cfg "k8s.io/minikube/pkg/minikube/config"
......@@ -152,8 +150,8 @@ func runStart(cmd *cobra.Command, args []string) {
ExtraOptions: extraOptions,
}
fmt.Println("SSH-ing files into VM...")
if err := cluster.UpdateCluster(host, host.Driver, kubernetesConfig); err != nil {
fmt.Println("Moving files into cluster...")
if err := cluster.UpdateCluster(host.Driver, kubernetesConfig); err != nil {
glog.Errorln("Error updating cluster: ", err)
cmdUtil.MaybeReportErrorAndExit(err)
}
......@@ -165,7 +163,8 @@ func runStart(cmd *cobra.Command, args []string) {
}
fmt.Println("Starting cluster components...")
if err := cluster.StartCluster(host, kubernetesConfig); err != nil {
if err := cluster.StartCluster(api, kubernetesConfig); err != nil {
glog.Errorln("Error starting cluster: ", err)
cmdUtil.MaybeReportErrorAndExit(err)
}
......@@ -237,6 +236,23 @@ func runStart(cmd *cobra.Command, args []string) {
} else {
fmt.Println("Kubectl is now configured to use the cluster.")
}
if config.VMDriver == "none" {
fmt.Println(`===================
WARNING: IT IS RECOMMENDED NOT TO RUN THE NONE DRIVER ON PERSONAL WORKSTATIONS
The 'none' driver will run an insecure kubernetes apiserver as root that may leave the host vulnerable to CSRF attacks
When using the none driver, the kubectl config and credentials generated will be root owned and will appear in the root home directory.
You will need to move the files to the appropriate location and then set the correct permissions. An example of this is below:
sudo mv /root/.kube $HOME/.kube # this will overwrite any config you have. You may have to append the file contents manually
sudo chown -R $USER $HOME/.kube
sudo chgrp -R $USER $HOME/.kube
sudo mv /root/.minikube $HOME/.minikube # this will overwrite any config you have. You may have to append the file contents manually
sudo chown -R $USER $HOME/.minikube
sudo chgrp -R $USER $HOME/.minikube
This can also be done automatically by setting the env var CHANGE_MINIKUBE_NONE_USER=true`)
}
}
func validateK8sVersion(version string) {
......
......@@ -49,18 +49,20 @@ var statusCmd = &cobra.Command{
os.Exit(1)
}
defer api.Close()
ms, err := cluster.GetHostStatus(api)
if err != nil {
glog.Errorln("Error getting machine status:", err)
cmdUtil.MaybeReportErrorAndExit(err)
}
ls := "N/A"
ls := state.None.String()
if ms == state.Running.String() {
ls, err = cluster.GetLocalkubeStatus(api)
}
if err != nil {
glog.Errorln("Error getting machine status:", err)
cmdUtil.MaybeReportErrorAndExit(err)
if err != nil {
glog.Errorln("Error localkube status:", err)
cmdUtil.MaybeReportErrorAndExit(err)
}
}
status := Status{ms, ls}
......
......@@ -40,13 +40,14 @@ MINIKUBE_WANTREPORTERRORPROMPT=False sudo ./out/minikube-${OS_ARCH} delete \
|| MINIKUBE_WANTREPORTERRORPROMPT=False ./out/minikube-${OS_ARCH} delete \
|| true
sudo rm -rf $HOME/.minikube || true
sudo rm -rf $HOME/.kube || true
# See the default image
./out/minikube-${OS_ARCH} start -h | grep iso
# Allow this to fail, we'll switch on the return code below.
set +e
out/e2e-${OS_ARCH} -minikube-args="--vm-driver=${VM_DRIVER} --v=10" -test.v -test.timeout=30m -binary=out/minikube-${OS_ARCH}
${SUDO_PREFIX}out/e2e-${OS_ARCH} -minikube-args="--vm-driver=${VM_DRIVER} --v=10" -test.v -test.timeout=30m -binary=out/minikube-${OS_ARCH}
result=$?
set -e
......@@ -54,6 +55,7 @@ MINIKUBE_WANTREPORTERRORPROMPT=False sudo ./out/minikube-${OS_ARCH} delete \
|| MINIKUBE_WANTREPORTERRORPROMPT=False ./out/minikube-${OS_ARCH} delete \
|| true
sudo rm -rf $HOME/.minikube || true
sudo rm -rf $HOME/.kube || true
if [[ $result -eq 0 ]]; then
status="success"
......
#!/bin/bash
# Copyright 2016 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.
# This script runs the integration tests on a Linux machine for the Virtualbox Driver
# The script expects the following env variables:
# MINIKUBE_LOCATION: GIT_COMMIT from upstream build.
# COMMIT: Actual commit ID from upstream build
# EXTRA_BUILD_ARGS (optional): Extra args to be passed into the minikube integrations tests
# access_token: The Github API access token. Injected by the Jenkins credential provider.
set -e
OS_ARCH="linux-amd64"
VM_DRIVER="none"
JOB_NAME="Linux-None"
EXTRA_BUILD_ARGS="$EXTRA_BUILD_ARGS --use-vendored-driver"
SUDO_PREFIX="sudo "
# Download files and set permissions
source common.sh
......@@ -20,6 +20,9 @@ import (
"bytes"
"io"
"os"
"os/user"
"path/filepath"
"strconv"
"github.com/pkg/errors"
)
......@@ -135,3 +138,48 @@ func (m *MemoryAsset) GetLength() int {
func (m *MemoryAsset) Read(p []byte) (int, error) {
return m.reader.Read(p)
}
func CopyFileLocal(f CopyableFile) error {
os.MkdirAll(f.GetTargetDir(), os.ModePerm)
targetPath := filepath.Join(f.GetTargetDir(), f.GetTargetName())
os.Remove(targetPath)
target, err := os.Create(targetPath)
defer target.Close()
perms, err := strconv.Atoi(f.GetPermissions())
if err != nil {
return errors.Wrap(err, "Error converting permissions to integer")
}
target.Chmod(os.FileMode(perms))
if err != nil {
return errors.Wrap(err, "Error changing file permissions")
}
_, err = io.Copy(target, f)
if err != nil {
return errors.Wrap(err, "Error copying file to target location")
}
if os.Getenv("CHANGE_MINIKUBE_NONE_USER") != "" {
username := os.Getenv("SUDO_USER")
if username == "" {
return nil
}
usr, err := user.Lookup(username)
if err != nil {
return errors.Wrap(err, "Error looking up user")
}
uid, err := strconv.Atoi(usr.Uid)
if err != nil {
return errors.Wrapf(err, "Error parsing uid for user: %s", username)
}
gid, err := strconv.Atoi(usr.Gid)
if err != nil {
return errors.Wrapf(err, "Error parsing gid for user: %s", username)
}
if err := os.Chown(targetPath, uid, gid); err != nil {
return errors.Wrapf(err, "Error changing ownership for: %s", targetPath)
}
}
return nil
}
......@@ -88,8 +88,10 @@ func StartHost(api libmachine.API, config MachineConfig) (*host.Host, error) {
}
}
if err := h.ConfigureAuth(); err != nil {
return nil, &util.RetriableError{Err: errors.Wrap(err, "Error configuring auth on host")}
if h.Driver.DriverName() != "none" {
if err := h.ConfigureAuth(); err != nil {
return nil, &util.RetriableError{Err: errors.Wrap(err, "Error configuring auth on host")}
}
}
return h, nil
}
......@@ -120,13 +122,12 @@ func DeleteHost(api libmachine.API) error {
// GetHostStatus gets the status of the host VM.
func GetHostStatus(api libmachine.API) (string, error) {
dne := "Does Not Exist"
exists, err := api.Exists(cfg.GetMachineName())
if err != nil {
return "", errors.Wrapf(err, "Error checking that api exists for: %s", cfg.GetMachineName())
}
if !exists {
return dne, nil
return state.None.String(), nil
}
host, err := api.Load(cfg.GetMachineName())
......@@ -135,9 +136,6 @@ func GetHostStatus(api libmachine.API) (string, error) {
}
s, err := host.Driver.GetState()
if s.String() == "" {
return dne, nil
}
if err != nil {
return "", errors.Wrap(err, "Error getting host state")
}
......@@ -150,7 +148,10 @@ func GetLocalkubeStatus(api libmachine.API) (string, error) {
if err != nil {
return "", err
}
s, err := h.RunSSHCommand(localkubeStatusCommand)
statusCmd := localkubeStatusCommand
s, err := RunCommand(h, statusCmd, false)
if err != nil {
return "", err
}
......@@ -164,18 +165,19 @@ func GetLocalkubeStatus(api libmachine.API) (string, error) {
}
}
type sshAble interface {
RunSSHCommand(string) (string, error)
}
// StartCluster starts a k8s cluster on the specified Host.
func StartCluster(h sshAble, kubernetesConfig KubernetesConfig) error {
func StartCluster(api libmachine.API, kubernetesConfig KubernetesConfig) error {
h, err := CheckIfApiExistsAndLoad(api)
if err != nil {
return errors.Wrap(err, "Error checking that api exists and loading it")
}
startCommand, err := GetStartCommand(kubernetesConfig)
if err != nil {
return errors.Wrapf(err, "Error generating start command: %s", err)
}
glog.Infoln(startCommand)
output, err := h.RunSSHCommand(startCommand)
output, err := RunCommand(h, startCommand, true)
glog.Infoln(output)
if err != nil {
return errors.Wrapf(err, "Error running ssh command: %s", startCommand)
......@@ -183,7 +185,7 @@ func StartCluster(h sshAble, kubernetesConfig KubernetesConfig) error {
return nil
}
func UpdateCluster(h sshAble, d drivers.Driver, config KubernetesConfig) error {
func UpdateCluster(d drivers.Driver, config KubernetesConfig) error {
copyableFiles := []assets.CopyableFile{}
var localkubeFile assets.CopyableFile
var err error
......@@ -215,6 +217,16 @@ func UpdateCluster(h sshAble, d drivers.Driver, config KubernetesConfig) error {
}
}
if d.DriverName() == "none" {
// transfer files to correct place on filesystem
for _, f := range copyableFiles {
if err := assets.CopyFileLocal(f); err != nil {
return err
}
}
return nil
}
// transfer files to vm via SSH
client, err := sshutil.NewSSHClient(d)
if err != nil {
......@@ -267,6 +279,16 @@ func SetupCerts(d drivers.Driver, apiServerName string) error {
copyableFiles = append(copyableFiles, certFile)
}
if d.DriverName() == "none" {
// transfer files to correct place on filesystem
for _, f := range copyableFiles {
if err := assets.CopyFileLocal(f); err != nil {
return err
}
}
return nil
}
// transfer files to vm via SSH
client, err := sshutil.NewSSHClient(d)
if err != nil {
......@@ -305,8 +327,10 @@ func createVirtualboxHost(config MachineConfig) drivers.Driver {
func createHost(api libmachine.API, config MachineConfig) (*host.Host, error) {
var driver interface{}
if err := config.Downloader.CacheMinikubeISOFromURL(config.MinikubeISO); err != nil {
return nil, errors.Wrap(err, "Error attempting to cache minikube ISO from URL")
if config.VMDriver != "none" {
if err := config.Downloader.CacheMinikubeISOFromURL(config.MinikubeISO); err != nil {
return nil, errors.Wrap(err, "Error attempting to cache minikube ISO from URL")
}
}
switch config.VMDriver {
......@@ -320,6 +344,8 @@ func createHost(api libmachine.API, config MachineConfig) (*host.Host, error) {
driver = createXhyveHost(config)
case "hyperv":
driver = createHypervHost(config)
case "none":
driver = createNoneHost(config)
default:
glog.Exitf("Unsupported driver: %s\n", config.VMDriver)
}
......@@ -394,7 +420,8 @@ func GetHostLogs(api libmachine.API, follow bool) (string, error) {
}
return "", err
}
s, err := h.RunSSHCommand(logsCommand)
s, err := RunCommand(h, logsCommand, false)
if err != nil {
return "", err
}
......@@ -523,3 +550,19 @@ func EnsureMinikubeRunningOrExit(api libmachine.API, exitStatus int) {
os.Exit(exitStatus)
}
}
// RunCommand executes commands for both the local and driver implementations
func RunCommand(h *host.Host, command string, sudo bool) (string, error) {
if h.Driver.DriverName() == "none" {
cmd := exec.Command("/bin/sh", "-c", command)
if sudo {
cmd = exec.Command("sudo", "/bin/sh", "-c", command)
}
out, err := cmd.CombinedOutput()
if err != nil {
return "", err
}
return string(out), nil
}
return h.RunSSHCommand(command)
}
......@@ -24,6 +24,7 @@ import (
"github.com/docker/machine/libmachine/drivers"
cfg "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
pkgDrivers "k8s.io/minikube/pkg/minikube/machine/drivers"
)
type kvmDriver struct {
......@@ -67,3 +68,12 @@ func detectVBoxManageCmd() string {
}
return cmd
}
func createNoneHost(config MachineConfig) *pkgDrivers.Driver {
return &pkgDrivers.Driver{
BaseDriver: &drivers.BaseDriver{
MachineName: cfg.GetMachineName(),
StorePath: constants.GetMinipath(),
},
}
}
......@@ -23,3 +23,7 @@ import "github.com/docker/machine/libmachine/drivers"
func createKVMHost(config MachineConfig) drivers.Driver {
panic("kvm not supported")
}
func createNoneHost(config MachineConfig) drivers.Driver {
panic("no-vm not supported")
}
......@@ -87,13 +87,29 @@ func TestCreateHost(t *testing.T) {
}
func TestStartCluster(t *testing.T) {
h := tests.NewMockHost()
ip, _ := h.Driver.GetIP()
api := tests.NewMockAPI()
s, _ := tests.NewSSHServer()
port, err := s.Start()
if err != nil {
t.Fatalf("Error starting ssh server: %s", err)
}
d := &tests.MockDriver{
Port: port,
BaseDriver: drivers.BaseDriver{
IPAddress: "127.0.0.1",
SSHKeyPath: "",
},
CurrentState: state.Running,
}
api.Hosts[config.GetMachineName()] = &host.Host{Driver: d}
kubernetesConfig := KubernetesConfig{
NodeIP: ip,
NodeIP: "",
}
err := StartCluster(h, kubernetesConfig)
err = StartCluster(api, kubernetesConfig)
if err != nil {
t.Fatalf("Error starting cluster: %s", err)
......@@ -104,21 +120,37 @@ func TestStartCluster(t *testing.T) {
t.Fatalf("Error getting start command: %s", err)
}
for _, cmd := range []string{startCommand} {
if _, ok := h.Commands[cmd]; !ok {
t.Fatalf("Expected command not run: %s. Commands run: %v", cmd, h.Commands)
if _, ok := s.Commands[cmd]; !ok {
t.Fatalf("Expected command not run: %s. Commands run: %v", cmd, s.Commands)
}
}
}
func TestStartClusterError(t *testing.T) {
h := tests.NewMockHost()
h.Error = "error"
ip, _ := h.Driver.GetIP()
api := tests.NewMockAPI()
s, _ := tests.NewSSHServer()
port, err := s.Start()
if err != nil {
t.Fatalf("Error starting ssh server: %s", err)
}
d := &tests.MockDriver{
Port: port,
BaseDriver: drivers.BaseDriver{
IPAddress: "127.0.0.1",
SSHKeyPath: "",
},
CurrentState: state.Running,
HostError: true,
}
api.Hosts[config.GetMachineName()] = &host.Host{Driver: d}
kubernetesConfig := KubernetesConfig{
NodeIP: ip,
NodeIP: "192",
}
err := StartCluster(h, kubernetesConfig)
err = StartCluster(api, kubernetesConfig)
if err == nil {
t.Fatal("Error not thrown starting cluster.")
......@@ -337,7 +369,7 @@ func TestGetHostStatus(t *testing.T) {
}
}
checkState("Does Not Exist")
checkState(state.None.String())
createHost(api, defaultMachineConfig)
checkState(state.Running.String())
......@@ -562,7 +594,6 @@ func TestUpdateDefault(t *testing.T) {
t.Fatalf("Error starting ssh server: %s", err)
}
h := tests.NewMockHost()
d := &tests.MockDriver{
Port: port,
BaseDriver: drivers.BaseDriver{
......@@ -575,7 +606,7 @@ func TestUpdateDefault(t *testing.T) {
KubernetesVersion: constants.DefaultKubernetesVersion,
}
if err := UpdateCluster(h, d, kubernetesConfig); err != nil {
if err := UpdateCluster(d, kubernetesConfig); err != nil {
t.Fatalf("Error updating cluster: %s", err)
}
transferred := s.Transfers.Bytes()
......@@ -618,7 +649,6 @@ func TestUpdateKubernetesVersion(t *testing.T) {
t.Fatalf("Error starting ssh server: %s", err)
}
h := tests.NewMockHost()
d := &tests.MockDriver{
Port: port,
BaseDriver: drivers.BaseDriver{
......@@ -632,7 +662,7 @@ func TestUpdateKubernetesVersion(t *testing.T) {
kubernetesConfig := KubernetesConfig{
KubernetesVersion: server.URL,
}
if err := UpdateCluster(h, d, kubernetesConfig); err != nil {
if err := UpdateCluster(d, kubernetesConfig); err != nil {
t.Fatalf("Error updating cluster: %s", err)
}
transferred := s.Transfers.Bytes()
......@@ -698,7 +728,6 @@ func TestUpdateCustomAddons(t *testing.T) {
t.Fatalf("Error starting ssh server: %s", err)
}
h := tests.NewMockHost()
d := &tests.MockDriver{
Port: port,
BaseDriver: drivers.BaseDriver{
......@@ -726,7 +755,7 @@ func TestUpdateCustomAddons(t *testing.T) {
kubernetesConfig := KubernetesConfig{
KubernetesVersion: constants.DefaultKubernetesVersion,
}
if err := UpdateCluster(h, d, kubernetesConfig); err != nil {
if err := UpdateCluster(d, kubernetesConfig); err != nil {
t.Fatalf("Error updating cluster: %s", err)
}
transferred := s.Transfers.Bytes()
......
......@@ -28,8 +28,7 @@ import (
)
// Kill any running instances.
var localkubeStartCmdTemplate = "/usr/local/bin/localkube {{.Flags}} --generate-certs=false --logtostderr=true --enable-dns=false --node-ip={{.NodeIP}}"
var localkubeStartCmdTemplate = "/usr/local/bin/localkube {{.Flags}} --generate-certs=false --logtostderr=true --enable-dns=false"
var localkubeSystemdTmpl = `[Unit]
Description=Localkube
......@@ -123,20 +122,21 @@ func GenLocalkubeStartCmd(kubernetesConfig KubernetesConfig) (string, error) {
flagVals = append(flagVals, "--dns-domain="+kubernetesConfig.DNSDomain)
}
if kubernetesConfig.NodeIP != "127.0.0.1" {
flagVals = append(flagVals, "--node-ip="+kubernetesConfig.NodeIP)
}
for _, e := range kubernetesConfig.ExtraOptions {
flagVals = append(flagVals, fmt.Sprintf("--extra-config=%s", e.String()))
}
flags := strings.Join(flagVals, " ")
t := template.Must(template.New("localkubeStartCmd").Parse(localkubeStartCmdTemplate))
buf := bytes.Buffer{}
data := struct {
Flags string
NodeIP string
APIServerName string
}{
Flags: flags,
NodeIP: kubernetesConfig.NodeIP,
APIServerName: kubernetesConfig.APIServerName,
}
if err := t.Execute(&buf, data); err != nil {
......
......@@ -89,7 +89,7 @@ const (
DefaultDiskSize = "20g"
MinimumDiskSizeMB = 2000
DefaultVMDriver = "virtualbox"
DefaultStatusFormat = "minikubeVM: {{.MinikubeStatus}}\n" +
DefaultStatusFormat = "minikube: {{.MinikubeStatus}}\n" +
"localkube: {{.LocalkubeStatus}}\n"
DefaultAddonListFormat = "- {{.AddonName}}: {{.AddonStatus}}\n"
DefaultConfigViewFormat = "- {{.ConfigKey}}: {{.ConfigValue}}\n"
......@@ -118,6 +118,7 @@ const AddonsPath = "/etc/kubernetes/addons"
const (
RemoteLocalKubeErrPath = "/var/lib/localkube/localkube.err"
RemoteLocalKubeOutPath = "/var/lib/localkube/localkube.out"
LocalkubePIDPath = "/var/run/localkube.pid"
)
const (
......
......@@ -25,6 +25,7 @@ import (
var SupportedVMDrivers = [...]string{
"virtualbox",
"kvm",
"none",
}
var DefaultMountDir = homedir.HomeDir()
......@@ -35,7 +35,7 @@ import (
"github.com/docker/machine/libmachine/check"
"github.com/docker/machine/libmachine/drivers"
"github.com/docker/machine/libmachine/drivers/plugin/localbinary"
"github.com/docker/machine/libmachine/drivers/rpc"
rpcdriver "github.com/docker/machine/libmachine/drivers/rpc"
"github.com/docker/machine/libmachine/engine"
"github.com/docker/machine/libmachine/host"
"github.com/docker/machine/libmachine/mcnutils"
......@@ -73,6 +73,7 @@ func (*rpcClientFactory) NewClient(storePath, certsDir string) libmachine.API {
}
var clientFactories = map[ClientType]clientFactory{
// ClientTypeNative: &nativeClientFactory{},
ClientTypeLocal: &localClientFactory{},
ClientTypeRPC: &rpcClientFactory{},
}
......@@ -80,6 +81,8 @@ var clientFactories = map[ClientType]clientFactory{
const (
ClientTypeLocal ClientType = iota
ClientTypeRPC
// ClientTypeNative
)
// Gets a new client depending on the clientType specified
......@@ -201,12 +204,18 @@ func (api *LocalClient) Create(h *host.Host) error {
{
"Waiting for VM to start.",
func() error {
if h.Driver.DriverName() == "none" {
return nil
}
return mcnutils.WaitFor(drivers.MachineInState(h.Driver, state.Running))
},
},
{
"Provisioning VM.",
func() error {
if h.Driver.DriverName() == "none" {
return nil
}
pv := provision.NewBuildrootProvisioner(h.Driver)
return pv.Provision(*h.HostOptions.SwarmOptions, *h.HostOptions.AuthOptions, *h.HostOptions.EngineOptions)
},
......
......@@ -17,16 +17,20 @@ limitations under the License.
package machine
import (
"encoding/json"
"github.com/docker/machine/drivers/virtualbox"
"github.com/docker/machine/libmachine/drivers"
"github.com/docker/machine/libmachine/drivers/plugin"
"github.com/golang/glog"
"github.com/pkg/errors"
pkgDrivers "k8s.io/minikube/pkg/minikube/machine/drivers"
)
var driverMap = map[string]driverGetter{
"kvm": getKVMDriver,
"virtualbox": getVirtualboxDriver,
"none": getNoneDriver,
}
func getKVMDriver(rawDriver []byte) (drivers.Driver, error) {
......@@ -36,11 +40,22 @@ https://github.com/kubernetes/minikube/blob/master/DRIVERS.md#kvm-driver
`)
}
func getNoneDriver(rawDriver []byte) (drivers.Driver, error) {
var driver drivers.Driver
driver = &pkgDrivers.Driver{}
if err := json.Unmarshal(rawDriver, &driver); err != nil {
return nil, errors.Wrap(err, "Error unmarshalling none driver")
}
return driver, nil
}
// StartDriver starts the desired machine driver if necessary.
func registerDriver(driverName string) {
switch driverName {
case "virtualbox":
plugin.RegisterDriver(virtualbox.NewDriver("", ""))
case "none":
plugin.RegisterDriver(pkgDrivers.NewDriver("", ""))
default:
glog.Exitf("Unsupported driver: %s\n", driverName)
}
......
/*
Copyright 2016 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 drivers
import (
"errors"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/docker/machine/libmachine/drivers"
"github.com/docker/machine/libmachine/mcnflag"
"github.com/docker/machine/libmachine/state"
"k8s.io/minikube/pkg/minikube/constants"
)
const driverName = "none"
// none Driver is a driver designed to run localkube w/o a VM
type Driver struct {
*drivers.BaseDriver
URL string
}
func NewDriver(hostName, storePath string) *Driver {
return &Driver{
BaseDriver: &drivers.BaseDriver{
MachineName: hostName,
StorePath: storePath,
},
}
}
// PreCreateCheck checks that VBoxManage exists and works
func (d *Driver) PreCreateCheck() error {
// check that systemd is installed as it is a requirement
if _, err := exec.LookPath("systemctl"); err != nil {
return errors.New("systemd is a requirement in order to use the none driver")
}
return nil
}
func (d *Driver) GetCreateFlags() []mcnflag.Flag {
return []mcnflag.Flag{}
}
func (d *Driver) Create() error {
// creation for the none driver is handled by commands.go
return nil
}
// DriverName returns the name of the driver
func (d *Driver) DriverName() string {
return driverName
}
func (d *Driver) GetIP() (string, error) {
return "127.0.0.1", nil
}
func (d *Driver) GetSSHHostname() (string, error) {
return "", fmt.Errorf("driver does not support ssh commands")
}
func (d *Driver) GetSSHKeyPath() string {
return ""
}
func (d *Driver) GetSSHPort() (int, error) {
return 0, fmt.Errorf("driver does not support ssh commands")
}
func (d *Driver) GetSSHUsername() string {
return ""
}
func (d *Driver) GetURL() (string, error) {
return "127.0.0.1:8080", nil
}
func (d *Driver) GetState() (state.State, error) {
command := `sudo systemctl is-active localkube 2>&1 1>/dev/null && echo "Running" || echo "Stopped"`
path := filepath.Join(constants.GetMinipath(), "tmp-cmd")
ioutil.WriteFile(filepath.Join(constants.GetMinipath(), "tmp-cmd"), []byte(command), os.FileMode(0644))
defer os.Remove(path)
cmd := exec.Command("sudo", "/bin/sh", path)
out, err := cmd.CombinedOutput()
if err != nil {
return state.None, err
}
s := strings.TrimSpace(string(out))
if state.Running.String() == s {
return state.Running, nil
} else if state.Stopped.String() == s {
return state.Stopped, nil
} else {
return state.None, fmt.Errorf("Error: Unrecognize output from GetLocalkubeStatus: %s", s)
}
}
func (d *Driver) Kill() error {
cmd := exec.Command("sudo", "systemctl", "stop", "localkube.service")
if err := cmd.Start(); err != nil {
return err
}
cmd = exec.Command("sudo", "rm", "-rf", "/var/lib/localkube")
if err := cmd.Start(); err != nil {
return err
}
return nil
}
func (d *Driver) Remove() error {
cmd := exec.Command("sudo", "systemctl", "stop", "localkube.service")
if err := cmd.Start(); err != nil {
return err
}
cmd = exec.Command("sudo", "rm", "-rf", "/var/lib/localkube")
if err := cmd.Start(); err != nil {
return err
}
return nil
}
func (d *Driver) Restart() error {
cmd := exec.Command("sudo", "systemctl", "restart", "localkube.service")
if err := cmd.Start(); err != nil {
return err
}
return nil
}
func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
return nil
}
func (d *Driver) Start() error {
d.IPAddress = "127.0.0.1"
d.URL = "127.0.0.1:8080"
return nil
}
func (d *Driver) Stop() error {
cmd := exec.Command("sudo", "systemctl", "stop", "localkube.service")
if err := cmd.Start(); err != nil {
return err
}
for {
s, err := d.GetState()
if err != nil {
return err
}
if s != state.Running {
break
}
}
return nil
}
func (d *Driver) RunSSHCommandFromDriver() error {
return fmt.Errorf("driver does not support ssh commands")
}
......@@ -29,6 +29,7 @@ import (
func testClusterEnv(t *testing.T) {
t.Parallel()
minikubeRunner := util.MinikubeRunner{
Args: *args,
BinaryPath: *binaryPath,
......
......@@ -32,8 +32,11 @@ func TestDocker(t *testing.T) {
BinaryPath: *binaryPath,
T: t}
minikubeRunner.RunCommand("delete", false)
if strings.Contains(*args, "--vm-driver=none") {
t.Skip("skipping test as none driver does not bundle docker")
}
minikubeRunner.RunCommand("delete", false)
startCmd := fmt.Sprintf("start %s %s", minikubeRunner.Args, "--docker-env=FOO=BAR --docker-env=BAZ=BAT --docker-opt=debug --docker-opt=icc=true")
minikubeRunner.RunCommand(startCmd, true)
minikubeRunner.EnsureRunning()
......
......@@ -19,6 +19,8 @@ limitations under the License.
package integration
import (
"runtime"
"strings"
"testing"
"k8s.io/minikube/test/integration/util"
......@@ -34,15 +36,20 @@ func TestFunctional(t *testing.T) {
// This one is not parallel, and ensures the cluster comes up
// before we run any other tests.
t.Run("Status", testClusterStatus)
t.Run("DNS", testClusterDNS)
t.Run("EnvVars", testClusterEnv)
t.Run("Logs", testClusterLogs)
t.Run("SSH", testClusterSSH)
t.Run("Systemd", testVMSystemd)
t.Run("Addons", testAddons)
t.Run("Dashboard", testDashboard)
t.Run("ServicesList", testServicesList)
t.Run("Provisioning", testProvisioning)
// t.Run("Mounting", testMounting)
if !strings.Contains(*args, "--vm-driver=none") {
t.Run("EnvVars", testClusterEnv)
t.Run("SSH", testClusterSSH)
if runtime.GOOS != "windows" {
t.Run("Systemd", testVMSystemd)
}
// t.Run("Mounting", testMounting)
}
}
......@@ -23,6 +23,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
"time"
......@@ -33,6 +34,9 @@ import (
func testMounting(t *testing.T) {
t.Parallel()
if strings.Contains(*args, "--vm-driver=none") {
t.Skip("skipping test for none driver as it does not need mount")
}
minikubeRunner := util.MinikubeRunner{
Args: *args,
BinaryPath: *binaryPath,
......
......@@ -84,8 +84,16 @@ func TestPersistence(t *testing.T) {
}
// Now restart minikube and make sure the pod is still there.
minikubeRunner.RunCommand("stop", true)
minikubeRunner.CheckStatus("Stopped")
// minikubeRunner.RunCommand("stop", true)
// minikubeRunner.CheckStatus("Stopped")
checkStop := func() error {
minikubeRunner.RunCommand("stop", true)
return minikubeRunner.CheckStatusNoFail(state.Stopped.String())
}
if err := commonutil.RetryAfter(6, checkStop, 5*time.Second); err != nil {
t.Fatalf("timed out while checking stopped status: %s", err)
}
minikubeRunner.Start()
minikubeRunner.CheckStatus(state.Running.String())
......
......@@ -24,6 +24,7 @@ import (
"testing"
"time"
"github.com/docker/machine/libmachine/state"
commonutil "k8s.io/minikube/pkg/util"
"k8s.io/minikube/test/integration/util"
)
......@@ -35,10 +36,10 @@ func TestStartStop(t *testing.T) {
BinaryPath: *binaryPath,
T: t}
runner.RunCommand("delete", false)
runner.CheckStatus("Does Not Exist")
runner.CheckStatus(state.None.String())
runner.Start()
runner.CheckStatus("Running")
runner.CheckStatus(state.Running.String())
ip := runner.RunCommand("ip", true)
ip = strings.TrimRight(ip, "\n")
......@@ -52,7 +53,7 @@ func TestStartStop(t *testing.T) {
checkStop := func() error {
runner.RunCommand("stop", true)
return runner.CheckStatusNoFail("Stopped")
return runner.CheckStatusNoFail(state.Stopped.String())
}
if err := commonutil.RetryAfter(6, checkStop, 5*time.Second); err != nil {
......@@ -60,8 +61,8 @@ func TestStartStop(t *testing.T) {
}
runner.Start()
runner.CheckStatus("Running")
runner.CheckStatus(state.Running.String())
runner.RunCommand("delete", true)
runner.CheckStatus("Does Not Exist")
runner.CheckStatus(state.None.String())
}
......@@ -31,6 +31,7 @@ func testVMSystemd(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("skipping test in windows as it doesn't exit properly")
}
minikubeRunner := util.MinikubeRunner{
Args: *args,
BinaryPath: *binaryPath,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册