diff --git a/internal/distro/rhel9/images.go b/internal/distro/rhel9/images.go index 92ef6c854..9d8486273 100644 --- a/internal/distro/rhel9/images.go +++ b/internal/distro/rhel9/images.go @@ -8,6 +8,7 @@ import ( "github.com/osbuild/osbuild-composer/internal/container" "github.com/osbuild/osbuild-composer/internal/distro" "github.com/osbuild/osbuild-composer/internal/fdo" + "github.com/osbuild/osbuild-composer/internal/ignition" "github.com/osbuild/osbuild-composer/internal/image" "github.com/osbuild/osbuild-composer/internal/manifest" "github.com/osbuild/osbuild-composer/internal/osbuild" @@ -411,6 +412,9 @@ func edgeSimplifiedInstallerImage(workload workload.Workload, if bpFDO := customizations.GetFDO(); bpFDO != nil { img.FDO = fdo.FromBP(*bpFDO) } + if bpIgnition := customizations.GetIgnition(); bpIgnition != nil && customizations.Ignition.FirstBoot != nil { + img.Ignition = ignition.FromBP(*bpIgnition.FirstBoot) + } d := t.arch.distro img.ISOLabelTempl = d.isolabelTmpl diff --git a/internal/distro/rhel9/imagetype.go b/internal/distro/rhel9/imagetype.go index ade9ae1a3..3db9e769a 100644 --- a/internal/distro/rhel9/imagetype.go +++ b/internal/distro/rhel9/imagetype.go @@ -332,7 +332,7 @@ func (t *imageType) checkOptions(customizations *blueprint.Customizations, optio } if t.name == "edge-simplified-installer" { - allowed := []string{"InstallationDevice", "FDO"} + allowed := []string{"InstallationDevice", "FDO", "Ignition"} if err := customizations.CheckAllowed(allowed...); err != nil { return fmt.Errorf("unsupported blueprint customizations found for boot ISO image type %q: (allowed: %s)", t.name, strings.Join(allowed, ", ")) } @@ -359,6 +359,22 @@ func (t *imageType) checkOptions(customizations *blueprint.Customizations, optio return fmt.Errorf("boot ISO image type %q requires specifying one of [FDO.DiunPubKeyHash,FDO.DiunPubKeyInsecure,FDO.DiunPubKeyRootCerts] configuration to install to when using FDO", t.name) } } + + // ignition is optional, we might be using FDO + if customizations.Ignition.HasIgnition() { + if customizations.GetIgnition().Embedded != nil && customizations.GetIgnition().FirstBoot != nil { + return fmt.Errorf("both ignition embedded and firstboot configurations found") + } + if customizations.GetIgnition().Embedded != nil { + possibleErr := customizations.GetIgnition().Embedded.CheckEmbeddedIgnition() + if possibleErr != nil { + return possibleErr + } + } + if customizations.GetIgnition().FirstBoot != nil && customizations.GetIgnition().FirstBoot.ProvisioningURL == "" { + return fmt.Errorf("ignition.firstboot requires a provisioning url") + } + } } else if t.name == "edge-installer" { allowed := []string{"User", "Group"} if err := customizations.CheckAllowed(allowed...); err != nil { diff --git a/internal/ignition/ignition.go b/internal/ignition/ignition.go new file mode 100644 index 000000000..da0b9e7f1 --- /dev/null +++ b/internal/ignition/ignition.go @@ -0,0 +1,12 @@ +package ignition + +import "github.com/osbuild/osbuild-composer/internal/blueprint" + +type Options struct { + ProvisioningURL string +} + +func FromBP(bpIgnitionFirstboot blueprint.FirstBootIgnitionCustomization) *Options { + ignition := Options(bpIgnitionFirstboot) + return &ignition +} diff --git a/internal/image/ostree_simplified_installer.go b/internal/image/ostree_simplified_installer.go index d78e959c0..a7bd3e1d0 100644 --- a/internal/image/ostree_simplified_installer.go +++ b/internal/image/ostree_simplified_installer.go @@ -9,6 +9,7 @@ import ( "github.com/osbuild/osbuild-composer/internal/disk" "github.com/osbuild/osbuild-composer/internal/environment" "github.com/osbuild/osbuild-composer/internal/fdo" + "github.com/osbuild/osbuild-composer/internal/ignition" "github.com/osbuild/osbuild-composer/internal/manifest" "github.com/osbuild/osbuild-composer/internal/platform" "github.com/osbuild/osbuild-composer/internal/rpmmd" @@ -50,6 +51,9 @@ type OSTreeSimplifiedInstaller struct { FDO *fdo.Options + // ignition firstboot configuration options + Ignition *ignition.Options + AdditionalDracutModules []string } @@ -118,6 +122,12 @@ func (img *OSTreeSimplifiedInstaller) InstantiateManifest(m *manifest.Manifest, kernelOpts = append(kernelOpts, "fdo.diun_pub_key_root_certs=/fdo_diun_pub_key_root_certs.pem") } } + + // ignition firstboot options + if img.Ignition != nil { + kernelOpts = append(kernelOpts, "coreos.inst.append ignition.config.url="+img.Ignition.ProvisioningURL) + } + bootTreePipeline.KernelOpts = kernelOpts rootfsPartitionTable := &disk.PartitionTable{