bootv2 support
This commit is contained in:
140
cmd/dkl-local-server/bootv2.go
Normal file
140
cmd/dkl-local-server/bootv2.go
Normal file
@ -0,0 +1,140 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
|
||||
"novit.tech/direktil/pkg/cpiocat"
|
||||
)
|
||||
|
||||
func renderBootstrapConfig(w http.ResponseWriter, r *http.Request, ctx *renderContext, asJson bool) (err error) {
|
||||
log.Printf("sending bootstrap config for %q", ctx.Host.Name)
|
||||
|
||||
_, cfg, err := ctx.BootstrapConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if asJson {
|
||||
err = json.NewEncoder(w).Encode(cfg)
|
||||
} else {
|
||||
err = yaml.NewEncoder(w).Encode(cfg)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildInitrdV2(out io.Writer, ctx *renderContext) (err error) {
|
||||
_, cfg, err := ctx.Config()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
cat := cpiocat.New(out)
|
||||
|
||||
// initrd
|
||||
initrdPath, err := ctx.distFetch("initrd", "2.0.0" /* FIXME */)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
cat.AppendArchFile(initrdPath)
|
||||
|
||||
// embedded layers (modules)
|
||||
for _, layer := range cfg.Layers {
|
||||
switch layer {
|
||||
case "modules":
|
||||
|
||||
layerVersion := ctx.Host.Versions[layer]
|
||||
modulesPath, err := ctx.distFetch("layers", layer, layerVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cat.AppendFile(modulesPath, "modules.sqfs")
|
||||
}
|
||||
}
|
||||
|
||||
// config
|
||||
cfgBytes, _, err := ctx.BootstrapConfig()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
cat.AppendBytes(cfgBytes, "config.yaml", 0600)
|
||||
|
||||
// ssh keys
|
||||
// FIXME we want a bootstrap-stage key instead of the real host key
|
||||
cat.AppendBytes(cfg.FileContent("/etc/ssh/ssh_host_rsa_key"), "id_rsa", 0600)
|
||||
|
||||
return cat.Close()
|
||||
}
|
||||
|
||||
func buildBootstrap(out io.Writer, ctx *renderContext) (err error) {
|
||||
arch := tar.NewWriter(out)
|
||||
defer arch.Close()
|
||||
|
||||
// config
|
||||
cfgBytes, cfg, err := ctx.Config()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = arch.WriteHeader(&tar.Header{Name: "config.yaml", Size: int64(len(cfgBytes))})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = arch.Write(cfgBytes)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// layers
|
||||
for _, layer := range cfg.Layers {
|
||||
if layer == "modules" {
|
||||
continue // modules are with the kernel in boot v2
|
||||
}
|
||||
|
||||
layerVersion := ctx.Host.Versions[layer]
|
||||
if layerVersion == "" {
|
||||
return fmt.Errorf("layer %q not mapped to a version", layer)
|
||||
}
|
||||
|
||||
outPath, err := ctx.distFetch("layers", layer, layerVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := os.Open(outPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
stat, err := f.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = arch.WriteHeader(&tar.Header{
|
||||
Name: layer + ".fs",
|
||||
Size: stat.Size(),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = io.Copy(arch, f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user