@@ -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