diff --git a/src/cmd/moby/build.go b/src/cmd/moby/build.go index 4eacf97d7..5fffb34f6 100644 --- a/src/cmd/moby/build.go +++ b/src/cmd/moby/build.go @@ -19,8 +19,7 @@ import ( func build(args []string) { buildCmd := flag.NewFlagSet("build", flag.ExitOnError) buildCmd.Usage = func() { - fmt.Printf("USAGE: %s build [options] [file.yml]\n\n", os.Args[0]) - fmt.Printf("'file.yml' defaults to 'moby.yml' if not specified.\n\n") + fmt.Printf("USAGE: %s build [options] [.yml]\n\n", os.Args[0]) fmt.Printf("Options:\n") buildCmd.PrintDefaults() } @@ -30,9 +29,14 @@ func build(args []string) { buildCmd.Parse(args) remArgs := buildCmd.Args() - conf := "moby.yml" - if len(remArgs) > 0 { - conf = remArgs[0] + if len(remArgs) == 0 { + fmt.Println("Please specify a configuration file\n") + buildCmd.Usage() + os.Exit(1) + } + conf := remArgs[0] + if filepath.Ext(conf) == "" { + conf = conf + ".yml" } buildInternal(*buildName, *buildPull, conf) diff --git a/src/cmd/moby/run_hyperkit.go b/src/cmd/moby/run_hyperkit.go index e0df419b6..ab9ded647 100644 --- a/src/cmd/moby/run_hyperkit.go +++ b/src/cmd/moby/run_hyperkit.go @@ -8,56 +8,79 @@ import ( log "github.com/Sirupsen/logrus" "github.com/docker/hyperkit/go" + "github.com/rneugeba/iso9660wrap" ) // Process the run arguments and execute run func runHyperKit(args []string) { hyperkitCmd := flag.NewFlagSet("hyperkit", flag.ExitOnError) hyperkitCmd.Usage = func() { - fmt.Printf("USAGE: %s run hyperkit [options] [prefix]\n\n", os.Args[0]) + fmt.Printf("USAGE: %s run hyperkit [options] prefix\n\n", os.Args[0]) fmt.Printf("'prefix' specifies the path to the VM image.\n") - fmt.Printf("It defaults to './moby'.\n") fmt.Printf("\n") fmt.Printf("Options:\n") hyperkitCmd.PrintDefaults() } - runHyperKit := hyperkitCmd.String("hyperkit", "", "Path to hyperkit binary (if not in default location)") - runCPUs := hyperkitCmd.Int("cpus", 1, "Number of CPUs") - runMem := hyperkitCmd.Int("mem", 1024, "Amount of memory in MB") - runDiskSz := hyperkitCmd.Int("disk-size", 0, "Size of Disk in MB") - runDisk := hyperkitCmd.String("disk", "", "Path to disk image to used") + hyperkitPath := hyperkitCmd.String("hyperkit", "", "Path to hyperkit binary (if not in default location)") + cpus := hyperkitCmd.Int("cpus", 1, "Number of CPUs") + mem := hyperkitCmd.Int("mem", 1024, "Amount of memory in MB") + diskSz := hyperkitCmd.Int("disk-size", 0, "Size of Disk in MB") + disk := hyperkitCmd.String("disk", "", "Path to disk image to used") + data := hyperkitCmd.String("data", "", "Metadata to pass to VM (either a path to a file or a string)") hyperkitCmd.Parse(args) remArgs := hyperkitCmd.Args() + if len(remArgs) == 0 { + fmt.Println("Please specify the prefix to the image to boot\n") + hyperkitCmd.Usage() + os.Exit(1) + } + prefix := remArgs[0] - prefix := "moby" - if len(remArgs) > 0 { - prefix = remArgs[0] + isoPath := "" + if *data != "" { + var d []byte + if _, err := os.Stat(*data); os.IsNotExist(err) { + d = []byte(*data) + } else { + d, err = ioutil.ReadFile(*data) + if err != nil { + log.Fatalf("Cannot read user data: %v", err) + } + } + isoPath = prefix + "-data.iso" + outfh, err := os.OpenFile(isoPath, os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Fatalf("Cannot create user data ISO: %v", err) + } + err = iso9660wrap.WriteBuffer(outfh, d, "config") + if err != nil { + log.Fatalf("Cannot write user data ISO: %v", err) + } + outfh.Close() } - runHyperKitInternal(*runHyperKit, *runCPUs, *runMem, *runDiskSz, *runDisk, prefix) -} - -func runHyperKitInternal(hyperkitPath string, cpus, mem, diskSz int, disk, prefix string) { + // Run cmdline, err := ioutil.ReadFile(prefix + "-cmdline") if err != nil { log.Fatalf("Cannot open cmdline file: %v", err) } - if diskSz != 0 && disk == "" { - disk = prefix + "-disk.img" + if *diskSz != 0 && *disk == "" { + *disk = prefix + "-disk.img" } - h, err := hyperkit.New(hyperkitPath, "", "auto", disk) + h, err := hyperkit.New(*hyperkitPath, "", "auto", *disk) if err != nil { log.Fatalln("Error creating hyperkit: ", err) } h.Kernel = prefix + "-bzImage" h.Initrd = prefix + "-initrd.img" - h.CPUs = cpus - h.Memory = mem - h.DiskSize = diskSz + h.ISOImage = isoPath + h.CPUs = *cpus + h.Memory = *mem + h.DiskSize = *diskSz err = h.Run(string(cmdline)) if err != nil { diff --git a/vendor/github.com/rneugeba/iso9660wrap/iso9660wrap.go b/vendor/github.com/rneugeba/iso9660wrap/iso9660wrap.go index 7acf7f78f..d18049c70 100644 --- a/vendor/github.com/rneugeba/iso9660wrap/iso9660wrap.go +++ b/vendor/github.com/rneugeba/iso9660wrap/iso9660wrap.go @@ -2,6 +2,7 @@ package iso9660wrap import ( "bufio" + "bytes" "encoding/binary" "fmt" "io" @@ -154,21 +155,38 @@ const rootDirectorySectorNum uint32 = primaryVolumeSectorNum + numVolumeSectors // WriteFile writes the contents of infh to an iso at outfh with the name provided func WriteFile(outfh, infh *os.File) error { - inputFileSize, inputFilename, err := getInputFileSizeAndName(infh) + fileSize, filename, err := getInputFileSizeAndName(infh) if err != nil { return err } - if inputFileSize == 0 { + if fileSize == 0 { return fmt.Errorf("input file must be at least 1 byte in size") } - inputFilename = strings.ToUpper(inputFilename) - if !filenameSatisfiesISOConstraints(inputFilename) { - return fmt.Errorf("Input file name %s does not satisfy the ISO9660 character set constraints", inputFilename) + filename = strings.ToUpper(filename) + if !filenameSatisfiesISOConstraints(filename) { + return fmt.Errorf("Input file name %s does not satisfy the ISO9660 character set constraints", filename) } + buf := make([]byte, fileSize, fileSize) + _, err = infh.Read(buf) + if err != nil { + return err + } + + return WriteBuffer(outfh, buf, filename) +} + +// WriteBuffer writes the contents of buf to an iso at outfh with the name provided +func WriteBuffer(outfh *os.File, buf []byte, filename string) error { + fileSize := uint32(len(buf)) + if fileSize == 0 { + return fmt.Errorf("input buffer must be at least 1 byte in size") + } + r := bytes.NewReader(buf) + // reserved sectors reservedAreaLength := int64(16 * SectorSize) - _, err = outfh.Write([]byte(reservedAreaData)) + _, err := outfh.Write([]byte(reservedAreaData)) if err != nil { return fmt.Errorf("could not write to output file: %s", err) } @@ -198,11 +216,11 @@ func WriteFile(outfh, infh *os.File) error { w := NewISO9660Writer(bufw) - writePrimaryVolumeDescriptor(w, inputFileSize, inputFilename) + writePrimaryVolumeDescriptor(w, fileSize, filename) writeVolumeDescriptorSetTerminator(w) writePathTable(w, binary.LittleEndian) writePathTable(w, binary.BigEndian) - writeData(w, infh, inputFileSize, inputFilename) + writeData(w, r, fileSize, filename) w.Finish() @@ -217,9 +235,9 @@ func WriteFile(outfh, infh *os.File) error { return nil } -func writePrimaryVolumeDescriptor(w *ISO9660Writer, inputFileSize uint32, inputFilename string) { - if len(inputFilename) > 32 { - inputFilename = inputFilename[:32] +func writePrimaryVolumeDescriptor(w *ISO9660Writer, fileSize uint32, filename string) { + if len(filename) > 32 { + filename = filename[:32] } now := time.Now() @@ -233,10 +251,10 @@ func writePrimaryVolumeDescriptor(w *ISO9660Writer, inputFileSize uint32, inputF sw.WriteByte('\x00') sw.WritePaddedString("", 32) - sw.WritePaddedString(inputFilename, 32) + sw.WritePaddedString(filename, 32) sw.WriteZeros(8) - sw.WriteBothEndianDWord(numTotalSectors(inputFileSize)) + sw.WriteBothEndianDWord(numTotalSectors(fileSize)) sw.WriteZeros(32) sw.WriteBothEndianWord(1) // volume set size @@ -294,7 +312,7 @@ func writePathTable(w *ISO9660Writer, bo binary.ByteOrder) { sw.PadWithZeros() } -func writeData(w *ISO9660Writer, infh io.Reader, inputFileSize uint32, inputFilename string) { +func writeData(w *ISO9660Writer, infh io.Reader, fileSize uint32, filename string) { sw := w.NextSector() if w.CurrentSector() != rootDirectorySectorNum { Panicf("internal error: unexpected root directory sector %d", w.CurrentSector()) @@ -302,7 +320,7 @@ func writeData(w *ISO9660Writer, infh io.Reader, inputFileSize uint32, inputFile WriteDirectoryRecord(sw, "\x00", w.CurrentSector()) WriteDirectoryRecord(sw, "\x01", rootDirectorySectorNum) - WriteFileRecordHeader(sw, inputFilename, w.CurrentSector()+1, inputFileSize) + WriteFileRecordHeader(sw, filename, w.CurrentSector()+1, fileSize) // Now stream the data. Note that the first buffer is never of SectorSize, // since we've already filled a part of the sector. @@ -322,17 +340,17 @@ func writeData(w *ISO9660Writer, infh io.Reader, inputFileSize uint32, inputFile break } } - if total != inputFileSize { - Panicf("input file size changed while the ISO file was being created (expected to read %d, read %d)", inputFileSize, total) - } else if w.CurrentSector() != numTotalSectors(inputFileSize)-1 { + if total != fileSize { + Panicf("input file size changed while the ISO file was being created (expected to read %d, read %d)", fileSize, total) + } else if w.CurrentSector() != numTotalSectors(fileSize)-1 { Panicf("internal error: unexpected last sector number (expected %d, actual %d)", - numTotalSectors(inputFileSize)-1, w.CurrentSector()) + numTotalSectors(fileSize)-1, w.CurrentSector()) } } -func numTotalSectors(inputFileSize uint32) uint32 { +func numTotalSectors(fileSize uint32) uint32 { var numDataSectors uint32 - numDataSectors = (inputFileSize + (SectorSize - 1)) / SectorSize + numDataSectors = (fileSize + (SectorSize - 1)) / SectorSize return 1 + rootDirectorySectorNum + numDataSectors }