mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-20 17:49:10 +00:00
linuxkit: add -start-vpnkit flag
Adds a flag to launch a new vpnkit instance. This enables port forwarding via a 9p mount (tag:port) if the guest supports it. Vsock port 62373 is also opened so vpnkit can forward connections back to the guest. If -start-vpnkit is not specified HyperKit will connect to the vpnkit instance managed by Docker for Mac, as before. Signed-off-by: Magnus Skjegstad <magnus@skjegstad.com>
This commit is contained in:
parent
32ee53f14e
commit
9c4dc38883
@ -6,6 +6,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
@ -33,6 +34,7 @@ func runHyperKit(args []string) {
|
|||||||
ipStr := flags.String("ip", "", "IP address for the VM")
|
ipStr := flags.String("ip", "", "IP address for the VM")
|
||||||
state := flags.String("state", "", "Path to directory to keep VM state in")
|
state := flags.String("state", "", "Path to directory to keep VM state in")
|
||||||
vsockports := flags.String("vsock-ports", "", "List of vsock ports to forward from the guest on startup (comma separated). A unix domain socket for each port will be created in the state directory")
|
vsockports := flags.String("vsock-ports", "", "List of vsock ports to forward from the guest on startup (comma separated). A unix domain socket for each port will be created in the state directory")
|
||||||
|
startVPNKit := flags.Bool("start-vpnkit", false, "Launch a new VPNKit instead of reusing the instance from Docker for Mac. The new instance will be on a separate internal network. This enables IP port forwarding from the host to the guest if the guest supports it.")
|
||||||
|
|
||||||
if err := flags.Parse(args); err != nil {
|
if err := flags.Parse(args); err != nil {
|
||||||
log.Fatal("Unable to parse args")
|
log.Fatal("Unable to parse args")
|
||||||
@ -96,7 +98,30 @@ func runHyperKit(args []string) {
|
|||||||
*disk = filepath.Join(*state, "disk.img")
|
*disk = filepath.Join(*state, "disk.img")
|
||||||
}
|
}
|
||||||
|
|
||||||
h, err := hyperkit.New(*hyperkitPath, "auto", *state)
|
vpnKitEthernetSocket := "auto"
|
||||||
|
var vpnKitPortSocket string
|
||||||
|
var vpnKitProcess *os.Process
|
||||||
|
|
||||||
|
// Launch new VPNKit if needed
|
||||||
|
if *startVPNKit {
|
||||||
|
vpnKitEthernetSocket = filepath.Join(*state, "vpnkit_eth.sock")
|
||||||
|
vpnKitPortSocket = filepath.Join(*state, "vpnkit_port.sock")
|
||||||
|
vsockSocket := filepath.Join(*state, "connect")
|
||||||
|
vpnKitProcess, err = launchVPNKit(vpnKitEthernetSocket, vsockSocket, vpnKitPortSocket)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("Unable to start vpnkit: ", err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if vpnKitProcess != nil {
|
||||||
|
err := vpnKitProcess.Kill()
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
h, err := hyperkit.New(*hyperkitPath, vpnKitEthernetSocket, *state)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln("Error creating hyperkit: ", err)
|
log.Fatalln("Error creating hyperkit: ", err)
|
||||||
}
|
}
|
||||||
@ -116,8 +141,74 @@ func runHyperKit(args []string) {
|
|||||||
h.Memory = *mem
|
h.Memory = *mem
|
||||||
h.DiskSize = *diskSz
|
h.DiskSize = *diskSz
|
||||||
|
|
||||||
|
// Add 9p and vsock for port forwarding if VPNKit is launched automatically
|
||||||
|
if *startVPNKit {
|
||||||
|
// The guest will use this 9P mount to configure which ports to forward
|
||||||
|
h.Sockets9P = []hyperkit.Socket9P{{Path: vpnKitPortSocket, Tag: "port"}}
|
||||||
|
// VSOCK port 62373 is used to pass traffic from host->guest
|
||||||
|
h.VSockPorts = append(h.VSockPorts, 62373)
|
||||||
|
}
|
||||||
|
|
||||||
err = h.Run(string(cmdline))
|
err = h.Run(string(cmdline))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Cannot run hyperkit: %v", err)
|
log.Fatalf("Cannot run hyperkit: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// createListenSocket creates a new unix domain socket and returns the open file
|
||||||
|
func createListenSocket(path string) (*os.File, error) {
|
||||||
|
os.Remove(path)
|
||||||
|
conn, err := net.ListenUnix("unix", &net.UnixAddr{Name: path, Net: "unix"})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to create socket: %v", err)
|
||||||
|
}
|
||||||
|
f, err := conn.File()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return f, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// launchVPNKit starts a new instance of VPNKit. Ethernet socket and port socket
|
||||||
|
// will be created and passed to VPNKit. The VSOCK socket should be created
|
||||||
|
// by HyperKit when it starts.
|
||||||
|
func launchVPNKit(etherSock string, vsockSock string, portSock string) (*os.Process, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
vpnKitPath, err := exec.LookPath("vpnkit")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Unable to find vpnkit binary")
|
||||||
|
}
|
||||||
|
|
||||||
|
etherFile, err := createListenSocket(etherSock)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
portFile, err := createListenSocket(portSock)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command(vpnKitPath,
|
||||||
|
"--ethernet", "fd:3",
|
||||||
|
"--vsock-path", vsockSock,
|
||||||
|
"--port", "fd:4")
|
||||||
|
|
||||||
|
cmd.ExtraFiles = append(cmd.ExtraFiles, etherFile)
|
||||||
|
cmd.ExtraFiles = append(cmd.ExtraFiles, portFile)
|
||||||
|
|
||||||
|
cmd.Env = os.Environ() // pass env for DEBUG
|
||||||
|
|
||||||
|
cmd.Stdin = os.Stdin
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
|
if err := cmd.Start(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
go cmd.Wait() // run in background
|
||||||
|
|
||||||
|
return cmd.Process, nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user