@@ -17,12 +17,15 @@ import (
1717 bibcontainer "github.com/osbuild/images/pkg/bib/container"
1818 "github.com/osbuild/images/pkg/bib/osinfo"
1919 "github.com/osbuild/images/pkg/container"
20+ "github.com/osbuild/images/pkg/customizations/anaconda"
21+ "github.com/osbuild/images/pkg/customizations/kickstart"
2022 "github.com/osbuild/images/pkg/customizations/users"
2123 "github.com/osbuild/images/pkg/disk"
2224 "github.com/osbuild/images/pkg/distro"
2325 "github.com/osbuild/images/pkg/distro/defs"
2426 "github.com/osbuild/images/pkg/image"
2527 "github.com/osbuild/images/pkg/manifest"
28+ "github.com/osbuild/images/pkg/osbuild"
2629 "github.com/osbuild/images/pkg/platform"
2730 "github.com/osbuild/images/pkg/policies"
2831 "github.com/osbuild/images/pkg/rpmmd"
@@ -272,6 +275,17 @@ func (t *BootcImageType) Exports() []string {
272275}
273276
274277func (t * BootcImageType ) SupportedBlueprintOptions () []string {
278+ if t .BootISO {
279+ // XXX: this is probably too minimal but lets start small
280+ // and expand
281+ return []string {
282+ "customizations.fips" ,
283+ "customizations.group" ,
284+ "customizations.installer" ,
285+ "customizations.kernel.append" ,
286+ "customizations.user" ,
287+ }
288+ }
275289 return []string {
276290 "customizations.directories" ,
277291 "customizations.disk" ,
@@ -287,6 +301,13 @@ func (t *BootcImageType) RequiredBlueprintOptions() []string {
287301}
288302
289303func (t * BootcImageType ) Manifest (bp * blueprint.Blueprint , options distro.ImageOptions , repos []rpmmd.RepoConfig , seedp * int64 ) (* manifest.Manifest , []string , error ) {
304+ if t .BootISO {
305+ return t .manifestForISO (bp , options , repos , seedp )
306+ }
307+ return t .manifestForDisk (bp , options , repos , seedp )
308+ }
309+
310+ func (t * BootcImageType ) manifestForDisk (bp * blueprint.Blueprint , options distro.ImageOptions , repos []rpmmd.RepoConfig , seedp * int64 ) (* manifest.Manifest , []string , error ) {
290311 if t .arch .distro .imgref == "" {
291312 return nil , nil , fmt .Errorf ("internal error: no base image defined" )
292313 }
@@ -330,7 +351,9 @@ func (t *BootcImageType) Manifest(bp *blueprint.Blueprint, options distro.ImageO
330351 }
331352
332353 imageConfig := t .ImageTypeYAML .ImageConfig (t .arch .distro .id , t .arch .Name ())
333- img .OSCustomizations .KernelOptionsAppend = imageConfig .KernelOptions
354+ if imageConfig != nil {
355+ img .OSCustomizations .KernelOptionsAppend = imageConfig .KernelOptions
356+ }
334357 if kopts := customizations .GetKernel (); kopts != nil && kopts .Append != "" {
335358 img .OSCustomizations .KernelOptionsAppend = append (img .OSCustomizations .KernelOptionsAppend , kopts .Append )
336359 }
@@ -375,6 +398,131 @@ func (t *BootcImageType) Manifest(bp *blueprint.Blueprint, options distro.ImageO
375398 return & mf , nil , nil
376399}
377400
401+ func (t * BootcImageType ) manifestForISO (bp * blueprint.Blueprint , options distro.ImageOptions , repos []rpmmd.RepoConfig , seedp * int64 ) (* manifest.Manifest , []string , error ) {
402+ if t .arch .distro .imgref == "" {
403+ return nil , nil , fmt .Errorf ("internal error: no base image defined" )
404+ }
405+ if options .Bootc == nil || options .Bootc .InstallerPayloadRef == "" {
406+ return nil , nil , fmt .Errorf ("no installer payload bootc ref set" )
407+ }
408+ payloadRef := options .Bootc .InstallerPayloadRef
409+
410+ containerSource := container.SourceSpec {
411+ Source : t .arch .distro .imgref ,
412+ Name : t .arch .distro .imgref ,
413+ Local : true ,
414+ }
415+ // XXX: keep it simple for now, we may allow this in the future
416+ if t .arch .distro .buildImgref != t .arch .distro .imgref {
417+ return nil , nil , fmt .Errorf ("cannot use build-containers with anaconda installer images" )
418+ }
419+
420+ var customizations * blueprint.Customizations
421+ if bp != nil {
422+ customizations = bp .Customizations
423+ }
424+ seed , err := cmdutil .SeedArgFor (nil , t .Name (), t .arch .Name (), t .arch .distro .Name ())
425+ if err != nil {
426+ return nil , nil , err
427+ }
428+ //nolint:gosec
429+ rng := rand .New (rand .NewSource (seed ))
430+
431+ platformi := PlatformFor (t .arch .Name (), t .arch .distro .sourceInfo .UEFIVendor )
432+ platformi .ImageFormat = platform .FORMAT_ISO
433+
434+ // XXX: tons of copied code from
435+ // bootc-image-builder:bib/cmd/bootc-image-builder/legacy_iso.go
436+ // but sharing is hard because AnacondaContainerInstaller and
437+ // AnacondaContainerInstallerLegacy are different types so
438+ // a shared helper to set the fields won't work (unless
439+ // reflection urgh).
440+
441+ // The ref is not needed and will be removed from the ctor later
442+ // in time
443+ img := image .NewAnacondaContainerInstaller (platformi , t .Filename (), containerSource , "" )
444+ img .ContainerRemoveSignatures = true
445+ img .RootfsCompression = "zstd"
446+ // kernelVer is used by dracut
447+ img .KernelVer = t .arch .distro .sourceInfo .KernelInfo .Version
448+ img .KernelPath = fmt .Sprintf ("lib/modules/%s/vmlinuz" , t .arch .distro .sourceInfo .KernelInfo .Version )
449+ img .InitramfsPath = fmt .Sprintf ("lib/modules/%s/initramfs.img" , t .arch .distro .sourceInfo .KernelInfo .Version )
450+ img .InstallerHome = "/var/roothome"
451+ payloadSource := container.SourceSpec {
452+ Source : payloadRef ,
453+ Name : payloadRef ,
454+ Local : true ,
455+ }
456+ img .InstallerPayload = payloadSource
457+
458+ if t .arch .Name () == arch .ARCH_X86_64 .String () {
459+ img .InstallerCustomizations .ISOBoot = manifest .Grub2ISOBoot
460+ }
461+
462+ img .InstallerCustomizations .Product = t .arch .distro .sourceInfo .OSRelease .Name
463+ img .InstallerCustomizations .OSVersion = t .arch .distro .sourceInfo .OSRelease .VersionID
464+ img .InstallerCustomizations .ISOLabel = LabelForISO (& t .arch .distro .sourceInfo .OSRelease , t .arch .Name ())
465+
466+ img .InstallerCustomizations .FIPS = customizations .GetFIPS ()
467+ img .Kickstart , err = kickstart .New (customizations )
468+ if err != nil {
469+ return nil , nil , err
470+ }
471+ img .Kickstart .Path = osbuild .KickstartPathOSBuild
472+ if kopts := customizations .GetKernel (); kopts != nil && kopts .Append != "" {
473+ img .Kickstart .KernelOptionsAppend = append (img .Kickstart .KernelOptionsAppend , kopts .Append )
474+ }
475+ img .Kickstart .NetworkOnBoot = true
476+
477+ instCust , err := customizations .GetInstaller ()
478+ if err != nil {
479+ return nil , nil , err
480+ }
481+ if instCust != nil && instCust .Modules != nil {
482+ img .InstallerCustomizations .EnabledAnacondaModules = append (img .InstallerCustomizations .EnabledAnacondaModules , instCust .Modules .Enable ... )
483+ img .InstallerCustomizations .DisabledAnacondaModules = append (img .InstallerCustomizations .DisabledAnacondaModules , instCust .Modules .Disable ... )
484+ }
485+ img .InstallerCustomizations .EnabledAnacondaModules = append (img .InstallerCustomizations .EnabledAnacondaModules ,
486+ anaconda .ModuleUsers ,
487+ anaconda .ModuleServices ,
488+ anaconda .ModuleSecurity ,
489+ // XXX: get from the imagedefs
490+ anaconda .ModuleNetwork ,
491+ anaconda .ModulePayloads ,
492+ anaconda .ModuleRuntime ,
493+ anaconda .ModuleStorage ,
494+ )
495+ if bpKernel := customizations .GetKernel (); bpKernel .Append != "" {
496+ img .InstallerCustomizations .KernelOptionsAppend = append (img .InstallerCustomizations .KernelOptionsAppend , bpKernel .Append )
497+ }
498+
499+ img .Kickstart .OSTree = & kickstart.OSTree {
500+ OSName : "default" ,
501+ }
502+ img .InstallerCustomizations .LoraxTemplates = LoraxTemplates (t .arch .distro .sourceInfo .OSRelease )
503+ img .InstallerCustomizations .LoraxTemplatePackage = LoraxTemplatePackage (t .arch .distro .sourceInfo .OSRelease )
504+
505+ // see https://github.com/osbuild/bootc-image-builder/issues/733
506+ img .InstallerCustomizations .ISORootfsType = manifest .SquashfsRootfs
507+
508+ installRootfsType , err := disk .NewFSType (t .arch .distro .defaultFs )
509+ if err != nil {
510+ return nil , nil , err
511+ }
512+ img .InstallRootfsType = installRootfsType
513+
514+ mf := manifest .New ()
515+
516+ foundDistro , foundRunner , err := GetDistroAndRunner (t .arch .distro .sourceInfo .OSRelease )
517+ if err != nil {
518+ return nil , nil , fmt .Errorf ("failed to infer distro and runner: %w" , err )
519+ }
520+ mf .Distro = foundDistro
521+
522+ _ , err = img .InstantiateManifestFromContainer (& mf , []container.SourceSpec {containerSource }, foundRunner , rng )
523+ return & mf , nil , err
524+ }
525+
378526// newBootcDistro returns a new instance of BootcDistro
379527// from the given url
380528func NewBootcDistro (imgref string ) (* BootcDistro , error ) {
@@ -447,12 +595,6 @@ func newBootcDistroAfterIntrospect(archStr string, info *osinfo.Info, imgref, de
447595 ImageTypeYAML : imgTypeYaml ,
448596 })
449597 }
450- // XXX: move into YAML as well
451- ba .imageTypes ["bootc-installer" ] = & BootcAnacondaInstaller {
452- arch : ba ,
453- name : "bootc-installer" ,
454- export : "bootiso" ,
455- }
456598 bd .addArches (ba )
457599
458600 return bd , nil
0 commit comments