Skip to content

Commit f4c01de

Browse files
committed
Make sure vmlinux and initrd file path are not hard coded
1 parent 1c896e0 commit f4c01de

File tree

4 files changed

+124
-100
lines changed

4 files changed

+124
-100
lines changed

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ build: $(BUILD_DIR) vendor
2020
go build \
2121
-installsuffix "static" \
2222
-o $(BUILD_DIR)/docker-machine-driver-hyperkit
23+
chmod +x $(BUILD_DIR)/docker-machine-driver-hyperkit
24+
sudo mv $(BUILD_DIR)/docker-machine-driver-hyperkit /usr/local/bin/ && sudo chown root:wheel /usr/local/bin/docker-machine-driver-hyperkit && sudo chmod u+s /usr/local/bin/docker-machine-driver-hyperkit

pkg/hyperkit/driver.go

Lines changed: 85 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,25 @@ import (
3636
hyperkit "github.com/moby/hyperkit/go"
3737
"github.com/pkg/errors"
3838
pkgdrivers "github.com/praveenkumar/docker-machine-driver-hyperkit/pkg/drivers"
39+
"regexp"
40+
"github.com/docker/machine/libmachine/mcnutils"
3941
)
4042

4143
const (
4244
isoFilename = "boot2docker.iso"
45+
isoMountPath = "b2d-image"
4346
pidFileName = "hyperkit.pid"
4447
machineFileName = "hyperkit.json"
4548
permErr = "%s needs to run with elevated permissions. " +
4649
"Please run the following command, then try again: " +
4750
"sudo chown root:wheel %s && sudo chmod u+s %s"
4851
)
4952

