deps: bump images to 0.164

We have an issue where `%post` scripts are not being executed due to our incorrect handling of Anaconda modules [1].

[1]: https://github.com/osbuild/bootc-image-builder/issues/968

Signed-off-by: Simon de Vlieger <supakeen@redhat.com>
This commit is contained in:
Simon de Vlieger 2025-07-21 12:25:08 +02:00 committed by Tomáš Hozza
parent d8db1e7c39
commit ccb4a3df88
89 changed files with 57336 additions and 56135 deletions

View file

@ -1 +1 @@
153
156

View file

@ -1,7 +0,0 @@
package workload
// TODO: replace the Anaconda pipeline by the OS pipeline with the
// anaconda workload.
type Anaconda struct {
BaseWorkload
}

View file

@ -1,6 +0,0 @@
package workload
// TODO!
type SAP struct {
BaseWorkload
}

View file

@ -1,7 +0,0 @@
package workload
// TODO: replace the CommitServerTree pipeline by the OS pipeline with the
// StaticWebserver workload.
type StaticWebserver struct {
BaseWorkload
}

View file

@ -81,6 +81,18 @@ distros:
- "platform-python" # osbuild
- "systemd" # systemd-tmpfiles and systemd-sysusers
- "python3" # osbuild stages
conditions:
"some image types are rhel-only":
when:
not_distro_name: "rhel"
ignore_image_types:
- azure-cvm
- azure-rhui
- azure-sap-rhui
- azure-sapapps-rhui
- ec2
- ec2-sap
- ec2-ha
# rhel9 & cs9 share the same list
# of allowed profiles so a single
# allow list can be used
@ -111,6 +123,7 @@ distros:
iso_label_tmpl: "AlmaLinux-{{.Distro.MajorVersion}}-{{.Distro.MinorVersion}}-{{.Arch}}-dvd"
- &centos10
<<: *rhel10
name: centos-10
distro_like: rhel-10
product: "CentOS Stream"
@ -122,14 +135,6 @@ distros:
default_fs_type: "xfs"
defs_path: rhel-10
iso_label_tmpl: "CentOS-Stream-{{.Distro.MajorVersion}}-BaseOS-{{.Arch}}"
ignore_image_types:
- azure-cvm
- azure-rhui
- azure-sap-rhui
- azure-sapapps-rhui
- ec2
- ec2-sap
- ec2-ha
runner:
name: org.osbuild.centos10
build_packages:

View file

@ -38,6 +38,13 @@
- "rw"
- "coreos.no_persist_ip"
rpm_ostree_imgtype_common: &rpm_ostree_imgtype_common
rpm_ostree: true
supported_partitioning_modes:
- "" # empty string means default partitioning mode
- "auto-lvm"
- "lvm"
environments:
kvm: &kvm_env
packages:
@ -577,6 +584,13 @@ image_types:
- <<: *aarch64_platform
image_format: "vagrant_libvirt"
"server-vagrant-virtualbox": &server_vagrant_virtualbox
<<: *server_vagrant_libvirt
filename: "vagrant-virtualbox.box"
platforms:
- <<: *x86_64_bios_platform
image_format: "vagrant_virtualbox"
"server-qcow2": &server_qcow2
name_aliases: ["qcow2"]
filename: "disk.qcow2"
@ -747,10 +761,10 @@ image_types:
# NOTE: keep in sync with official fedora-iot definitions:
# https://pagure.io/fedora-iot/ostree/blob/main/f/fedora-iot-base.yaml
"iot-commit": &iot_commit
<<: *rpm_ostree_imgtype_common
name_aliases: ["fedora-iot-commit"]
filename: "commit.tar"
mime_type: "application/x-tar"
rpm_ostree: true
image_func: "iot_commit"
build_pipelines: ["build"]
payload_pipelines: ["os", "ostree-commit", "commit-archive"]
@ -911,7 +925,6 @@ image_types:
name_aliases: ["fedora-iot-container"]
filename: "container.tar"
mime_type: "application/x-tar"
rpm_ostree: true
image_func: "iot_container"
build_pipelines: ["build"]
payload_pipelines: ["os", "ostree-commit", "container-tree", "container"]
@ -922,12 +935,12 @@ image_types:
- *aarch64_installer_platform
"iot-raw-xz":
<<: *rpm_ostree_imgtype_common
name_aliases: ["iot-raw-image", "fedora-iot-raw-image"]
filename: "image.raw.xz"
compression: "xz"
mime_type: "application/xz"
default_size: 4_294_967_296 # 4 * datasizes.GibiByte
rpm_ostree: true
bootable: true
image_func: "iot"
ostree:
@ -1002,11 +1015,11 @@ image_types:
- *iot_base_partition_table_part_root_fstab_ro_aarch64
"iot-qcow2":
<<: *rpm_ostree_imgtype_common
name_aliases: ["iot-qcow2-image"]
filename: "image.qcow2"
mime_type: "application/x-qemu-disk"
default_size: 10_737_418_240 # 10 * datasizes.GibiByte
rpm_ostree: true
bootable: true
image_func: "iot"
ostree:
@ -1031,9 +1044,9 @@ image_types:
qcow2_compat: "1.1"
"iot-bootable-container":
<<: *rpm_ostree_imgtype_common
filename: "iot-bootable-container.tar"
mime_type: "application/x-tar"
rpm_ostree: true
image_func: "bootable_container"
build_pipelines: ["build"]
payload_pipelines: ["os", "ostree-commit", "ostree-encapsulate"]
@ -1468,10 +1481,10 @@ image_types:
- "dmidecode"
"iot-installer":
<<: *rpm_ostree_imgtype_common
name_aliases: ["fedora-iot-installer"]
filename: "installer.iso"
mime_type: "application/x-iso9660-image"
rpm_ostree: true
boot_iso: true
image_func: "iot_installer"
iso_label: "IoT"
@ -1497,6 +1510,11 @@ image_types:
version_less_than: "41"
shallow_merge:
iso_rootfs_type: "squashfs-ext4"
"x86_64 uses grub2":
when:
arch: "x86_64"
shallow_merge:
iso_boot_type: "grub2"
package_sets:
installer:
- *anaconda_pkgset
@ -1532,6 +1550,11 @@ image_types:
version_less_than: "41"
shallow_merge:
iso_rootfs_type: "squashfs-ext4"
"x86_64 uses grub2":
when:
arch: "x86_64"
shallow_merge:
iso_boot_type: "grub2"
package_sets:
installer:
- include:
@ -1628,6 +1651,11 @@ image_types:
version_less_than: "41"
shallow_merge:
iso_rootfs_type: "squashfs-ext4"
"x86_64 uses grub2":
when:
arch: "x86_64"
shallow_merge:
iso_boot_type: "grub2"
platforms:
- *x86_64_installer_platform
- *aarch64_installer_platform
@ -1807,9 +1835,9 @@ image_types:
- "fuse-libs"
"iot-simplified-installer":
<<: *rpm_ostree_imgtype_common
filename: "simplified-installer.iso"
mime_type: "application/x-iso9660-image"
rpm_ostree: true
bootable: true
boot_iso: true
default_size: 10_737_418_240 # 10 * datasizes.GibiByte

