126 lines
2.3 KiB
Go
126 lines
2.3 KiB
Go
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 = buildInitrdV2(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 = buildInitrdV2(initrd, ctx)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
err = archAdd(prefix+"current_initrd.img", initrd.Bytes())
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
// done
|
|
return nil
|
|
}
|