diff --git a/Dockerfile b/Dockerfile index ad7ae76..1ca4b29 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,8 @@ # ------------------------------------------------------------------------ -from mcluseau/golang-builder:1.13.4 as build +from mcluseau/golang-builder:1.14.0 as build # ------------------------------------------------------------------------ -from alpine:3.10.3 +from alpine:3.11.3 env busybox_v=1.28.1-defconfig-multiarch \ arch=x86_64 diff --git a/main.go b/main.go index a9d67f5..bd24f6b 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "io" "io/ioutil" "log" "os" @@ -45,6 +46,7 @@ func main() { // find and mount /boot bootMatch := param("boot", "") + bootMounted := false if bootMatch != "" { bootFS := param("boot.fs", "vfat") for i := 0; ; i++ { @@ -64,6 +66,7 @@ func main() { log.Print("boot partition found: ", devFile) mount(devFile, "/boot", bootFS, bootMountFlags, "") + bootMounted = true break } } else { @@ -90,6 +93,14 @@ func main() { log.Printf("wanted layers: %q", cfg.Layers) + layersInMemory := paramBool("layers-in-mem", false) + + const layersInMemDir = "/layers-in-mem" + if layersInMemory { + mkdir(layersInMemDir, 0700) + mount("layers-mem", layersInMemDir, "tmpfs", 0, "") + } + lowers := make([]string, len(cfg.Layers)) for i, layer := range cfg.Layers { path := layerPath(layer) @@ -101,6 +112,13 @@ func main() { log.Printf("layer %s found (%d bytes)", layer, info.Size()) + if layersInMemory { + log.Print(" copying to memory...") + targetPath := filepath.Join(layersInMemDir, layer) + cp(path, targetPath) + path = targetPath + } + dir := "/layers/" + layer lowers[i] = dir @@ -119,7 +137,14 @@ func main() { mount("overlay", "/system", "overlay", rootMountFlags, "lowerdir="+strings.Join(lowers, ":")+",upperdir=/changes/upperdir,workdir=/changes/workdir") - mount("/boot", "/system/boot", "", syscall.MS_BIND, "") + + // mount("/boot", "/system/boot", "", syscall.MS_BIND, "") + if layersInMemory && bootMounted { + if err := syscall.Unmount("/boot", 0); err != nil { + log.Print("WARNING: failed to unmount /boot: ", err) + time.Sleep(2 * time.Second) + } + } // - write configuration log.Print("writing /config.yaml") @@ -188,3 +213,28 @@ func mount(source, target, fstype string, flags uintptr, data string) { } log.Printf("mounted %q", target) } + +func cp(srcPath, dstPath string) { + var err error + defer func() { + if err != nil { + fatalf("cp %s %s failed: %v", srcPath, dstPath, err) + } + }() + + src, err := os.Open(srcPath) + if err != nil { + return + } + + defer src.Close() + + dst, err := os.Create(dstPath) + if err != nil { + return + } + + defer dst.Close() + + _, err = io.Copy(dst, src) +} diff --git a/modd.conf b/modd.conf new file mode 100644 index 0000000..5746255 --- /dev/null +++ b/modd.conf @@ -0,0 +1,6 @@ +go.??? *.go { + prep: go test ./... + prep: dockb -t dkl-initrd . + prep: docker run dkl-initrd | docker exec -i dls sh -c "base64 -d >/var/lib/direktil/dist/initrd/1.0.7 && rm -rfv /var/lib/direktil/cache/*" + prep: curl -H'Autorization: Bearer adm1n' localhost:7606/hosts/m1/boot.iso >/tmp/m1-boot.iso +} diff --git a/params.go b/params.go index d46287c..e4728f2 100644 --- a/params.go +++ b/params.go @@ -11,13 +11,29 @@ func param(name, defaultValue string) (value string) { fatal("could not read /proc/cmdline: ", err) } - prefix := "direktil." + name + "=" + prefixes := []string{ + "direktil." + name + "=", + "dkl." + name + "=", + } + + value = defaultValue for _, part := range strings.Split(string(ba), " ") { - if strings.HasPrefix(part, prefix) { - return strings.TrimSpace(part[len(prefix):]) + for _, prefix := range prefixes { + if strings.HasPrefix(part, prefix) { + value = strings.TrimSpace(part[len(prefix):]) + } } } - return defaultValue + return +} + +func paramBool(name string, defaultValue bool) (value bool) { + defaultValueS := "false" + if defaultValue { + defaultValueS = "true" + } + + return "true" == param(name, defaultValueS) }