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 }