diff --git a/internal/distro/rhel9/images.go b/internal/distro/rhel9/images.go index 9d8486273..293a62ab9 100644 --- a/internal/distro/rhel9/images.go +++ b/internal/distro/rhel9/images.go @@ -412,8 +412,14 @@ 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) + // ignition configs from blueprint + if bpIgnition := customizations.GetIgnition(); bpIgnition != nil { + if bpIgnition.FirstBoot != nil { + img.IgnitionFirstBoot = ignition.FirstbootOptionsFromBP(*bpIgnition.FirstBoot) + } + if bpIgnition.Embedded != nil { + img.IgnitionEmbedded = ignition.EmbeddedOptionsFromBP(*bpIgnition.Embedded) + } } d := t.arch.distro diff --git a/internal/ignition/ignition.go b/internal/ignition/ignition.go index da0b9e7f1..cca1afe0a 100644 --- a/internal/ignition/ignition.go +++ b/internal/ignition/ignition.go @@ -2,11 +2,21 @@ package ignition import "github.com/osbuild/osbuild-composer/internal/blueprint" -type Options struct { +type FirstBootOptions struct { ProvisioningURL string } -func FromBP(bpIgnitionFirstboot blueprint.FirstBootIgnitionCustomization) *Options { - ignition := Options(bpIgnitionFirstboot) +func FirstbootOptionsFromBP(bpIgnitionFirstboot blueprint.FirstBootIgnitionCustomization) *FirstBootOptions { + ignition := FirstBootOptions(bpIgnitionFirstboot) + return &ignition +} + +type EmbeddedOptions struct { + ProvisioningURL string + Data64 string +} + +func EmbeddedOptionsFromBP(bpIgnitionEmbedded blueprint.EmbeddedIgnitionCustomization) *EmbeddedOptions { + ignition := EmbeddedOptions(bpIgnitionEmbedded) return &ignition } diff --git a/internal/image/ostree_simplified_installer.go b/internal/image/ostree_simplified_installer.go index a7bd3e1d0..15ca7ea6d 100644 --- a/internal/image/ostree_simplified_installer.go +++ b/internal/image/ostree_simplified_installer.go @@ -51,8 +51,11 @@ type OSTreeSimplifiedInstaller struct { FDO *fdo.Options - // ignition firstboot configuration options - Ignition *ignition.Options + // Ignition firstboot configuration options + IgnitionFirstBoot *ignition.FirstBootOptions + + // Ignition embedded configuration options + IgnitionEmbedded *ignition.EmbeddedOptions AdditionalDracutModules []string } @@ -88,6 +91,7 @@ func (img *OSTreeSimplifiedInstaller) InstantiateManifest(m *manifest.Manifest, coiPipeline.ExtraPackages = img.ExtraBasePackages.Include coiPipeline.ExtraRepos = img.ExtraBasePackages.Repositories coiPipeline.FDO = img.FDO + coiPipeline.Ignition = img.IgnitionEmbedded coiPipeline.Biosdevname = (img.Platform.GetArch() == platform.ARCH_X86_64) coiPipeline.Variant = img.Variant coiPipeline.AdditionalDracutModules = img.AdditionalDracutModules @@ -124,8 +128,8 @@ func (img *OSTreeSimplifiedInstaller) InstantiateManifest(m *manifest.Manifest, } // ignition firstboot options - if img.Ignition != nil { - kernelOpts = append(kernelOpts, "coreos.inst.append ignition.config.url="+img.Ignition.ProvisioningURL) + if img.IgnitionFirstBoot != nil { + kernelOpts = append(kernelOpts, "coreos.inst.append ignition.config.url="+img.IgnitionFirstBoot.ProvisioningURL) } bootTreePipeline.KernelOpts = kernelOpts diff --git a/internal/manifest/coi_iso_tree.go b/internal/manifest/coi_iso_tree.go index 699d3cfb0..028e61337 100644 --- a/internal/manifest/coi_iso_tree.go +++ b/internal/manifest/coi_iso_tree.go @@ -1,6 +1,7 @@ package manifest import ( + "crypto/sha256" "fmt" "github.com/osbuild/osbuild-composer/internal/disk" @@ -66,6 +67,30 @@ func (p *CoreOSISOTree) serialize() osbuild.Pipeline { osbuild.NewFilesInputs(osbuild.NewFilesInputReferencesPipeline(p.payloadPipeline.Name(), p.payloadPipeline.Filename)), )) + if p.coiPipeline.Ignition != nil { + filename := "" + copyInput := "" + // These specific filenames in the root of the ISO are expected by + // coreos-installer-dracut during installation + if p.coiPipeline.Ignition.Data64 != "" { + filename = "ignition_config" + copyInput = p.coiPipeline.Ignition.Data64 + } else { + filename = "ignition_url" + copyInput = p.coiPipeline.Ignition.ProvisioningURL + } + pipeline.AddStage(osbuild.NewCopyStageSimple( + &osbuild.CopyStageOptions{ + Paths: []osbuild.CopyStagePath{ + { + From: fmt.Sprintf("input://inlinefile/sha256:%x", sha256.Sum256([]byte(copyInput))), + To: fmt.Sprintf("tree:///%s", filename), + }, + }, + }, + osbuild.NewIgnitionInlineInput(copyInput))) + } + pipeline.AddStage(osbuild.NewMkdirStage(&osbuild.MkdirStageOptions{ Paths: []osbuild.Path{ { diff --git a/internal/manifest/coreos_installer.go b/internal/manifest/coreos_installer.go index fed41d993..973958990 100644 --- a/internal/manifest/coreos_installer.go +++ b/internal/manifest/coreos_installer.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/osbuild/osbuild-composer/internal/fdo" + "github.com/osbuild/osbuild-composer/internal/ignition" "github.com/osbuild/osbuild-composer/internal/osbuild" "github.com/osbuild/osbuild-composer/internal/platform" "github.com/osbuild/osbuild-composer/internal/rpmmd" @@ -35,6 +36,9 @@ type CoreOSInstaller struct { FDO *fdo.Options + // For the coreos-installer we only have EmbeddedOptions for ignition + Ignition *ignition.EmbeddedOptions + AdditionalDracutModules []string } @@ -127,11 +131,20 @@ func (p *CoreOSInstaller) serializeStart(packages []rpmmd.PackageSpec) { } func (p *CoreOSInstaller) getInline() []string { + inlineData := []string{} // inline data for FDO cert if p.FDO != nil && p.FDO.DiunPubKeyRootCerts != "" { - return []string{p.FDO.DiunPubKeyRootCerts} + inlineData = append(inlineData, p.FDO.DiunPubKeyRootCerts) } - return []string{} + // inline data for ignition embedded (url or data) + if p.Ignition != nil { + if p.Ignition.Data64 != "" { + inlineData = append(inlineData, p.Ignition.Data64) + } else { + inlineData = append(inlineData, p.Ignition.ProvisioningURL) + } + } + return inlineData } func (p *CoreOSInstaller) serializeEnd() { diff --git a/internal/osbuild/ignition_stage.go b/internal/osbuild/ignition_stage.go new file mode 100644 index 000000000..ae07747f9 --- /dev/null +++ b/internal/osbuild/ignition_stage.go @@ -0,0 +1,29 @@ +package osbuild + +import ( + "crypto/sha256" + "fmt" +) + +type IgnitionStageInputInline struct { + InlineFile IgnitionStageInput `json:"inlinefile"` +} + +func (IgnitionStageInputInline) isStageInputs() {} + +type IgnitionStageInput struct { + inputCommon + References IgnitionStageReferences `json:"references"` +} + +type IgnitionStageReferences []string + +func (IgnitionStageReferences) isReferences() {} + +func NewIgnitionInlineInput(embeddedData string) Inputs { + inputs := new(IgnitionStageInputInline) + inputs.InlineFile.Type = "org.osbuild.files" + inputs.InlineFile.Origin = "org.osbuild.source" + inputs.InlineFile.References = IgnitionStageReferences{fmt.Sprintf("sha256:%x", sha256.Sum256([]byte(embeddedData)))} + return inputs +}