53+
var (
54+
kernelRegexp = regexp.MustCompile(`(vmlinu[xz]|bzImage)[\d]*`)
55+
kernelOptionRegexp = regexp.MustCompile(`(?:\t|\s{2})append\s+([[:print:]]+)`)
56+
)
57+
5058
type Driver struct {
5159
*drivers.BaseDriver
5260
*pkgdrivers.CommonDriver
@@ -58,6 +66,10 @@ type Driver struct {
5866
NFSShares []string
5967
NFSSharesRoot string
6068
UUID string
69+
BootKernel string
70+
BootInitrd string
71+
Initrd string
72+
Vmlinuz string
6173
}
6274

6375
func NewDriver(hostName, storePath string) *Driver {
@@ -169,8 +181,8 @@ func (d *Driver) Start() error {
169181
}
170182

171183
// TODO: handle the rest of our settings.
172-
h.Kernel = d.ResolveStorePath("bzimage")
173-
h.Initrd = d.ResolveStorePath("initrd")
184+
h.Kernel = d.ResolveStorePath(d.Vmlinuz)
185+
h.Initrd =d.ResolveStorePath(d.Initrd)
174186
h.VMNet = true
175187
h.ISOImages = []string{d.ResolveStorePath(isoFilename)}
176188
h.Console = hyperkit.ConsoleFile
@@ -233,19 +245,54 @@ func (d *Driver) Stop() error {
233245
}
234246

235247
func (d *Driver) extractKernel(isoPath string) error {
236-
for _, f := range []struct {
237-
pathInIso string
238-
destPath string
239-
}{
240-
{"/boot/bzimage", "bzimage"},
241-
{"/boot/initrd", "initrd"},
242-
{"/isolinux/isolinux.cfg", "isolinux.cfg"},
243-
} {
244-
fullDestPath := d.ResolveStorePath(f.destPath)
245-
if err := ExtractFile(isoPath, f.pathInIso, fullDestPath); err != nil {
246-
return err
248+
log.Debugf("Mounting %s", isoFilename)
249+
250+
volumeRootDir := d.ResolveStorePath(isoMountPath)
251+
err := hdiutil("attach", d.ResolveStorePath(isoFilename), "-mountpoint", volumeRootDir)
252+
if err != nil {
253+
return err
254+
}
255+
defer func() error {
256+
log.Debugf("Unmounting %s", isoFilename)
257+
return hdiutil("detach", volumeRootDir)
258+
}()
259+
260+
log.Debugf("Extracting Kernel Options...")
261+
if err := d.extractKernelOptions(); err != nil {
262+
return err
263+
}
264+
265+
if d.BootKernel == "" && d.BootInitrd == "" {
266+
filepath.Walk(volumeRootDir, func(path string, f os.FileInfo, err error) error {
267+
if kernelRegexp.MatchString(path) {
268+
d.BootKernel = path
269+
_, d.Vmlinuz = filepath.Split(path)
270+
}
271+
if strings.Contains(path, "initrd") {
272+
d.BootInitrd = path
273+
_, d.Initrd = filepath.Split(path)
274+
}
275+
return nil
276+
})
277+
}
278+
279+
if d.BootKernel == "" || d.BootInitrd == "" {
280+
err := fmt.Errorf("==== Can't extract Kernel and Ramdisk file ====")
281+
return err
247282
}
283+
284+
dest := d.ResolveStorePath(d.Vmlinuz)
285+
log.Debugf("Extracting %s into %s", d.BootKernel, dest)
286+
if err := mcnutils.CopyFile(d.BootKernel, dest); err != nil {
287+
return err
288+
}
289+
290+
dest = d.ResolveStorePath(d.Initrd)
291+
log.Debugf("Extracting %s into %s", d.BootInitrd, dest)
292+
if err := mcnutils.CopyFile(d.BootInitrd, dest); err != nil {
293+
return err
248294
}
295+
249296
return nil
250297
}
251298

@@ -341,3 +388,28 @@ func (d *Driver) cleanupNfsExports() {
341388
}
342389
}
343390
}
391+
392+
func (d *Driver) extractKernelOptions() error {
393+
volumeRootDir := d.ResolveStorePath(isoMountPath)
394+
if d.Cmdline == "" {
395+
err := filepath.Walk(volumeRootDir, func(path string, f os.FileInfo, err error) error {
396+
if strings.Contains(path, "isolinux.cfg") {
397+
d.Cmdline, err = readLine(path)
398+
if err != nil {
399+
return err
400+
}
401+
}
402+
return nil
403+
})
404+
if err != nil {
405+
return err
406+
}
407+
408+
if d.Cmdline == "" {
409+
return errors.New("Not able to parse isolinux.cfg")
410+
}
411+
}
412+
413+
log.Debugf("Extracted Options %q", d.Cmdline)
414+
return nil
415+
}

pkg/hyperkit/iso.go

Lines changed: 0 additions & 87 deletions
This file was deleted.

pkg/hyperkit/util.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ import (
2020
"time"
2121
"errors"
2222
"strings"
23+
"os/exec"
24+
"os"
25+
"github.com/docker/machine/libmachine/log"
26+
"bufio"
27+
"fmt"
2328
)
2429

2530
type RetriableError struct {
@@ -66,4 +71,36 @@ func RetryAfter(attempts int, callback func() error, d time.Duration) (err error
6671
time.Sleep(d)
6772
}
6873
return m.ToError()
74+
}
75+
76+
func hdiutil(args ...string) error {
77+
cmd := exec.Command("hdiutil", args...)
78+
cmd.Stdout = os.Stdout
79+
cmd.Stderr = os.Stderr
80+
81+
log.Debugf("executing: %v %v", cmd, strings.Join(args, " "))
82+
83+
err := cmd.Run()
84+
if err != nil {
85+
return err
86+
}
87+
88+
return nil
89+
}
90+
91+
func readLine(path string) (string, error) {
92+
inFile, err := os.Open(path)
93+
if err != nil {
94+
return "", err
95+
}
96+
defer inFile.Close()
97+
98+
scanner := bufio.NewScanner(inFile)
99+
for scanner.Scan() {
100+
if kernelOptionRegexp.Match(scanner.Bytes()) {
101+
m := kernelOptionRegexp.FindSubmatch(scanner.Bytes())
102+
return string(m[1]), nil
103+
}
104+
}
105+
return "", fmt.Errorf("couldn't find kernel option from %s image", path)
69106
}

0 commit comments

Comments
 (0)