View file

@ -101,7 +101,7 @@ type DistroYAML struct {
imageConfig *distro.ImageConfig `yaml:"default"`
// ignore the given image types
IgnoreImageTypes []string `yaml:"ignore_image_types"`
Conditions map[string]distroConditions `yaml:"conditions"`
// XXX: remove this in favor of a better abstraction, this
// is currently needed because the manifest pkg has conditionals
@ -121,6 +121,18 @@ func (d *DistroYAML) ImageConfig() *distro.ImageConfig {
return d.imageConfig
}
func (d *DistroYAML) SkipImageType(imgTypeName, archName string) bool {
id := common.Must(distro.ParseID(d.Name))
for _, cond := range d.Conditions {
if cond.When.Eval(id, archName) && slices.Contains(cond.IgnoreImageTypes, imgTypeName) {
return true
}
}
return false
}
func (d *DistroYAML) runTemplates(nameVer string) error {
id, err := distro.ParseID(nameVer)
if err != nil {
@ -216,9 +228,6 @@ func NewDistroYAML(nameVer string) (*DistroYAML, error) {
if len(toplevel.ImageTypes) > 0 {
foundDistro.imageTypes = make(map[string]ImageTypeYAML, len(toplevel.ImageTypes))
for name := range toplevel.ImageTypes {
if slices.Contains(foundDistro.IgnoreImageTypes, name) {
continue
}
v := toplevel.ImageTypes[name]
v.name = name
if err := v.runTemplates(foundDistro); err != nil {
@ -252,6 +261,7 @@ type distroImageConfig struct {
// multiple whenConditions are considred AND
type whenCondition struct {
DistroName string `yaml:"distro_name,omitempty"`
NotDistroName string `yaml:"not_distro_name,omitempty"`
Architecture string `yaml:"arch,omitempty"`
VersionLessThan string `yaml:"version_less_than,omitempty"`
VersionGreaterOrEqual string `yaml:"version_greater_or_equal,omitempty"`
@ -264,6 +274,9 @@ func (wc *whenCondition) Eval(id *distro.ID, archStr string) bool {
if wc.DistroName != "" {
match = match && (wc.DistroName == id.Name)
}
if wc.NotDistroName != "" {
match = match && (wc.NotDistroName != id.Name)
}
if wc.Architecture != "" {
match = match && (wc.Architecture == archStr)
}
@ -306,6 +319,11 @@ type distroImageConfigConditions struct {
ShallowMerge *distro.ImageConfig `yaml:"shallow_merge,omitempty"`
}
type distroConditions struct {
When *whenCondition `yaml:"when"`
IgnoreImageTypes []string `yaml:"ignore_image_types"`
}
type ImageTypeYAML struct {
// This maps "pkgsKey" to their package sets. The
// map key here is a string that can either be:
@ -361,6 +379,8 @@ type ImageTypeYAML struct {
DiskImagePartTool *osbuild.PartTool `yaml:"disk_image_part_tool"`
DiskImageVPCForceSize *bool `yaml:"disk_image_vpc_force_size"`
SupportedPartitioningModes []disk.PartitioningMode `yaml:"supported_partitioning_modes"`
// name is set by the loader
name string
}

View file

@ -799,7 +799,7 @@ image_types:
- "insights-client"
- "subscription-manager-cockpit"
"vagrant-libvirt":
"vagrant-libvirt": &vagrant_libvirt
<<: *qcow2
filename: "vagrant-libvirt.box"
mime_type: "application/x-tar"
@ -813,10 +813,8 @@ image_types:
platforms:
- <<: *x86_64_bios_platform
image_format: "vagrant_libvirt"
qcow2_compat: ""
- <<: *aarch64_platform
image_format: "vagrant_libvirt"
qcow2_compat: ""
image_config:
<<: *qcow2_image_config
users:
@ -834,6 +832,13 @@ image_types:
data: |
vagrant ALL=(ALL) NOPASSWD: ALL
"vagrant-virtualbox":
<<: *vagrant_libvirt
filename: "vagrant-virtualbox.box"
platforms:
- <<: *x86_64_bios_platform
image_format: "vagrant_virtualbox"
oci:
<<: *qcow2
platforms:
@ -1525,6 +1530,12 @@ image_types:
required_partition_sizes: *default_required_dir_sizes
image_config:
iso_rootfs_type: "squashfs"
conditions:
"x86_64 uses grub2":
when:
arch: "x86_64"
shallow_merge:
iso_boot_type: "grub2"
installer_config:
additional_dracut_modules:
- "nvdimm" # non-volatile DIMM firmware (provides nfit, cuse, and nd_e820)

View file

@ -1511,8 +1511,58 @@ image_types:
- "rhui-azure-rhel8"
exclude:
- "firewalld"
# from the previous eapWorkload() workload, for simplicity
# this is now a normal packageset
- include:
- "java-1.8.0-openjdk"
- "java-1.8.0-openjdk-devel"
- "eap7-wildfly"
- "eap7-artemis-native-wildfly"
exclude:
# weak dependencies of the above eapWorkload packages
# that we don't need (and were not part of the original
# eapWorkload() package set (as it excluded weak deps)
- "graphite2"
- "libXdamage"
- "libXrandr"
- "libthai"
- "libXfixes"
- "atk"
- "fribidi"
- "jbigkit-libs"
- "hicolor-icon-theme"
- "libtiff"
- "gtk2"
- "harfbuzz"
- "libXinerama"
- "libatrie"
- "libXft"
- "pango"
- "gdk-pixbuf2-modules"
- "libXcursor"
conditions:
"rhel-8.8+ needs to exclude libjpeg-turbo as well":
when:
version_greater_or_equal: "8.8"
append:
exclude:
- "libjpeg-turbo"
"rhel-8.10 must exclude python3-{webencodings,html5lib":
when:
version_greater_or_equal: "8.10"
append:
exclude:
- "python3-webencodings"
- "python3-html5lib"
"image-installer":
image_config:
conditions:
"x86_64 uses syslinux":
when:
arch: "x86_64"
shallow_merge:
iso_boot_type: "syslinux"
package_sets:
<<: *bare_metal_pkgset
installer:
@ -1710,6 +1760,12 @@ image_types:
"edge-installer":
image_config:
iso_rootfs_type: "squashfs-ext4"
conditions:
"x86_64 uses syslinux":
when:
arch: "x86_64"
shallow_merge:
iso_boot_type: "syslinux"
package_sets:
installer:
# TODO: non-arch-specific package set handling for installers

View file

@ -1671,6 +1671,12 @@ image_types:
"image-installer":
image_config:
locale: "C.UTF-8"
conditions:
"x86_64 uses syslinux":
when:
arch: "x86_64"
shallow_merge:
iso_boot_type: "syslinux"
package_sets:
<<: *bare_metal_pkgset
installer:
@ -2144,6 +2150,12 @@ image_types:
image_config:
enabled_services: *enabled_services_edge
locale: "en_US.UTF-8"
conditions:
"x86_64 uses syslinux":
when:
arch: "x86_64"
shallow_merge:
iso_boot_type: "syslinux"
package_sets:
installer:
- *installer_pkgset
@ -2324,6 +2336,19 @@ image_types:
apply_network_config: false
datasource_list:
- "Azure"
conditions:
<<: *conditions_azure_image_config_base
"x86_64 shim package version lock":
# Lock the shim package to its installed version. This is necessary
# for UKI-based images that can become unbootable if the shim is
# upgraded to one signed by a newer certificate that does not exist
# in the system's database.
# See https://issues.redhat.com/browse/RHEL-93650
when:
arch: "x86_64"
shallow_merge:
versionlock_packages:
- "shim-x64"
package_sets:
os:
- include:

View file

@ -102,6 +102,9 @@ func newDistro(nameVer string) (distro.Distro, error) {
ar = newArchitecture(rd, pl.Arch.String())
rd.arches[pl.Arch.String()] = ar
}
if distroYAML.SkipImageType(imgTypeYAML.Name(), pl.Arch.String()) {
continue
}
it := newImageTypeFrom(rd, ar, imgTypeYAML)
if err := ar.addImageType(&pl, it); err != nil {
return nil, err

View file

@ -6,7 +6,6 @@ import (
"strings"
"github.com/osbuild/images/internal/workload"
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/blueprint"
"github.com/osbuild/images/pkg/container"
"github.com/osbuild/images/pkg/customizations/anaconda"
@ -155,9 +154,9 @@ func osCustomizations(t *imageType, osPackageSet rpmmd.PackageSet, options distr
osc.ChronyConfig = imageConfig.TimeSynchronization
}
// Relabel the tree, unless the `NoSElinux` flag is explicitly set to `true`
if imageConfig.NoSElinux == nil || imageConfig.NoSElinux != nil && !*imageConfig.NoSElinux {
osc.SElinux = "targeted"
// Relabel the tree, unless the `NoSELinux` flag is explicitly set to `true`
if imageConfig.NoSELinux == nil || imageConfig.NoSELinux != nil && !*imageConfig.NoSELinux {
osc.SELinux = "targeted"
osc.SELinuxForceRelabel = imageConfig.SELinuxForceRelabel
}
@ -317,6 +316,8 @@ func osCustomizations(t *imageType, osPackageSet rpmmd.PackageSet, options distr
osc.MountUnits = *imageConfig.MountUnits
}
osc.VersionlockPackages = imageConfig.VersionlockPackages
return osc, nil
}
@ -527,14 +528,15 @@ func liveInstallerImage(workload workload.Workload,
img.Filename = t.Filename()
// Enable grub2 BIOS iso on x86_64 only
if img.Platform.GetArch() == arch.ARCH_X86_64 {
img.ISOBoot = manifest.Grub2ISOBoot
}
if locale := t.getDefaultImageConfig().Locale; locale != nil {
img.Locale = *locale
}
if isoroot := t.getDefaultImageConfig().ISORootfsType; isoroot != nil {
img.RootfsType = *isoroot
}
if isoboot := t.getDefaultImageConfig().ISOBootType; isoboot != nil {
img.ISOBoot = *isoboot
}
installerConfig, err := t.getDefaultInstallerConfig()
if err != nil {
@ -548,11 +550,6 @@ func liveInstallerImage(workload workload.Workload,
}
}
imgConfig := t.getDefaultImageConfig()
if imgConfig != nil && imgConfig.IsoRootfsType != nil {
img.RootfsType = *imgConfig.IsoRootfsType
}
return img, nil
}
@ -639,14 +636,11 @@ func imageInstallerImage(workload workload.Workload,
img.Filename = t.Filename()
img.RootfsCompression = "xz" // This also triggers using the bcj filter
imgConfig := t.getDefaultImageConfig()
if imgConfig != nil && imgConfig.IsoRootfsType != nil {
img.RootfsType = *imgConfig.IsoRootfsType
if isoroot := t.getDefaultImageConfig().ISORootfsType; isoroot != nil {
img.RootfsType = *isoroot
}
// Enable grub2 BIOS iso on x86_64 only
if img.Platform.GetArch() == arch.ARCH_X86_64 {
img.ISOBoot = manifest.Grub2ISOBoot
if isoboot := t.getDefaultImageConfig().ISOBootType; isoboot != nil {
img.ISOBoot = *isoboot
}
return img, nil
@ -838,19 +832,15 @@ func iotInstallerImage(workload workload.Workload,
img.Filename = t.Filename()
img.RootfsCompression = "xz" // This also triggers using the bcj filter
imgConfig := t.getDefaultImageConfig()
if imgConfig != nil && imgConfig.IsoRootfsType != nil {
img.RootfsType = *imgConfig.IsoRootfsType
}
// Enable grub2 BIOS iso on x86_64 only
if img.Platform.GetArch() == arch.ARCH_X86_64 {
img.ISOBoot = manifest.Grub2ISOBoot
}
if locale := t.getDefaultImageConfig().Locale; locale != nil {
img.Locale = *locale
}
if isoroot := t.getDefaultImageConfig().ISORootfsType; isoroot != nil {
img.RootfsType = *isoroot
}
if isoboot := t.getDefaultImageConfig().ISOBootType; isoboot != nil {
img.ISOBoot = *isoboot
}
return img, nil
}

View file

@ -159,19 +159,8 @@ func (t *imageType) getPartitionTable(customizations *blueprint.Customizations,
return disk.NewCustomPartitionTable(partitioning, partOptions, rng)
}
partitioningMode := options.PartitioningMode
if t.ImageTypeYAML.RPMOSTree {
// IoT supports only LVM, force it.
// Raw is not supported, return an error if it is requested
// TODO Need a central location for logic like this
if partitioningMode == disk.RawPartitioningMode {
return nil, fmt.Errorf("partitioning mode raw not supported for %s on %s", t.Name(), t.arch.Name())
}
partitioningMode = disk.AutoLVMPartitioningMode
}
mountpoints := customizations.GetFilesystems()
return disk.NewPartitionTable(basePartitionTable, mountpoints, imageSize, partitioningMode, t.platform.GetArch(), t.ImageTypeYAML.RequiredPartitionSizes, rng)
return disk.NewPartitionTable(basePartitionTable, mountpoints, imageSize, options.PartitioningMode, t.platform.GetArch(), t.ImageTypeYAML.RequiredPartitionSizes, rng)
}
func (t *imageType) getDefaultImageConfig() *distro.ImageConfig {
@ -332,6 +321,10 @@ func (t *imageType) checkOptions(bp *blueprint.Blueprint, options distro.ImageOp
return warnings, fmt.Errorf("OSTree is not supported for %q", t.Name())
}
if len(t.ImageTypeYAML.SupportedPartitioningModes) > 0 && !slices.Contains(t.ImageTypeYAML.SupportedPartitioningModes, options.PartitioningMode) {
return warnings, fmt.Errorf("partitioning mode %s not supported for %q on %q", options.PartitioningMode, t.Name(), t.arch.distro.Name())
}
// we do not support embedding containers on ostree-derived images, only on commits themselves
if len(bp.Containers) > 0 && t.ImageTypeYAML.RPMOSTree && (t.Name() != "iot-commit" && t.Name() != "iot-container") {
return warnings, fmt.Errorf("embedding containers is not supported for %s on %s", t.Name(), t.arch.distro.Name())

View file

@ -46,7 +46,7 @@ type ImageConfig struct {
GPGKeyFiles []string `yaml:"gpgkey_files,omitempty"`
// Disable SELinux labelling
NoSElinux *bool `yaml:"no_selinux,omitempty"`
NoSELinux *bool `yaml:"no_selinux,omitempty"`
// Do not use. Forces auto-relabelling on first boot.
// See https://github.com/osbuild/osbuild/commit/52cb27631b587c1df177cd17625c5b473e1e85d2
@ -135,9 +135,18 @@ type ImageConfig struct {
// instead of writing to /etc/fstab
MountUnits *bool `yaml:"mount_units,omitempty"`
// IsoRootfsType defines what rootfs (squashfs, erofs,ext4)
// ISORootfsType defines what rootfs (squashfs, erofs,ext4)
// is used
IsoRootfsType *manifest.RootfsType `yaml:"iso_rootfs_type,omitempty"`
ISORootfsType *manifest.RootfsType `yaml:"iso_rootfs_type,omitempty"`
// ISOBootType defines what type of bootloader is used for the iso
ISOBootType *manifest.ISOBootType `yaml:"iso_boot_type,omitempty"`
// VersionlockPackges uses dnf versionlock to lock a package to the version
// that is installed during image build, preventing it from being updated.
// This is only supported for distributions that use dnf4, because osbuild
// only has a stage for dnf4 version locking.
VersionlockPackages []string `yaml:"versionlock_packages,omitempty"`
}
// shallowMerge creates a new struct by merging a child and a parent.

View file

@ -5,7 +5,6 @@ import (
"math/rand"
"github.com/osbuild/images/internal/workload"
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/blueprint"
"github.com/osbuild/images/pkg/container"
"github.com/osbuild/images/pkg/customizations/anaconda"
@ -154,9 +153,9 @@ func osCustomizations(
osc.ChronyConfig = imageConfig.TimeSynchronization
}
// Relabel the tree, unless the `NoSElinux` flag is explicitly set to `true`
if imageConfig.NoSElinux == nil || imageConfig.NoSElinux != nil && !*imageConfig.NoSElinux {
osc.SElinux = "targeted"
// Relabel the tree, unless the `NoSELinux` flag is explicitly set to `true`
if imageConfig.NoSELinux == nil || imageConfig.NoSELinux != nil && !*imageConfig.NoSELinux {
osc.SELinux = "targeted"
osc.SELinuxForceRelabel = imageConfig.SELinuxForceRelabel
}
@ -312,6 +311,8 @@ func osCustomizations(
osc.MountUnits = *imageConfig.MountUnits
}
osc.VersionlockPackages = imageConfig.VersionlockPackages
return osc, nil
}
@ -537,15 +538,11 @@ func EdgeInstallerImage(workload workload.Workload,
img.RootfsType = manifest.SquashfsRootfs
}
// Enable BIOS iso on x86_64 only
// Use grub2 on RHEL10, otherwise use syslinux
// NOTE: Will need to be updated for RHEL11 and later
if img.Platform.GetArch() == arch.ARCH_X86_64 {
if t.Arch().Distro().Releasever() == "10" {
img.ISOBoot = manifest.Grub2ISOBoot
} else {
img.ISOBoot = manifest.SyslinuxISOBoot
}
if locale := t.getDefaultImageConfig().Locale; locale != nil {
img.Locale = *locale
}
if isoboot := t.getDefaultImageConfig().ISOBootType; isoboot != nil {
img.ISOBoot = *isoboot
}
installerConfig, err := t.getDefaultInstallerConfig()
@ -585,10 +582,6 @@ func EdgeInstallerImage(workload workload.Workload,
img.Filename = t.Filename()
if locale := t.getDefaultImageConfig().Locale; locale != nil {
img.Locale = *locale
}
return img, nil
}
@ -774,15 +767,8 @@ func ImageInstallerImage(workload workload.Workload,
img.RootfsType = manifest.SquashfsRootfs
}
// Enable BIOS iso on x86_64 only
// Use grub2 on RHEL10, otherwise use syslinux
// NOTE: Will need to be updated for RHEL11 and later
if img.Platform.GetArch() == arch.ARCH_X86_64 {
if t.Arch().Distro().Releasever() == "10" {
img.ISOBoot = manifest.Grub2ISOBoot
} else {
img.ISOBoot = manifest.SyslinuxISOBoot
}
if isoboot := t.getDefaultImageConfig().ISOBootType; isoboot != nil {
img.ISOBoot = *isoboot
}
// put the kickstart file in the root of the iso

View file

@ -106,7 +106,6 @@ func mkAzureEap7RhuiImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType
it.Bootable = true
it.DefaultSize = 64 * datasizes.GibiByte
it.BasePartitionTables = partitionTables
it.Workload = eapWorkload()
return it
}

View file

@ -1,11 +1,12 @@
package rhel8
import (
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/distro/rhel"
)
func mkImageInstaller() *rhel.ImageType {
func mkImageInstaller(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"image-installer",
"installer.iso",
@ -21,6 +22,7 @@ func mkImageInstaller() *rhel.ImageType {
it.Bootable = true
it.ISOLabelFn = distroISOLabelFunc
it.DefaultImageConfig = imageConfig(rd, a.String(), "image-installer")
it.DefaultInstallerConfig = &distro.InstallerConfig{
AdditionalDracutModules: []string{
"ifcfg",

View file

@ -141,7 +141,7 @@ func newDistro(name string, minor int) *rhel.Distribution {
mkEdgeOCIImgType(rd, arch.ARCH_X86_64),
mkEdgeCommitImgType(rd, arch.ARCH_X86_64),
mkEdgeInstallerImgType(rd, arch.ARCH_X86_64),
mkImageInstaller(),
mkImageInstaller(rd, arch.ARCH_X86_64),
)
gceX86Platform := &platform.X86{
@ -202,7 +202,7 @@ func newDistro(name string, minor int) *rhel.Distribution {
ImageFormat: platform.FORMAT_QCOW2,
},
},
mkOpenstackImgType(rd, arch.ARCH_X86_64),
mkOpenstackImgType(rd, arch.ARCH_AARCH64),
)
aarch64.AddImageTypes(
@ -218,10 +218,10 @@ func newDistro(name string, minor int) *rhel.Distribution {
aarch64.AddImageTypes(
bareMetalAarch64Platform,
mkEdgeOCIImgType(rd, arch.ARCH_X86_64),
mkEdgeCommitImgType(rd, arch.ARCH_X86_64),
mkEdgeInstallerImgType(rd, arch.ARCH_X86_64),
mkImageInstaller(),
mkEdgeOCIImgType(rd, arch.ARCH_AARCH64),
mkEdgeCommitImgType(rd, arch.ARCH_AARCH64),
mkEdgeInstallerImgType(rd, arch.ARCH_AARCH64),
mkImageInstaller(rd, arch.ARCH_AARCH64),
)
rawAarch64Platform := &platform.Aarch64{
@ -234,7 +234,7 @@ func newDistro(name string, minor int) *rhel.Distribution {
aarch64.AddImageTypes(
rawAarch64Platform,
mkAmiImgTypeAarch64(rd),
mkMinimalRawImgType(rd, arch.ARCH_X86_64),
mkMinimalRawImgType(rd, arch.ARCH_AARCH64),
)
ppc64le.AddImageTypes(

View file

@ -1,26 +0,0 @@
package rhel8
import "github.com/osbuild/images/internal/workload"
// rhel8Workload is a RHEL-8-specific implementation of the workload interface
// for internal workload variants.
type rhel8Workload struct {
workload.BaseWorkload
packages []string
}
func (w rhel8Workload) GetPackages() []string {
return w.packages
}
func eapWorkload() workload.Workload {
w := rhel8Workload{}
w.packages = []string{
"java-1.8.0-openjdk",
"java-1.8.0-openjdk-devel",
"eap7-wildfly",
"eap7-artemis-native-wildfly",
}
return &w
}

View file

@ -77,8 +77,8 @@ func (img *AnacondaLiveInstaller) InstantiateManifest(m *manifest.Manifest,
livePipeline.Biosdevname = (img.Platform.GetArch() == arch.ARCH_X86_64)
livePipeline.Locale = img.Locale
// The live installer has SElinux enabled and targeted
livePipeline.SElinux = "targeted"
// The live installer has SELinux enabled and targeted
livePipeline.SELinux = "targeted"
livePipeline.Checkpoint()

View file

@ -6,7 +6,6 @@ import (
"github.com/osbuild/images/pkg/container"
"github.com/osbuild/images/pkg/customizations/fsnode"
"github.com/osbuild/images/pkg/customizations/users"
"github.com/osbuild/images/pkg/disk"
"github.com/osbuild/images/pkg/manifest"
"github.com/osbuild/images/pkg/osbuild"
@ -26,21 +25,7 @@ type BootcDiskImage struct {
BuildContainerSource *container.SourceSpec
// Customizations
KernelOptionsAppend []string
// The users to put into the image, note that /etc/paswd (and friends)
// will become unmanaged state by bootc when used
Users []users.User
Groups []users.Group
// Custom directories and files to create in the image
Directories []*fsnode.Directory
Files []*fsnode.File
// SELinux policy, when set it enables the labeling of the tree with the
// selected profile
SELinux string
BuildSELinux string
OSCustomizations manifest.OSCustomizations
}
func NewBootcDiskImage(container container.SourceSpec, buildContainer container.SourceSpec) *BootcDiskImage {
@ -56,9 +41,9 @@ func (img *BootcDiskImage) InstantiateManifestFromContainers(m *manifest.Manifes
runner runner.Runner,
rng *rand.Rand) error {
policy := img.SELinux
if img.BuildSELinux != "" {
policy = img.BuildSELinux
policy := img.OSCustomizations.SELinux
if img.OSCustomizations.BuildSELinux != "" {
policy = img.OSCustomizations.BuildSELinux
}
var copyFilesFrom map[string][]string
@ -116,12 +101,12 @@ func (img *BootcDiskImage) InstantiateManifestFromContainers(m *manifest.Manifes
rawImage := manifest.NewRawBootcImage(buildPipeline, containers, img.Platform)
rawImage.PartitionTable = img.PartitionTable
rawImage.Users = img.Users
rawImage.Groups = img.Groups
rawImage.Files = img.Files
rawImage.Directories = img.Directories
rawImage.KernelOptionsAppend = img.KernelOptionsAppend
rawImage.SELinux = img.SELinux
rawImage.Users = img.OSCustomizations.Users
rawImage.Groups = img.OSCustomizations.Groups
rawImage.Files = img.OSCustomizations.Files
rawImage.Directories = img.OSCustomizations.Directories
rawImage.KernelOptionsAppend = img.OSCustomizations.KernelOptionsAppend
rawImage.SELinux = img.OSCustomizations.SELinux
rawImage.MountUnits = true // always use mount units for bootc disk images
// In BIB, we export multiple images from the same pipeline so we use the

View file

@ -44,9 +44,9 @@ func (img *BootcLegacyDiskImage) InstantiateManifestFromContainers(m *manifest.M
}
ostreeImg.Platform = img.bootcImg.Platform
ostreeImg.PartitionTable = img.bootcImg.PartitionTable
ostreeImg.OSTreeDeploymentCustomizations.KernelOptionsAppend = img.bootcImg.KernelOptionsAppend
ostreeImg.OSTreeDeploymentCustomizations.Users = img.bootcImg.Users
ostreeImg.OSTreeDeploymentCustomizations.Groups = img.bootcImg.Groups
ostreeImg.OSTreeDeploymentCustomizations.KernelOptionsAppend = img.bootcImg.OSCustomizations.KernelOptionsAppend
ostreeImg.OSTreeDeploymentCustomizations.Users = img.bootcImg.OSCustomizations.Users
ostreeImg.OSTreeDeploymentCustomizations.Groups = img.bootcImg.OSCustomizations.Groups
buildPipeline := manifest.NewBuildFromContainer(m, runner, containers, &manifest.BuildOptions{ContainerBuildable: true})
buildPipeline.Checkpoint()

View file

@ -76,11 +76,22 @@ func (img *DiskImage) InstantiateManifest(m *manifest.Manifest,
qcow2Pipeline := manifest.NewQCOW2(buildPipeline, rawImagePipeline)
qcow2Pipeline.Compat = img.Platform.GetQCOW2Compat()
vagrantPipeline := manifest.NewVagrant(buildPipeline, qcow2Pipeline)
vagrantPipeline := manifest.NewVagrant(buildPipeline, qcow2Pipeline, osbuild.VagrantProviderLibvirt, rng)
tarPipeline := manifest.NewTar(buildPipeline, vagrantPipeline, "archive")
tarPipeline.Format = osbuild.TarArchiveFormatUstar
imagePipeline = tarPipeline
case platform.FORMAT_VAGRANT_VIRTUALBOX:
vmdkPipeline := manifest.NewVMDK(buildPipeline, rawImagePipeline)
vmdkPipeline.SetFilename("box.vmdk")
vagrantPipeline := manifest.NewVagrant(buildPipeline, vmdkPipeline, osbuild.VagrantProviderVirtualBox, rng)
tarPipeline := manifest.NewTar(buildPipeline, vagrantPipeline, "archive")
tarPipeline.Format = osbuild.TarArchiveFormatUstar
tarPipeline.SetFilename(img.Filename)
imagePipeline = tarPipeline
case platform.FORMAT_VHD:
vpcPipeline := manifest.NewVPC(buildPipeline, rawImagePipeline)

View file

@ -86,7 +86,7 @@ type AnacondaInstaller struct {
// SELinux policy, when set it enables the labeling of the installer
// tree with the selected profile and selects the required package
// for depsolving
SElinux string
SELinux string
// Locale for the installer. This should be set to the same locale as the
// ISO OS payload, if known.
@ -167,8 +167,8 @@ func (p *AnacondaInstaller) getBuildPackages(Distro) []string {
)
}
if p.SElinux != "" {
packages = append(packages, "policycoreutils", fmt.Sprintf("selinux-policy-%s", p.SElinux))
if p.SELinux != "" {
packages = append(packages, "policycoreutils", fmt.Sprintf("selinux-policy-%s", p.SELinux))
}
return packages
@ -183,8 +183,8 @@ func (p *AnacondaInstaller) getPackageSetChain(Distro) []rpmmd.PackageSet {
packages = append(packages, "biosdevname")
}
if p.SElinux != "" {
packages = append(packages, fmt.Sprintf("selinux-policy-%s", p.SElinux))
if p.SELinux != "" {
packages = append(packages, fmt.Sprintf("selinux-policy-%s", p.SELinux))
}
return []rpmmd.PackageSet{
@ -192,7 +192,7 @@ func (p *AnacondaInstaller) getPackageSetChain(Distro) []rpmmd.PackageSet {
Include: append(packages, p.ExtraPackages...),
Exclude: p.ExcludePackages,
Repositories: append(p.repos, p.ExtraRepos...),
InstallWeakDeps: p.Type == AnacondaInstallerTypeLive,
InstallWeakDeps: true,
},
}
}
@ -328,10 +328,10 @@ func (p *AnacondaInstaller) payloadStages() []*osbuild.Stage {
stages = append(stages, osbuild.NewSELinuxConfigStage(&osbuild.SELinuxConfigStageOptions{State: osbuild.SELinuxStatePermissive}))
// SElinux is not supported on the non-live-installers (see the previous
// SELinux is not supported on the non-live-installers (see the previous
// stage setting SELinux to permissive. It's an error to set it to anything
// that isn't an empty string
if p.SElinux != "" {
if p.SELinux != "" {
panic("payload installers do not support SELinux policies")
}
@ -400,9 +400,9 @@ func (p *AnacondaInstaller) liveStages() []*osbuild.Stage {
dracutOptions := p.dracutStageOptions()
stages = append(stages, osbuild.NewDracutStage(dracutOptions))
if p.SElinux != "" {
if p.SELinux != "" {
stages = append(stages, osbuild.NewSELinuxStage(&osbuild.SELinuxStageOptions{
FileContexts: fmt.Sprintf("etc/selinux/%s/contexts/files/file_contexts", p.SElinux),
FileContexts: fmt.Sprintf("etc/selinux/%s/contexts/files/file_contexts", p.SELinux),
}))
}

View file

@ -58,6 +58,29 @@ const ( // ISOBoot type enum
Grub2ISOBoot // Boot with grub2 UEFI and grub2 BIOS
)
func (r *ISOBootType) UnmarshalJSON(data []byte) error {
var s string
if err := json.Unmarshal(data, &s); err != nil {
return err
}
switch s {
case "grub2-uefi", "":
*r = Grub2UEFIOnlyISOBoot
case "syslinux":
*r = SyslinuxISOBoot
case "grub2":
*r = Grub2ISOBoot
default:
return fmt.Errorf("unknown ISOBootType: %q", s)
}
return nil
}
func (r *ISOBootType) UnmarshalYAML(unmarshal func(any) error) error {
return common.UnmarshalYAMLviaJSON(r, unmarshal)
}
// An AnacondaInstallerISOTree represents a tree containing the anaconda installer,
// configuration in terms of a kickstart file, as well as an embedded
// payload to be installed, this payload can either be an ostree

View file

@ -85,9 +85,12 @@ type OSCustomizations struct {
MaskedServices []string
DefaultTarget string
// SELinux policy, when set it enables the labeling of the tree with the
// selected profile
SElinux string
// SELinux policy, when set it enables the labeling of the
// tree with the selected profile
SELinux string
// BuildSELinux policy, when set it enables the labeling of
// the *build tree* with the selected profile
BuildSELinux string
SELinuxForceRelabel *bool
@ -169,6 +172,12 @@ type OSCustomizations struct {
// MountUnits creates systemd .mount units to describe the filesystem
// instead of writing to /etc/fstab
MountUnits bool
// VersionlockPackges uses dnf versionlock to lock a package to the version
// that is installed during image build, preventing it from being updated.
// This is only supported for distributions that use dnf4, because osbuild
// only has a stage for dnf4 version locking.
VersionlockPackages []string
}
// OS represents the filesystem tree of the target image. This roughly
@ -253,8 +262,8 @@ func (p *OS) getPackageSetChain(Distro) []rpmmd.PackageSet {
customizationPackages = append(customizationPackages, "chrony")
}
if p.OSCustomizations.SElinux != "" {
customizationPackages = append(customizationPackages, fmt.Sprintf("selinux-policy-%s", p.OSCustomizations.SElinux))
if p.OSCustomizations.SELinux != "" {
customizationPackages = append(customizationPackages, fmt.Sprintf("selinux-policy-%s", p.OSCustomizations.SELinux))
}
if p.OSCustomizations.OpenSCAPRemediationConfig != nil {
@ -290,6 +299,11 @@ func (p *OS) getPackageSetChain(Distro) []rpmmd.PackageSet {
customizationPackages = append(customizationPackages, "firewalld")
}
if len(p.OSCustomizations.VersionlockPackages) > 0 {
// versionlocking packages requires dnf and the dnf plugin
customizationPackages = append(customizationPackages, "dnf", "python3-dnf-plugin-versionlock")
}
osRepos := append(p.repos, p.OSCustomizations.ExtraBaseRepos...)
// merge all package lists for the pipeline
@ -372,8 +386,8 @@ func (p *OS) getBuildPackages(distro Distro) []string {
if p.OSTreeRef != "" {
packages = append(packages, "rpm-ostree")
}
if p.OSCustomizations.SElinux != "" {
packages = append(packages, "policycoreutils", fmt.Sprintf("selinux-policy-%s", p.OSCustomizations.SElinux))
if p.OSCustomizations.SELinux != "" {
packages = append(packages, "policycoreutils", fmt.Sprintf("selinux-policy-%s", p.OSCustomizations.SELinux))
}
if len(p.OSCustomizations.CloudInit) > 0 {
switch distro {
@ -906,15 +920,23 @@ func (p *OS) serialize() osbuild.Pipeline {
pipeline.AddStage(osbuild.NewUpdateCATrustStage())
}
if len(p.OSCustomizations.VersionlockPackages) > 0 {
versionlockStageOptions, err := osbuild.GenDNF4VersionlockStageOptions(p.OSCustomizations.VersionlockPackages, p.packageSpecs)
if err != nil {
panic(err)
}
pipeline.AddStage(osbuild.NewDNF4VersionlockStage(versionlockStageOptions))
}
if p.OSCustomizations.MachineIdUninitialized {
pipeline.AddStage(osbuild.NewMachineIdStage(&osbuild.MachineIdStageOptions{
FirstBoot: osbuild.MachineIdFirstBootYes,
}))
}
if p.OSCustomizations.SElinux != "" {
if p.OSCustomizations.SELinux != "" {
pipeline.AddStage(osbuild.NewSELinuxStage(&osbuild.SELinuxStageOptions{
FileContexts: fmt.Sprintf("etc/selinux/%s/contexts/files/file_contexts", p.OSCustomizations.SElinux),
FileContexts: fmt.Sprintf("etc/selinux/%s/contexts/files/file_contexts", p.OSCustomizations.SELinux),
ForceAutorelabel: p.OSCustomizations.SELinuxForceRelabel,
}))
}
@ -1111,21 +1133,13 @@ func findESPMountpoint(pt *disk.PartitionTable) (string, error) {
//
// [1] https://gitlab.com/kraxel/virt-firmware/-/commit/ca385db4f74a4d542455b9d40c91c8448c7be90c
func maybeAddHMACandDirStage(packages []rpmmd.PackageSpec, espMountpoint, kernelVer string) ([]*osbuild.Stage, error) {
ukiDirectVer, err := rpmmd.GetVerStrFromPackageSpecList(packages, "uki-direct")
ukiDirect, err := rpmmd.GetPackage(packages, "uki-direct")
if err != nil {
// the uki-direct package isn't in the list: no override necessary
return nil, nil
}
// The GetVerStrFromPackageSpecList function returns
// <version>-<release>.<arch>. For the real package version, this doesn't
// appear to cause any issues with the version parser used by
// VersionLessThan. If a mock depsolver is used this can cause issues
// (Malformed version: 0-8.fk1.x86_64). Make sure we only use the <version>
// component to avoid issues.
ukiDirectVer = strings.SplitN(ukiDirectVer, "-", 2)[0]
if common.VersionLessThan(ukiDirectVer, "25.3") {
if common.VersionLessThan(ukiDirect.Version, "25.3") {
// generate hmac file using stage
kernelFilename := fmt.Sprintf("ffffffffffffffffffffffffffffffff-%s.efi", kernelVer)
kernelPath := filepath.Join(espMountpoint, "EFI", "Linux", kernelFilename)

View file

@ -1,17 +1,35 @@
package manifest
import (
"fmt"
"math/rand"
"github.com/osbuild/images/pkg/artifact"
"github.com/osbuild/images/pkg/osbuild"
)
type Vagrant struct {
Base
filename string
filename string
provider osbuild.VagrantProvider
macAddress string
imgPipeline FilePipeline
}
// Create a randomized mac address for each build, but generated with a potentially seeded
// PRNG.
// See: https://github.com/mirror/vbox/blob/b9657cd5351cf17432b664009cc25bb480dc64c1/src/VBox/Main/src-server/HostImpl.cpp#L3258-L3269
// for where this implementation comes from.
func virtualboxMacAddress(prng *rand.Rand) string {
manafacturer := "080027"
serial := make([]byte, 3)
prng.Read(serial)
return fmt.Sprintf("%s%x", manafacturer, serial)
}
func (p Vagrant) Filename() string {
return p.filename
}
@ -20,11 +38,16 @@ func (p *Vagrant) SetFilename(filename string) {
p.filename = filename
}
func NewVagrant(buildPipeline Build, imgPipeline FilePipeline) *Vagrant {
func NewVagrant(buildPipeline Build, imgPipeline FilePipeline, provider osbuild.VagrantProvider, prng *rand.Rand) *Vagrant {
p := &Vagrant{
Base: NewBase("vagrant", buildPipeline),
imgPipeline: imgPipeline,
filename: "image.box",
provider: provider,
// macAddress is only required when the provider is virtualbox, we set it always so we don't have to
// complicate flow in serialize
macAddress: virtualboxMacAddress(prng),
}
if buildPipeline != nil {
@ -39,8 +62,42 @@ func NewVagrant(buildPipeline Build, imgPipeline FilePipeline) *Vagrant {
func (p *Vagrant) serialize() osbuild.Pipeline {
pipeline := p.Base.serialize()
vagrantOptions := osbuild.NewVagrantStageOptions(p.provider)
// For the VirtualBox provider we need to inject the ovf stage as well
if p.provider == osbuild.VagrantProviderVirtualBox {
// TODO: find a way to avoid copying (by having the OVF stage take inputs?) as this can be
// slow and increase disk usage
inputName := "vmdk-tree"
pipeline.AddStage(osbuild.NewCopyStageSimple(
&osbuild.CopyStageOptions{
Paths: []osbuild.CopyStagePath{
{
From: fmt.Sprintf("input://%s/%s", inputName, p.imgPipeline.Export().Filename()),
To: "tree:///",
},
},
},
osbuild.NewPipelineTreeInputs(inputName, p.imgPipeline.Name()),
))
vagrantOptions.SyncedFolders = map[string]*osbuild.VagrantSyncedFolderStageOptions{
"/vagrant": &osbuild.VagrantSyncedFolderStageOptions{
Type: osbuild.VagrantSyncedFolderTypeRsync,
},
}
vagrantOptions.VirtualBox = &osbuild.VagrantVirtualBoxStageOptions{
MacAddress: p.macAddress,
}
pipeline.AddStage(osbuild.NewOVFStage(&osbuild.OVFStageOptions{
Vmdk: p.imgPipeline.Filename(),
}))
}
pipeline.AddStage(osbuild.NewVagrantStage(
osbuild.NewVagrantStageOptions(osbuild.VagrantProviderLibvirt),
vagrantOptions,
osbuild.NewVagrantStagePipelineFilesInputs(p.imgPipeline.Name(), p.imgPipeline.Filename()),
))

View file

@ -44,7 +44,7 @@ func defaultModuleStates() map[string]bool {
anaconda.ModuleLocalization: false,
anaconda.ModuleNetwork: true,
anaconda.ModulePayloads: true,
anaconda.ModuleRuntime: false,
anaconda.ModuleRuntime: true,
anaconda.ModuleSecurity: false,
anaconda.ModuleServices: false,
anaconda.ModuleStorage: true,

View file

@ -0,0 +1,70 @@
package osbuild
import (
"fmt"
"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/pkg/rpmmd"
)
const dnf4VersionlockType = "org.osbuild.dnf4.versionlock"
type DNF4VersionlockOptions struct {
Add []string `json:"add"`
}
func (*DNF4VersionlockOptions) isStageOptions() {}
func (o *DNF4VersionlockOptions) validate() error {
if len(o.Add) == 0 {
return fmt.Errorf("%s: at least one package must be included in the 'add' list", dnf4VersionlockType)
}
return nil
}
func NewDNF4VersionlockStage(options *DNF4VersionlockOptions) *Stage {
if err := options.validate(); err != nil {
panic(err)
}
return &Stage{
Type: dnf4VersionlockType,
Options: options,
}
}
// GenDNF4VersionlockStageOptions creates DNF4VersionlockOptions for the provided
// packages at the specific EVR that is contained in the package spec list.
// Returns an error if:
// - Any of the package names does not appear in the package specs.
// - dnf4 is not in the package specs: we only support the feature in dnf4 for now.
// - The python3-dnf-plugin-versionlock package is not in the package specs:
// the plugin is required for the lock to be effective.
func GenDNF4VersionlockStageOptions(lockPackageNames []string, packageSpecs []rpmmd.PackageSpec) (*DNF4VersionlockOptions, error) {
// check that dnf4 and the plugin are included in the package specs
dnf, err := rpmmd.GetPackage(packageSpecs, "dnf")
if err != nil {
return nil, fmt.Errorf("%s: dnf version locking enabled for an image that does not contain dnf: %w", dnf4VersionlockType, err)
}
if common.VersionGreaterThanOrEqual(dnf.Version, "5") {
return nil, fmt.Errorf("%s: dnf version locking enabled for an image that includes dnf version %s: the feature requires dnf4", dnf4VersionlockType, dnf.Version)
}
if _, err := rpmmd.GetPackage(packageSpecs, "python3-dnf-plugin-versionlock"); err != nil {
return nil, fmt.Errorf("%s: dnf version locking enabled for an image that does not contain the versionlock plugin: %w", dnf4VersionlockType, err)
}
pkgNEVRs := make([]string, len(lockPackageNames))
for idx, pkgName := range lockPackageNames {
pkg, err := rpmmd.GetPackage(packageSpecs, pkgName)
if err != nil {
return nil, fmt.Errorf("%s: package %q not found in package list", dnf4VersionlockType, pkgName)
}
nevr := fmt.Sprintf("%s-%d:%s-%s", pkg.Name, pkg.Epoch, pkg.Version, pkg.Release)
pkgNEVRs[idx] = nevr
}
return &DNF4VersionlockOptions{
Add: pkgNEVRs,
}, nil
}

View file

@ -8,7 +8,17 @@ import (
const vmdkRegex = "^[a-zA-Z0-9+_.-]*$"
type OVFStageOptions struct {
Vmdk string `json:"vmdk"`
Vmdk string `json:"vmdk"`
VMWare *OVFVMWareStageOptions `json:"vmware,omitempty"`
VirtualBox *OVFVirtualBoxStageOptions `json:"virtualbox,omitempty"`
}
type OVFVMWareStageOptions struct {
OSType string `json:"os_type,omitempty"`
}
type OVFVirtualBoxStageOptions struct {
MacAddress string `json:"mac_address"`
}
func (OVFStageOptions) isStageOptions() {}

View file

@ -7,11 +7,28 @@ import (
type VagrantProvider string
const (
VagrantProviderLibvirt VagrantProvider = "libvirt"
VagrantProviderLibvirt VagrantProvider = "libvirt"
VagrantProviderVirtualBox VagrantProvider = "virtualbox"
)
type VagrantSyncedFolderType string
const (
VagrantSyncedFolderTypeRsync = "rsync"
)
type VagrantVirtualBoxStageOptions struct {
MacAddress string `json:"mac_address"`
}
type VagrantSyncedFolderStageOptions struct {
Type VagrantSyncedFolderType `json:"type"`
}
type VagrantStageOptions struct {
Provider VagrantProvider `json:"provider"`
Provider VagrantProvider `json:"provider"`
VirtualBox *VagrantVirtualBoxStageOptions `json:"virtualbox,omitempty"`
SyncedFolders map[string]*VagrantSyncedFolderStageOptions `json:"synced_folders,omitempty"`
}
func (VagrantStageOptions) isStageOptions() {}
@ -41,10 +58,14 @@ func NewVagrantStageOptions(provider VagrantProvider) *VagrantStageOptions {
}
func (o *VagrantStageOptions) validate() error {
if o.Provider != VagrantProviderLibvirt {
if o.Provider != VagrantProviderLibvirt && o.Provider != VagrantProviderVirtualBox {
return fmt.Errorf("unknown provider in vagrant stage options %s", o.Provider)
}
if o.Provider != VagrantProviderVirtualBox && len(o.SyncedFolders) > 0 {
return fmt.Errorf("syncedfolders are only available for the virtualbox provider not for %q", o.Provider)
}
return nil
}

View file

@ -21,6 +21,7 @@ const ( // image format enum
FORMAT_GCE
FORMAT_OVA
FORMAT_VAGRANT_LIBVIRT
FORMAT_VAGRANT_VIRTUALBOX
)
type Bootloader int
@ -81,6 +82,8 @@ func (f ImageFormat) String() string {
return "ova"
case FORMAT_VAGRANT_LIBVIRT:
return "vagrant_libvirt"
case FORMAT_VAGRANT_VIRTUALBOX:
return "vagrant_virtualbox"
default:
panic(fmt.Errorf("unknown image format %d", f))
}
@ -110,6 +113,8 @@ func (f *ImageFormat) UnmarshalJSON(data []byte) error {
*f = FORMAT_OVA
case "vagrant_libvirt":
*f = FORMAT_VAGRANT_LIBVIRT
case "vagrant_virtualbox":
*f = FORMAT_VAGRANT_VIRTUALBOX
default:
panic(fmt.Errorf("unknown image format %q", s))
}

View file

@ -236,13 +236,23 @@ func (ps *PackageSpec) GetNEVRA() string {
return fmt.Sprintf("%s-%s", ps.Name, ps.GetEVRA())
}
func GetVerStrFromPackageSpecList(pkgs []PackageSpec, packageName string) (string, error) {
func GetPackage(pkgs []PackageSpec, packageName string) (PackageSpec, error) {
for _, pkg := range pkgs {
if pkg.Name == packageName {
return fmt.Sprintf("%s-%s.%s", pkg.Version, pkg.Release, pkg.Arch), nil
return pkg, nil
}
}
return "", fmt.Errorf("package %q not found in the PackageSpec list", packageName)
return PackageSpec{}, fmt.Errorf("package %q not found in the PackageSpec list", packageName)
}
func GetVerStrFromPackageSpecList(pkgs []PackageSpec, packageName string) (string, error) {
pkg, err := GetPackage(pkgs, packageName)
if err != nil {
return "", err
}
return pkg.GetEVRA(), nil
}
func GetVerStrFromPackageSpecListPanic(pkgs []PackageSpec, packageName string) string {