Merge pull request #1459 from aaron-prindle/add-mount-daemon

Added mount daemon process that is starts/stops w/ minikube start/stop
pull/1120/merge
Aaron Prindle 2017-05-17 13:34:22 -07:00 committed by GitHub
commit d4b5b62b2e
14 changed files with 135 additions and 15 deletions

View File

@ -21,6 +21,7 @@ import (
"os"
"github.com/spf13/cobra"
cmdUtil "k8s.io/minikube/cmd/util"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/machine"
)
@ -45,6 +46,10 @@ associated files.`,
os.Exit(1)
}
fmt.Println("Machine deleted.")
if err := cmdUtil.KillMountProcess(); err != nil {
fmt.Println("Errors occurred deleting mount process: ", err)
}
},
}

View File

@ -26,14 +26,15 @@ import (
"github.com/golang/glog"
"github.com/spf13/cobra"
cmdUtil "k8s.io/minikube/cmd/util"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/third_party/go9p/ufs"
)
var mountIP string
var isKill bool
// mountCmd represents the mount command
var mountCmd = &cobra.Command{
@ -41,6 +42,14 @@ var mountCmd = &cobra.Command{
Short: "Mounts the specified directory into minikube",
Long: `Mounts the specified directory into minikube.`,
Run: func(cmd *cobra.Command, args []string) {
if isKill {
if err := cmdUtil.KillMountProcess(); err != nil {
fmt.Println("Errors occurred deleting mount process: ", err)
os.Exit(1)
}
os.Exit(0)
}
if len(args) != 1 {
errText := `Please specify the directory to be mounted:
\tminikube mount HOST_MOUNT_DIRECTORY:VM_MOUNT_DIRECTORY(ex:"/host-home:/vm-home")
@ -104,13 +113,18 @@ var mountCmd = &cobra.Command{
}
fmt.Printf("Mounting %s into %s on the minikubeVM\n", hostPath, vmPath)
fmt.Println("This daemon process needs to stay alive for the mount to still be accessible...")
port, err := cmdUtil.GetPort()
if err != nil {
glog.Errorln("Error finding port for mount: ", err)
os.Exit(1)
}
var wg sync.WaitGroup
wg.Add(1)
go func() {
ufs.StartServer(net.JoinHostPort(ip.String(), constants.DefaultUfsPort), debugVal, hostPath)
ufs.StartServer(net.JoinHostPort(ip.String(), port), debugVal, hostPath)
wg.Done()
}()
err = cluster.MountHost(api, vmPath, ip)
err = cluster.MountHost(api, vmPath, ip, port)
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
@ -121,5 +135,6 @@ var mountCmd = &cobra.Command{
func init() {
mountCmd.Flags().StringVar(&mountIP, "ip", "", "Specify the ip that the mount should be setup on")
mountCmd.Flags().BoolVar(&isKill, "kill", false, "Kill the mount process spawned by minikube start")
RootCmd.AddCommand(mountCmd)
}

View File

@ -19,6 +19,7 @@ package cmd
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"
@ -30,6 +31,8 @@ import (
"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"
@ -55,9 +58,11 @@ const (
hypervVirtualSwitch = "hyperv-virtual-switch"
kvmNetwork = "kvm-network"
keepContext = "keep-context"
noMount = "no-mount"
featureGates = "feature-gates"
apiServerName = "apiserver-name"
dnsDomain = "dns-domain"
mountString = "mount-string"
)
var (
@ -197,8 +202,35 @@ func runStart(cmd *cobra.Command, args []string) {
cmdUtil.MaybeReportErrorAndExit(err)
}
fmt.Printf("Setting up hostmount on %s...\n", viper.GetString(mountString))
// start 9p server mount
if !viper.GetBool(noMount) || cfg.GetMachineName() != constants.DefaultMachineName {
path := os.Args[0]
mountDebugVal := 0
if glog.V(8) {
mountDebugVal = 1
}
mountCmd := exec.Command(path, "mount", fmt.Sprintf("--v=%d", mountDebugVal), viper.GetString(mountString))
mountCmd.Env = append(os.Environ(), constants.IsMinikubeChildProcess+"=true")
if glog.V(8) {
mountCmd.Stdout = os.Stdout
mountCmd.Stderr = os.Stderr
}
err = mountCmd.Start()
if err != nil {
glog.Errorf("Error running command minikube mount %s", err)
cmdUtil.MaybeReportErrorAndExit(err)
}
err = ioutil.WriteFile(filepath.Join(constants.GetMinipath(), constants.MountProcessFileName), []byte(strconv.Itoa(mountCmd.Process.Pid)), 0644)
if err != nil {
glog.Errorf("Error writing mount process pid to file: %s", err)
cmdUtil.MaybeReportErrorAndExit(err)
}
}
if kubeCfgSetup.KeepContext {
fmt.Printf("The local Kubernetes cluster has started. The kubectl context has not been altered, kubectl will require \"--context=%s\" to use the local Kubernetes cluster.\n", kubeCfgSetup.ClusterName)
fmt.Printf("The local Kubernetes cluster has started. The kubectl context has not been altered, kubectl will require \"--context=%s\" to use the local Kubernetes cluster.\n",
kubeCfgSetup.ClusterName)
} else {
fmt.Println("Kubectl is now configured to use the cluster.")
}
@ -227,6 +259,8 @@ func calculateDiskSizeInMB(humanReadableDiskSize string) int {
func init() {
startCmd.Flags().Bool(keepContext, constants.DefaultKeepContext, "This will keep the existing kubectl context and will create a minikube context.")
startCmd.Flags().Bool(noMount, constants.DefaultNoMount, "This will not start the mount daemon and automatically mount files into minikube")
startCmd.Flags().String(mountString, constants.DefaultMountDir+":"+constants.DefaultMountEndpoint, "The argument to pass the minikube mount command on start")
startCmd.Flags().String(isoURL, constants.DefaultIsoUrl, "Location of the minikube iso")
startCmd.Flags().String(vmDriver, constants.DefaultVMDriver, fmt.Sprintf("VM driver is one of: %v", constants.SupportedVMDrivers))
startCmd.Flags().Int(memory, constants.DefaultMemory, "Amount of RAM allocated to the minikube VM")

View File

@ -46,6 +46,10 @@ itself, leaving all files intact. The cluster can be started again with the "sta
cmdUtil.MaybeReportErrorAndExit(err)
}
fmt.Println("Machine stopped.")
if err := cmdUtil.KillMountProcess(); err != nil {
fmt.Println("Errors occurred deleting mount process: ", err)
}
},
}

View File

@ -17,12 +17,12 @@ limitations under the License.
package main
import (
"github.com/pkg/profile"
"k8s.io/minikube/cmd/minikube/cmd"
"k8s.io/minikube/pkg/minikube/machine"
"os"
"github.com/pkg/profile"
"k8s.io/minikube/cmd/minikube/cmd"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/machine"
_ "k8s.io/minikube/pkg/provision"
)
@ -32,6 +32,8 @@ func main() {
if os.Getenv(minikubeEnvPrefix) == "1" {
defer profile.Start(profile.TraceProfile).Stop()
}
machine.StartDriver()
if os.Getenv(constants.IsMinikubeChildProcess) == "" {
machine.StartDriver()
}
cmd.Execute()
}

View File

@ -22,13 +22,18 @@ import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"time"
"strconv"
"github.com/golang/glog"
"github.com/pkg/errors"
"github.com/spf13/viper"
@ -210,3 +215,34 @@ minikube config set WantKubectlDownloadMsg false
verb, fmt.Sprintf(installInstructions, constants.DefaultKubernetesVersion, goos, runtime.GOARCH))
}
}
// Ask the kernel for a free open port that is ready to use
func GetPort() (string, error) {
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
if err != nil {
panic(err)
}
l, err := net.ListenTCP("tcp", addr)
if err != nil {
return "", errors.Errorf("Error accessing port %d", addr.Port)
}
defer l.Close()
return strconv.Itoa(l.Addr().(*net.TCPAddr).Port), nil
}
func KillMountProcess() error {
out, err := ioutil.ReadFile(filepath.Join(constants.GetMinipath(), constants.MountProcessFileName))
if err != nil {
return errors.Wrap(err, "error reading mount process from file")
}
pid, err := strconv.Atoi(string(out))
if err != nil {
return errors.Wrap(err, "error converting mount string to pid")
}
mountProc, err := os.FindProcess(pid)
if err != nil {
return errors.Wrap(err, "error converting mount string to pid")
}
return mountProc.Kill()
}

