Skip to content
This repository was archived by the owner on Aug 25, 2026. It is now read-only.

Commit 322a8f7

Browse files
Test quadlet sugar
1 parent 31886a5 commit 322a8f7

1 file changed

Lines changed: 232 additions & 0 deletions

File tree

base/v0_8_exp/translate_test.go

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2517,3 +2517,235 @@ func TestToIgn3_7(t *testing.T) {
25172517
})
25182518
}
25192519
}
2520+
2521+
func TestTranslateQuadlets(t *testing.T) {
2522+
const (
2523+
SleepContainer = `[Unit]
2524+
Description=A sleepy container
2525+
[Container]
2526+
ContainerName=sleepy-pod-inf
2527+
Image=quay.io/fedora/fedora
2528+
Exec=sleep infinity
2529+
[Install]
2530+
WantedBy=multi-user.target`
2531+
2532+
SleepContainerAsData = "data:,%5BUnit%5D%0ADescription%3DA%20sleepy%20container%0A%5BContainer%5D%0AContainerName%3Dsleepy-pod-inf%0AImage%3Dquay.io%2Ffedora%2Ffedora%0AExec%3Dsleep%20infinity%0A%5BInstall%5D%0AWantedBy%3Dmulti-user.target"
2533+
2534+
SleepContainerTemplate = `[Unit]
2535+
Description=A templated sleepy container
2536+
[Container]
2537+
Image=quay.io/fedora/fedora
2538+
Exec=sleep %i
2539+
[Service]
2540+
# Restart service when sleep finishes
2541+
Restart=always
2542+
[Install]
2543+
WantedBy=multi-user.target`
2544+
2545+
SleepContainerTemplateAsData = "data:;base64,H4sIAAAAAAAC/zSNvU4DMRCE+32KlRAl4Qlc8FekBSGKk4uVb5Ks5Fsf3j2C3x6JJNWMRvPpmz5NI9MrvHRdQ5ulJw4sa5XAzF6BdXBpFqKGTtPLrWbaL3JE+t5k7LQ9HjC3Ltegt1+U9E/zvdL0gf6jBZnu+B0e0oP9MvH5BLt4+KCmfoLT9ZOknmU4TXvzkFozfYkF5ueRlq2GPmyOvgvpR8RfAAAA//91kIIEyQAAAA=="
2546+
)
2547+
2548+
filesDir := t.TempDir()
2549+
fileContents := map[string]string{
2550+
"sample.container": SleepContainer,
2551+
"sample@.container": SleepContainerTemplate,
2552+
}
2553+
for name, contents := range fileContents {
2554+
if err := os.MkdirAll(filepath.Join(filesDir, filepath.Dir(name)), 0755); err != nil {
2555+
t.Error(err)
2556+
return
2557+
}
2558+
err := os.WriteFile(filepath.Join(filesDir, name), []byte(contents), 0644)
2559+
if err != nil {
2560+
t.Error(err)
2561+
return
2562+
}
2563+
}
2564+
2565+
tests := []struct {
2566+
name string
2567+
inputConfig Config
2568+
outConf types.Config
2569+
reportPath string
2570+
options common.TranslateOptions
2571+
}{
2572+
{
2573+
name: "Basic .container quadlets",
2574+
inputConfig: Config{
2575+
Systemd: Systemd{
2576+
Quadlets: []Quadlet{
2577+
{
2578+
Name: "sleepy.container",
2579+
Contents: util.StrToPtr(SleepContainer),
2580+
Rootful: true,
2581+
},
2582+
{
2583+
Name: "sleepy.container",
2584+
Contents: util.StrToPtr(SleepContainer),
2585+
Rootful: false,
2586+
},
2587+
},
2588+
},
2589+
},
2590+
outConf: types.Config{
2591+
Ignition: types.Ignition{
2592+
Version: "3.7.0-experimental",
2593+
},
2594+
Storage: types.Storage{
2595+
Files: []types.File{
2596+
{
2597+
Node: types.Node{
2598+
Path: "/etc/containers/systemd/sleepy.container",
2599+
},
2600+
FileEmbedded1: types.FileEmbedded1{
2601+
Contents: types.Resource{
2602+
Source: util.StrToPtr(SleepContainerAsData),
2603+
Compression: util.StrToPtr(""),
2604+
},
2605+
},
2606+
},
2607+
{
2608+
Node: types.Node{
2609+
Path: "/etc/containers/systemd/users/sleepy.container",
2610+
},
2611+
FileEmbedded1: types.FileEmbedded1{
2612+
Contents: types.Resource{
2613+
Source: util.StrToPtr(SleepContainerAsData),
2614+
Compression: util.StrToPtr(""),
2615+
},
2616+
},
2617+
},
2618+
},
2619+
},
2620+
},
2621+
},
2622+
{
2623+
name: "Template instance is symlink",
2624+
inputConfig: Config{
2625+
Systemd: Systemd{
2626+
Quadlets: []Quadlet{
2627+
{
2628+
Name: "sleepy@.container",
2629+
Contents: util.StrToPtr(SleepContainerTemplate),
2630+
Rootful: true,
2631+
},
2632+
{
2633+
Name: "sleepy@100.container",
2634+
Rootful: true,
2635+
},
2636+
},
2637+
},
2638+
},
2639+
outConf: types.Config{
2640+
Ignition: types.Ignition{
2641+
Version: "3.7.0-experimental",
2642+
},
2643+
Storage: types.Storage{
2644+
Files: []types.File{
2645+
{
2646+
Node: types.Node{
2647+
Path: "/etc/containers/systemd/sleepy@.container",
2648+
},
2649+
FileEmbedded1: types.FileEmbedded1{
2650+
Contents: types.Resource{
2651+
Source: util.StrToPtr(SleepContainerTemplateAsData),
2652+
Compression: util.StrToPtr("gzip"),
2653+
},
2654+
},
2655+
},
2656+
},
2657+
Links: []types.Link{
2658+
{
2659+
Node: types.Node{
2660+
Path: "/etc/containers/systemd/sleepy@100.container",
2661+
},
2662+
LinkEmbedded1: types.LinkEmbedded1{
2663+
Target: util.StrToPtr("sleepy@.container"),
2664+
},
2665+
},
2666+
},
2667+
},
2668+
},
2669+
},
2670+
{
2671+
name: "Quadlet with non-existent contents_local",
2672+
inputConfig: Config{
2673+
Systemd: Systemd{
2674+
Quadlets: []Quadlet{
2675+
{
2676+
Name: "sleepy.container",
2677+
ContentsLocal: util.StrToPtr("fake/path"),
2678+
Rootful: true,
2679+
},
2680+
},
2681+
},
2682+
},
2683+
options: common.TranslateOptions{FilesDir: filesDir},
2684+
reportPath: "error at $.systemd.quadlets.0.contents_local: open " + filesDir + "/fake/path: no such file or directory\n",
2685+
},
2686+
{
2687+
name: "Quadlet with contents_local",
2688+
inputConfig: Config{
2689+
Systemd: Systemd{
2690+
Quadlets: []Quadlet{
2691+
{
2692+
Name: "sleepy.container",
2693+
ContentsLocal: util.StrToPtr("sample.container"),
2694+
Rootful: true,
2695+
},
2696+
},
2697+
},
2698+
},
2699+
outConf: types.Config{
2700+
Ignition: types.Ignition{
2701+
Version: "3.7.0-experimental",
2702+
},
2703+
Storage: types.Storage{
2704+
Files: []types.File{
2705+
{
2706+
Node: types.Node{
2707+
Path: "/etc/containers/systemd/sleepy.container",
2708+
},
2709+
FileEmbedded1: types.FileEmbedded1{
2710+
Contents: types.Resource{
2711+
Source: util.StrToPtr(SleepContainerAsData),
2712+
Compression: util.StrToPtr(""),
2713+
},
2714+
},
2715+
},
2716+
},
2717+
},
2718+
},
2719+
options: common.TranslateOptions{FilesDir: filesDir},
2720+
},
2721+
{
2722+
name: "Overrides break",
2723+
inputConfig: Config{
2724+
Systemd: Systemd{
2725+
Quadlets: []Quadlet{
2726+
// two quadlets with the same name should give an error
2727+
{
2728+
Name: "sleepy.container",
2729+
Contents: util.StrToPtr(SleepContainer),
2730+
Rootful: true,
2731+
},
2732+
{
2733+
Name: "sleepy.container",
2734+
Contents: util.StrToPtr(SleepContainerTemplate),
2735+
Rootful: true,
2736+
},
2737+
},
2738+
},
2739+
},
2740+
outConf: types.Config{},
2741+
reportPath: "error at $.systemd.quadlets.1: matching filesystem node has existing contents or different type\n",
2742+
},
2743+
}
2744+
for _, test := range tests {
2745+
t.Run(test.name, func(t *testing.T) {
2746+
c, _, r := test.inputConfig.ToIgn3_7Unvalidated(test.options)
2747+
assert.Equal(t, test.outConf, c, test.name+"translation mismatch")
2748+
assert.Equal(t, test.reportPath, r.String(), test.name+"report mismatch")
2749+
})
2750+
}
2751+
}

0 commit comments

Comments
 (0)