@@ -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
4143const (
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+
5058type 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
6375func 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
235247func (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+ }
0 commit comments