Skip to content

Commit f88bcd8

Browse files
author
seborama
committed
Added hyperkit options for enterprise VPN support
The purpose of these changes is to enhance Hyperkit support from the minikube command line for better integration with enterprise networks behind a VPN. uuid: Provide VM UUID to restore MAC address (only supported with Hyperkit driver). vpnkitSock: Location of the VPNKit socket used for networking. If empty, disables Hyperkit VPNKitSock, if 'auto' uses Docker for Mac VPNKit connection, otherwise uses the specified VSock." vsockPorts: List of guest VSock ports that should be exposed as sockets on the host (Only supported on with hyperkit now). Note: tests pass but file: `vendor/github.com/google/certificate-transparency/go/x509/root_darwin.go` has to be edited to correct an issue - not committed since this is in the vendor directory.
1 parent c6239b4 commit f88bcd8

File tree

3 files changed

+143
-16
lines changed

3 files changed

+143
-16
lines changed

Diff for: Makefile

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ REPOPATH ?= $(ORG)/docker-machine-driver-hyperkit
77
vendor:
88
dep ensure -v
99

10+
.PHONY: test
11+
test: vendor
12+
go test -cover -race -parallel 2 ./...
13+
1014
$(BUILD_DIR):
1115
mkdir -p $(BUILD_DIR)
1216

Diff for: pkg/hyperkit/driver.go

+53-16
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,21 @@ import (
2525
"os/user"
2626
"path"
2727
"path/filepath"
28+
"strconv"
2829
"strings"
2930
"syscall"
3031
"time"
3132

33+
"regexp"
34+
3235
"github.com/docker/machine/libmachine/drivers"
3336
"github.com/docker/machine/libmachine/log"
37+
"github.com/docker/machine/libmachine/mcnutils"
3438
"github.com/docker/machine/libmachine/state"
3539
nfsexports "github.com/johanneswuerbach/nfsexports"
40+
pkgdrivers "github.com/machine-drivers/docker-machine-driver-hyperkit/pkg/drivers"
3641
hyperkit "github.com/moby/hyperkit/go"
3742
"github.com/pkg/errors"
38-
pkgdrivers "github.com/machine-drivers/docker-machine-driver-hyperkit/pkg/drivers"
39-
"regexp"
40-
"github.com/docker/machine/libmachine/mcnutils"
4143
)
4244

