Merge pull request #1459 from aaron-prindle/add-mount-daemon
Added mount daemon process that is starts/stops w/ minikube start/stoppull/1120/merge
commit
d4b5b62b2e
|
@ -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)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -23,3 +23,6 @@ var SupportedVMDrivers = [...]string{
|
|||
"xhyve",
|
||||
"vmwarefusion",
|
||||
}
|
||||
|
||||
var DefaultMountDir = "/Users"
|
||||
var DefaultMountEndpoint = "/Users"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue