Skip to content

Commit 2937921

Browse files
mvo5supakeen
authored andcommitted
bootc: make bootc-installer ISO use YAML too
This commit moves the `bootc-installer` image type into YAML too. This makes it more uniform and we can drop some code. This means we have two manifest generating function but at least less duplication in the imagetype code.
1 parent 5a17790 commit 2937921

File tree

3 files changed

+155
-240
lines changed

3 files changed

+155
-240
lines changed

data/distrodefs/bootc-generic/imagetypes.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,9 @@ image_types:
136136
filename: "image.ova"
137137
mime_type: "application/ovf"
138138
exports: ["archive"]
139+
140+
bootc-installer:
141+
mime_type: "application/x-iso9660-image"
142+
exports: ["bootiso"]
143+
filename: "install.iso"
144+
boot_iso: true

pkg/distro/bootc/bootc.go

Lines changed: 149 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

274277
func (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

289303
func (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
380528
func 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

Comments
 (0)