View File

@ -46,7 +46,7 @@ sudo rm -rf $HOME/.minikube || true
# 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}
out/e2e-${OS_ARCH} -minikube-args="--vm-driver=${VM_DRIVER} --v=10 --no-mount" -test.v -test.timeout=30m -binary=out/minikube-${OS_ARCH}
result=$?
set -e

View File

@ -21,7 +21,7 @@ gsutil.cmd cp -r gs://minikube-builds/$env:MINIKUBE_LOCATION/testdata .
./out/minikube-windows-amd64.exe delete
Remove-Item -Recurse -Force C:\Users\jenkins\.minikube
out/e2e-windows-amd64.exe --% -minikube-args="--vm-driver=hyperv --hyperv-virtual-switch=Minikube --cpus=4 $env:EXTRA_BUILD_ARGS" -test.v -test.timeout=30m -binary=out/minikube-windows-amd64.exe
out/e2e-windows-amd64.exe --% -minikube-args="--vm-driver=hyperv --hyperv-virtual-switch=Minikube --cpus=4 $env:EXTRA_BUILD_ARGS --no-mount" -test.v -test.timeout=30m -binary=out/minikube-windows-amd64.exe
$env:result=$lastexitcode
# If the last exit code was 0->success, x>0->error

View File

@ -402,7 +402,7 @@ func GetHostLogs(api libmachine.API, follow bool) (string, error) {
}
// MountHost runs the mount command from the 9p client on the VM to the 9p server on the host
func MountHost(api libmachine.API, path string, ip net.IP) error {
func MountHost(api libmachine.API, path string, ip net.IP, port string) error {
host, err := CheckIfApiExistsAndLoad(api)
if err != nil {
return errors.Wrap(err, "Error checking that api exists and loading it")
@ -414,7 +414,7 @@ func MountHost(api libmachine.API, path string, ip net.IP) error {
}
}
host.RunSSHCommand(GetMountCleanupCommand(path))
mountCmd, err := GetMountCommand(ip, path)
mountCmd, err := GetMountCommand(ip, path, port)
if err != nil {
return errors.Wrap(err, "Error getting mount command")
}

View File

@ -184,18 +184,20 @@ sudo rm -rf %s;
var mountTemplate = `
sudo mkdir -p {{.Path}};
sudo mount -t 9p -o trans=tcp -o port=5640 -o uid=1001 -o gid=1001 {{.IP}} {{.Path}};
sudo mount -t 9p -o trans=tcp -o port={{.Port}} -o uid=1001 -o gid=1001 {{.IP}} {{.Path}};
sudo chmod 775 {{.Path}};`
func GetMountCommand(ip net.IP, path string) (string, error) {
func GetMountCommand(ip net.IP, path string, port string) (string, error) {
t := template.Must(template.New("mountCommand").Parse(mountTemplate))
buf := bytes.Buffer{}
data := struct {
IP string
Path string
Port string
}{
IP: ip.String(),
Path: path,
Port: port,
}
if err := t.Execute(&buf, data); err != nil {
return "", err

View File

@ -73,6 +73,8 @@ func MakeMiniPath(fileName ...string) string {
return filepath.Join(args...)
}
var MountProcessFileName = ".mount-process"
// Only pass along these flags to localkube.
var LogFlags = [...]string{
"v",
@ -127,4 +129,7 @@ const (
const (
DefaultUfsPort = "5640"
DefaultUfsDebugLvl = 0
DefaultNoMount = false
)
const IsMinikubeChildProcess = "IS_MINIKUBE_CHILD_PROCESS"

View File

@ -23,3 +23,6 @@ var SupportedVMDrivers = [...]string{
"xhyve",
"vmwarefusion",
}
var DefaultMountDir = "/Users"
var DefaultMountEndpoint = "/Users"

View File

@ -18,7 +18,14 @@ limitations under the License.
package constants
import (
"k8s.io/client-go/util/homedir"
)
var SupportedVMDrivers = [...]string{
"virtualbox",
"kvm",
}
var DefaultMountDir = homedir.HomeDir()
var DefaultMountEndpoint = "/hosthome"

View File

@ -18,7 +18,14 @@ limitations under the License.
package constants
import (
"k8s.io/client-go/util/homedir"
)
var SupportedVMDrivers = [...]string{
"virtualbox",
"hyperv",
}
var DefaultMountDir = homedir.HomeDir()
var DefaultMountEndpoint = "/hostmount"