package config import ( "encoding/json" "os" "path/filepath" "testing" "banger/internal/paths" "banger/internal/runtimebundle" ) func TestLoadDerivesArtifactPathsFromRuntimeDir(t *testing.T) { runtimeDir := t.TempDir() meta := runtimebundle.BundleMetadata{ FirecrackerBin: "bin/firecracker", SSHKeyPath: "keys/id_ed25519", NamegenPath: "bin/namegen", CustomizeScript: "scripts/customize.sh", DefaultPackages: "config/packages.apt", DefaultRootfs: "images/rootfs-docker.ext4", DefaultKernel: "kernels/vmlinux", DefaultInitrd: "kernels/initrd.img", DefaultModulesDir: "modules/current", } for _, rel := range []string{ meta.FirecrackerBin, meta.SSHKeyPath, meta.NamegenPath, meta.CustomizeScript, meta.DefaultPackages, meta.DefaultRootfs, meta.DefaultKernel, meta.DefaultInitrd, filepath.Join(meta.DefaultModulesDir, "modules.dep"), } { path := filepath.Join(runtimeDir, rel) if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { t.Fatalf("mkdir %s: %v", filepath.Dir(path), err) } if err := os.WriteFile(path, []byte("test"), 0o644); err != nil { t.Fatalf("write %s: %v", path, err) } } data, err := json.Marshal(meta) if err != nil { t.Fatalf("Marshal: %v", err) } if err := os.WriteFile(filepath.Join(runtimeDir, runtimebundle.BundleMetadataFile), data, 0o644); err != nil { t.Fatalf("write bundle metadata: %v", err) } t.Setenv("BANGER_RUNTIME_DIR", runtimeDir) cfg, err := Load(paths.Layout{ConfigDir: t.TempDir()}) if err != nil { t.Fatalf("Load: %v", err) } if cfg.RuntimeDir != runtimeDir { t.Fatalf("RuntimeDir = %q, want %q", cfg.RuntimeDir, runtimeDir) } if cfg.FirecrackerBin != filepath.Join(runtimeDir, meta.FirecrackerBin) { t.Fatalf("FirecrackerBin = %q", cfg.FirecrackerBin) } if cfg.SSHKeyPath != filepath.Join(runtimeDir, meta.SSHKeyPath) { t.Fatalf("SSHKeyPath = %q", cfg.SSHKeyPath) } if cfg.NamegenPath != filepath.Join(runtimeDir, meta.NamegenPath) { t.Fatalf("NamegenPath = %q", cfg.NamegenPath) } if cfg.CustomizeScript != filepath.Join(runtimeDir, meta.CustomizeScript) { t.Fatalf("CustomizeScript = %q", cfg.CustomizeScript) } if cfg.DefaultRootfs != filepath.Join(runtimeDir, meta.DefaultRootfs) { t.Fatalf("DefaultRootfs = %q", cfg.DefaultRootfs) } if cfg.DefaultBaseRootfs != filepath.Join(runtimeDir, meta.DefaultRootfs) { t.Fatalf("DefaultBaseRootfs = %q", cfg.DefaultBaseRootfs) } if cfg.DefaultKernel != filepath.Join(runtimeDir, meta.DefaultKernel) { t.Fatalf("DefaultKernel = %q", cfg.DefaultKernel) } if cfg.DefaultInitrd != filepath.Join(runtimeDir, meta.DefaultInitrd) { t.Fatalf("DefaultInitrd = %q", cfg.DefaultInitrd) } if cfg.DefaultModulesDir != filepath.Join(runtimeDir, meta.DefaultModulesDir) { t.Fatalf("DefaultModulesDir = %q", cfg.DefaultModulesDir) } if cfg.DefaultPackagesFile != filepath.Join(runtimeDir, meta.DefaultPackages) { t.Fatalf("DefaultPackagesFile = %q", cfg.DefaultPackagesFile) } } func TestLoadFallsBackToLegacyRuntimeLayoutWithoutBundleMetadata(t *testing.T) { runtimeDir := t.TempDir() for _, rel := range []string{ "firecracker", "id_ed25519", "namegen", "customize.sh", "packages.apt", "rootfs-docker.ext4", "wtf/root/boot/vmlinux-6.8.0-94-generic", "wtf/root/boot/initrd.img-6.8.0-94-generic", "wtf/root/lib/modules/6.8.0-94-generic/modules.dep", } { path := filepath.Join(runtimeDir, rel) if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { t.Fatalf("mkdir %s: %v", filepath.Dir(path), err) } if err := os.WriteFile(path, []byte("test"), 0o644); err != nil { t.Fatalf("write %s: %v", path, err) } } t.Setenv("BANGER_RUNTIME_DIR", runtimeDir) cfg, err := Load(paths.Layout{ConfigDir: t.TempDir()}) if err != nil { t.Fatalf("Load: %v", err) } if cfg.FirecrackerBin != filepath.Join(runtimeDir, "firecracker") { t.Fatalf("FirecrackerBin = %q", cfg.FirecrackerBin) } if cfg.DefaultKernel != filepath.Join(runtimeDir, "wtf/root/boot/vmlinux-6.8.0-94-generic") { t.Fatalf("DefaultKernel = %q", cfg.DefaultKernel) } } func TestLoadAppliesMapDNSEnvOverrides(t *testing.T) { t.Setenv("BANGER_MAPDNS_BIN", "/opt/bin/mapdns") t.Setenv("BANGER_MAPDNS_DATA_FILE", "/tmp/mapdns-records.json") cfg, err := Load(paths.Layout{ConfigDir: t.TempDir()}) if err != nil { t.Fatalf("Load: %v", err) } if cfg.MapDNSBin != "/opt/bin/mapdns" { t.Fatalf("MapDNSBin = %q", cfg.MapDNSBin) } if cfg.MapDNSDataFile != "/tmp/mapdns-records.json" { t.Fatalf("MapDNSDataFile = %q", cfg.MapDNSDataFile) } }