package main import ( "fmt" "io" "io/ioutil" "log" "os" "os/exec" "path/filepath" "strconv" "github.com/cespare/xxhash" ) func buildBootISO(out io.Writer, ctx *renderContext) (err error) { tempDir, err := ioutil.TempDir("/tmp", "iso-v2-") if err != nil { return } defer os.RemoveAll(tempDir) buildRes := func(build func(out io.Writer, ctx *renderContext) error, dst string) (err error) { log.Printf("iso-v2: building %s", dst) outPath := filepath.Join(tempDir, dst) if err = os.MkdirAll(filepath.Dir(outPath), 0755); err != nil { return err } out, err := os.Create(outPath) if err != nil { return err } defer out.Close() err = build(out, ctx) if err != nil { return } return err } err = func() (err error) { // grub if err = os.MkdirAll(filepath.Join(tempDir, "grub"), 0755); err != nil { return } // create a tag file bootstrapBytes, _, err := ctx.BootstrapConfig() if err != nil { return } h := xxhash.New() fmt.Fprintln(h, ctx.Host.Kernel) h.Write(bootstrapBytes) tag := "dkl-" + strconv.FormatUint(h.Sum64(), 32) + ".tag" f, err := os.Create(filepath.Join(tempDir, tag)) if err != nil { return } f.Write([]byte("direktil marker file\n")) f.Close() err = ioutil.WriteFile(filepath.Join(tempDir, "grub", "grub.cfg"), []byte(` search --set=root --file /`+tag+` insmod all_video set timeout=3 menuentry "Direktil" { linux /vmlinuz `+ctx.CmdLine+` initrd /initrd } `), 0644) if err != nil { return } coreImgPath := filepath.Join(tempDir, "grub", "core.img") grubCfgPath := filepath.Join(tempDir, "grub", "grub.cfg") cmd := exec.Command("grub-mkstandalone", "--format=i386-pc", "--output="+coreImgPath, "--install-modules=linux normal iso9660 biosdisk memdisk search tar ls", "--modules=linux normal iso9660 biosdisk search", "--locales=", "--fonts=", "boot/grub/grub.cfg="+grubCfgPath, ) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { return err } defer os.Remove(coreImgPath) defer os.Remove(grubCfgPath) out, err := os.Create(filepath.Join(tempDir, "grub", "bios.img")) if err != nil { return err } defer out.Close() b, err := ioutil.ReadFile("/usr/lib/grub/i386-pc/cdboot.img") if err != nil { return err } if _, err := out.Write(b); err != nil { return err } b, err = ioutil.ReadFile(coreImgPath) if err != nil { return err } if _, err := out.Write(b); err != nil { return err } return nil }() if err != nil { return err } // kernel and initrd buildRes(fetchKernel, "vmlinuz") buildRes(buildInitrd, "initrd") // build the ISO mkisofs, err := exec.LookPath("genisoimage") if err != nil { mkisofs, err = exec.LookPath("mkisofs") } if err != nil { return err } cmd := exec.Command(mkisofs, "-quiet", "-joliet", "-joliet-long", "-rock", "-translation-table", "-no-emul-boot", "-boot-load-size", "4", "-boot-info-table", "-eltorito-boot", "grub/bios.img", "-eltorito-catalog", "grub/boot.cat", tempDir, ) cmd.Stdout = out cmd.Stderr = os.Stderr return cmd.Run() }