package main import ( "archive/tar" "bytes" "io" "io/ioutil" "log" "os" "novit.tech/direktil/local-server/pkg/utf16" ) func rmTempFile(f *os.File) { f.Close() if err := os.Remove(f.Name()); err != nil { log.Print("failed to remove ", f.Name(), ": ", err) } } func buildBootTar(out io.Writer, ctx *renderContext) (err error) { arch := tar.NewWriter(out) defer arch.Close() archAdd := func(path string, ba []byte) (err error) { err = arch.WriteHeader(&tar.Header{Name: path, Mode: 0640, Size: int64(len(ba))}) if err != nil { return } _, err = arch.Write(ba) return } // kernel kernelPath, err := ctx.distFetch("kernels", ctx.Host.Kernel) if err != nil { return } kernelBytes, err := ioutil.ReadFile(kernelPath) if err != nil { return } err = archAdd("current/vmlinuz", kernelBytes) if err != nil { return } // initrd initrd := new(bytes.Buffer) err = buildInitrd(initrd, ctx) if err != nil { return } err = archAdd("current/initrd", initrd.Bytes()) if err != nil { return } // done return nil } func buildBootEFITar(out io.Writer, ctx *renderContext) (err error) { arch := tar.NewWriter(out) defer arch.Close() archAdd := func(path string, ba []byte) (err error) { err = arch.WriteHeader(&tar.Header{Name: path, Mode: 0640, Size: int64(len(ba))}) if err != nil { return } _, err = arch.Write(ba) return } const ( prefix = "EFI/dkl/" efiPrefix = "\\EFI\\dkl\\" ) // boot.csv // -> annoyingly it's UTF-16... bootCsvBytes := utf16.FromUTF8([]byte("" + "current_kernel.efi,dkl current,initrd=" + efiPrefix + "current_initrd.img,Direktil current\n" + "previous_kernel.efi,dkl previous,initrd=" + efiPrefix + "previous_initrd.img,Direktil previous\n")) err = archAdd(prefix+"BOOT.CSV", []byte(bootCsvBytes)) if err != nil { return } // kernel kernelPath, err := ctx.distFetch("kernels", ctx.Host.Kernel) if err != nil { return } kernelBytes, err := ioutil.ReadFile(kernelPath) if err != nil { return } err = archAdd(prefix+"current_kernel.efi", kernelBytes) if err != nil { return } // initrd initrd := new(bytes.Buffer) err = buildInitrd(initrd, ctx) if err != nil { return } err = archAdd(prefix+"current_initrd.img", initrd.Bytes()) if err != nil { return } // done return nil }