4345
const (
@@ -66,10 +68,12 @@ type Driver struct {
6668
NFSShares []string
6769
NFSSharesRoot string
6870
UUID string
69-
BootKernel string
70-
BootInitrd string
71-
Initrd string
72-
Vmlinuz string
71+
BootKernel string
72+
BootInitrd string
73+
Initrd string
74+
Vmlinuz string
75+
VpnKitSock string
76+
VSockPorts []string
7377
}
7478

7579
func NewDriver(hostName, storePath string) *Driver {
@@ -103,7 +107,7 @@ func (d *Driver) Create() error {
103107

104108
isoPath := d.ResolveStorePath(isoFilename)
105109
if err := d.extractKernel(isoPath); err != nil {
106-
return err
110+
return errors.Wrap(err, "extracting kernel")
107111
}
108112

109113
return d.Start()
@@ -175,25 +179,33 @@ func (d *Driver) Restart() error {
175179

176180
// Start a host
177181
func (d *Driver) Start() error {
178-
h, err := hyperkit.New("", "", filepath.Join(d.StorePath, "machines", d.MachineName))
182+
log.Infof("SEBDEBUG - VpnKitSock=%s\n", d.VpnKitSock)
183+
h, err := hyperkit.New("", d.VpnKitSock, filepath.Join(d.StorePath, "machines", d.MachineName))
179184
if err != nil {
180-
return err
185+
return errors.Wrap(err, "new-ing Hyperkit")
181186
}
182187

183188
// TODO: handle the rest of our settings.
184189
h.Kernel = d.ResolveStorePath(d.Vmlinuz)
185-
h.Initrd =d.ResolveStorePath(d.Initrd)
190+
h.Initrd = d.ResolveStorePath(d.Initrd)
186191
h.VMNet = true
187192
h.ISOImages = []string{d.ResolveStorePath(isoFilename)}
188193
h.Console = hyperkit.ConsoleFile
189194
h.CPUs = d.CPU
190195
h.Memory = d.Memory
191196
h.UUID = d.UUID
192197

198+
if vsockPorts, err := d.extractVSockPorts(); err != nil {
199+
return err
200+
} else if len(vsockPorts) >= 1 {
201+
h.VSock = true
202+
h.VSockPorts = vsockPorts
203+
}
204+
193205
log.Infof("Using UUID %s", h.UUID)
194206
mac, err := GetMACAddressFromUUID(h.UUID)
195207
if err != nil {
196-
return err
208+
return errors.Wrap(err, "getting MAC address from UUID")
197209
}
198210

199211
// Need to strip 0's
@@ -208,7 +220,7 @@ func (d *Driver) Start() error {
208220
}
209221
log.Infof("Starting with cmdline: %s", d.Cmdline)
210222
if err := h.Start(d.Cmdline); err != nil {
211-
return err
223+
return errors.Wrapf(err, "starting with cmd line: %s", d.Cmdline)
212224
}
213225

214226
getIP := func() error {
@@ -275,11 +287,11 @@ func (d *Driver) extractKernel(isoPath string) error {
275287
return nil
276288
})
277289
}
278-
279-
if d.BootKernel == "" || d.BootInitrd == "" {
290+
291+
if d.BootKernel == "" || d.BootInitrd == "" {
280292
err := fmt.Errorf("==== Can't extract Kernel and Ramdisk file ====")
281293
return err
282-
}
294+
}
283295

284296
dest := d.ResolveStorePath(d.Vmlinuz)
285297
log.Debugf("Extracting %s into %s", d.BootKernel, dest)
@@ -296,6 +308,31 @@ func (d *Driver) extractKernel(isoPath string) error {
296308
return nil
297309
}
298310

311+
// InvalidPortNumberError implements the Error interface.
312+
// It is used when a VSockPorts port number cannot be recognised as an integer.
313+
type InvalidPortNumberError string
314+
315+
// Error returns an Error for InvalidPortNumberError
316+
func (port InvalidPortNumberError) Error() string {
317+
return fmt.Sprintf("vsock port '%s' is not an integer", string(port))
318+
}
319+
320+
func (d *Driver) extractVSockPorts() ([]int, error) {
321+
vsockPorts := make([]int, 0, len(d.VSockPorts))
322+
323+
for _, port := range d.VSockPorts {
324+
p, err := strconv.Atoi(port)
325+
if err != nil {
326+
var err InvalidPortNumberError
327+
err = InvalidPortNumberError(port)
328+
return nil, err
329+
}
330+
vsockPorts = append(vsockPorts, p)
331+
}
332+
333+
return vsockPorts, nil
334+
}
335+
299336
func (d *Driver) setupNFSShare() error {
300337
user, err := user.Current()
301338
if err != nil {

Diff for: pkg/hyperkit/driver_test.go

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// +build darwin
2+
3+
/*
4+
Copyright 2018 The Kubernetes Authors All rights reserved.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
package hyperkit
20+
21+
import (
22+
"testing"
23+
)
24+
25+
func Test_portExtraction(t *testing.T) {
26+
tests := []struct {
27+
name string
28+
ports []string
29+
want []int
30+
wantErr error
31+
}{
32+
{
33+
"valid_empty",
34+
[]string{},
35+
[]int{},
36+
nil,
37+
},
38+
{
39+
"valid_list",
40+
[]string{"10", "20", "30"},
41+
[]int{10, 20, 30},
42+
nil,
43+
},
44+
{
45+
"invalid",
46+
[]string{"8080", "not_an_integer"},
47+
nil,
48+
InvalidPortNumberError("not_an_integer"),
49+
},
50+
}
51+
52+
for _, tt := range tests {
53+
d := NewDriver("", "")
54+
d.VSockPorts = tt.ports
55+
got, gotErr := d.extractVSockPorts()
56+
if !testEq(got, tt.want) {
57+
t.Errorf("extractVSockPorts() got: %v, want: %v", got, tt.want)
58+
}
59+
if gotErr != tt.wantErr {
60+
t.Errorf("extractVSockPorts() gotErr: %s, wantErr: %s", gotErr.Error(), tt.wantErr.Error())
61+
}
62+
}
63+
}
64+
65+
func testEq(a, b []int) bool {
66+
67+
if a == nil && b == nil {
68+
return true
69+
}
70+
71+
if a == nil || b == nil {
72+
return false
73+
}
74+
75+
if len(a) != len(b) {
76+
return false
77+
}
78+
79+
for i := range a {
80+
if a[i] != b[i] {
81+
return false
82+
}
83+
}
84+
85+
return true
86+
}

0 commit comments

Comments
 (0)