Update osbuild/images to v0.79.0

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
This commit is contained in:
Tomáš Hozza 2024-08-20 13:56:53 +02:00 committed by Achilleas Koutsou
parent 9fcbcdb5dc
commit 62d8ad4efe
340 changed files with 15526 additions and 2999 deletions

View file

@ -2,6 +2,7 @@ package blueprint
import (
"encoding/json"
"errors"
"fmt"
"github.com/osbuild/images/internal/common"
@ -73,16 +74,15 @@ func (fsc *FilesystemCustomization) UnmarshalJSON(data []byte) error {
// CheckMountpointsPolicy checks if the mountpoints are allowed by the policy
func CheckMountpointsPolicy(mountpoints []FilesystemCustomization, mountpointAllowList *pathpolicy.PathPolicies) error {
invalidMountpoints := []string{}
var errs []error
for _, m := range mountpoints {
err := mountpointAllowList.Check(m.Mountpoint)
if err != nil {
invalidMountpoints = append(invalidMountpoints, m.Mountpoint)
if err := mountpointAllowList.Check(m.Mountpoint); err != nil {
errs = append(errs, err)
}
}
if len(invalidMountpoints) > 0 {
return fmt.Errorf("The following custom mountpoints are not supported %+q", invalidMountpoints)
if len(errs) > 0 {
return fmt.Errorf("The following errors occurred while setting up custom mountpoints:\n%w", errors.Join(errs...))
}
return nil

View file

@ -177,13 +177,13 @@ func (bs *BtrfsSubvolume) GetFSSpec() FSSpec {
}
}
func (bs *BtrfsSubvolume) GetFSTabOptions() FSTabOptions {
func (bs *BtrfsSubvolume) GetFSTabOptions() (FSTabOptions, error) {
if bs == nil {
return FSTabOptions{}
return FSTabOptions{}, nil
}
if bs.Name == "" {
panic(fmt.Errorf("internal error: BtrfsSubvolume.GetFSTabOptions() for %+v called without a name", bs))
return FSTabOptions{}, fmt.Errorf("internal error: BtrfsSubvolume.GetFSTabOptions() for %+v called without a name", bs)
}
ops := fmt.Sprintf("subvol=%s", bs.Name)
if bs.Compress != "" {
@ -196,5 +196,5 @@ func (bs *BtrfsSubvolume) GetFSTabOptions() FSTabOptions {
MntOps: ops,
Freq: 0,
PassNo: 0,
}
}, nil
}

View file

@ -114,7 +114,7 @@ type Mountable interface {
GetFSSpec() FSSpec
// GetFSTabOptions returns options for mounting the entity.
GetFSTabOptions() FSTabOptions
GetFSTabOptions() (FSTabOptions, error)
}
// A MountpointCreator is a container that is able to create new volumes.

View file

@ -76,15 +76,15 @@ func (fs *Filesystem) GetFSSpec() FSSpec {
}
}
func (fs *Filesystem) GetFSTabOptions() FSTabOptions {
func (fs *Filesystem) GetFSTabOptions() (FSTabOptions, error) {
if fs == nil {
return FSTabOptions{}
return FSTabOptions{}, nil
}
return FSTabOptions{
MntOps: fs.FSTabOptions,
Freq: fs.FSTabFreq,
PassNo: fs.FSTabPassNo,
}
}, nil
}
func (fs *Filesystem) GenUUID(rng *rand.Rand) {

View file

@ -773,6 +773,10 @@ func (pt *PartitionTable) ensureBtrfs() error {
return fmt.Errorf("root entity is not mountable: %T, this is a violation of entityPath() contract", rootPath[0])
}
opts, err := rootMountable.GetFSTabOptions()
if err != nil {
return err
}
btrfs := &Btrfs{
Label: "root",
Subvolumes: []BtrfsSubvolume{
@ -780,7 +784,7 @@ func (pt *PartitionTable) ensureBtrfs() error {
Name: "root",
Mountpoint: "/",
Compress: DefaultBtrfsCompression,
ReadOnly: rootMountable.GetFSTabOptions().ReadOnly(),
ReadOnly: opts.ReadOnly(),
},
},
}

View file

@ -1,4 +1,4 @@
package fedora
const VERSION_BRANCHED = "41"
const VERSION_RAWHIDE = "41"
const VERSION_RAWHIDE = "42"

View file

@ -1,6 +1,10 @@
package rhel10
import (
"fmt"
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/distro/rhel"
"github.com/osbuild/images/pkg/rpmmd"
)
@ -24,3 +28,301 @@ func mkTarImgType() *rhel.ImageType {
[]string{"archive"},
)
}
func mkImageInstallerImgType() *rhel.ImageType {
it := rhel.NewImageType(
"image-installer",
"installer.iso",
"application/x-iso9660-image",
map[string]rhel.PackageSetFunc{
rhel.OSPkgsKey: bareMetalPackageSet,
rhel.InstallerPkgsKey: anacondaPackageSet,
},
rhel.ImageInstallerImage,
[]string{"build"},
[]string{"anaconda-tree", "rootfs-image", "efiboot-tree", "os", "bootiso-tree", "bootiso"},
[]string{"bootiso"},
)
it.BootISO = true
it.Bootable = true
it.ISOLabelFn = distroISOLabelFunc
it.DefaultInstallerConfig = &distro.InstallerConfig{
AdditionalDracutModules: []string{
"nvdimm", // non-volatile DIMM firmware (provides nfit, cuse, and nd_e820)
"prefixdevname",
"prefixdevname-tools",
},
AdditionalDrivers: []string{
"ipmi_devintf",
"ipmi_msghandler",
},
}
return it
}
// PACKAGE SETS
func bareMetalPackageSet(t *rhel.ImageType) rpmmd.PackageSet {
ps := rpmmd.PackageSet{
Include: []string{
"@core",
"chrony",
"cockpit-system",
"cockpit-ws",
"dnf-utils",
"dosfstools",
"firewalld",
"iwl1000-firmware",
"iwl100-firmware",
"iwl105-firmware",
"iwl135-firmware",
"iwl2000-firmware",
"iwl2030-firmware",
"iwl3160-firmware",
"iwl5000-firmware",
"iwl5150-firmware",
"iwl6000g2a-firmware",
"iwl6000g2b-firmware",
"iwl6050-firmware",
"iwl7260-firmware",
"lvm2",
"net-tools",
"nfs-utils",
"oddjob",
"oddjob-mkhomedir",
"policycoreutils",
"psmisc",
"python3-jsonschema",
"qemu-guest-agent",
"redhat-release",
"redhat-release-eula",
"rsync",
"tar",
"tcpdump",
"tuned",
},
Exclude: []string{
"dracut-config-rescue",
},
}.Append(distroBuildPackageSet(t))
// Ensure to not pull in subscription-manager on non-RHEL distro
if t.IsRHEL() {
ps = ps.Append(rpmmd.PackageSet{
Include: []string{
"subscription-manager-cockpit",
},
})
}
return ps
}
func installerPackageSet(t *rhel.ImageType) rpmmd.PackageSet {
ps := rpmmd.PackageSet{
Include: []string{
"anaconda-dracut",
"curl",
"dracut-config-generic",
"dracut-network",
"hostname",
"iwl100-firmware",
"iwl1000-firmware",
"iwl105-firmware",
"iwl135-firmware",
"iwl2000-firmware",
"iwl2030-firmware",
"iwl3160-firmware",
"iwl5000-firmware",
"iwl5150-firmware",
"iwl6050-firmware",
"iwl7260-firmware",
"kernel",
"less",
"nfs-utils",
"openssh-clients",
"ostree",
"plymouth",
"prefixdevname",
"rng-tools",
"rpcbind",
"selinux-policy-targeted",
"systemd",
"tar",
"xfsprogs",
"xz",
},
}
ps = ps.Append(rpmmd.PackageSet{
// Extra packages that are required by the dracut stage of all installers.
// These are weak deps of other packages in the list above, but lets be
// explicit about what we need and not rely on the weak deps. Relying
// on hard-dependencies for other modules is OK for now.
//
// TODO: add these dynamically based on the modules enabled by each
// pipeline.
Include: []string{
"mdadm",
"nss-softokn",
},
})
switch t.Arch().Name() {
case arch.ARCH_X86_64.String():
ps = ps.Append(rpmmd.PackageSet{
Include: []string{
"biosdevname",
},
})
}
return ps
}
func anacondaPackageSet(t *rhel.ImageType) rpmmd.PackageSet {
// common installer packages
ps := installerPackageSet(t)
ps = ps.Append(rpmmd.PackageSet{
Include: []string{
"alsa-firmware",
"alsa-tools-firmware",
"anaconda",
"anaconda-dracut",
"anaconda-install-img-deps",
"anaconda-widgets",
"audit",
"bind-utils",
"bzip2",
"cryptsetup",
"curl",
"dbus-x11",
"default-fonts-core-sans",
"default-fonts-other-sans",
"dejavu-sans-fonts",
"dejavu-sans-mono-fonts",
"device-mapper-persistent-data",
"dmidecode",
"dnf",
"dracut-config-generic",
"dracut-network",
"efibootmgr",
"ethtool",
"fcoe-utils",
"ftp",
"gdb-gdbserver",
"glibc-all-langpacks",
"gnome-kiosk",
"google-noto-sans-cjk-ttc-fonts",
"grub2-tools",
"grub2-tools-extra",
"grub2-tools-minimal",
"grubby",
"gsettings-desktop-schemas",
"hdparm",
"hexedit",
"hostname",
"initscripts",
"ipmitool",
"iwl1000-firmware",
"iwl100-firmware",
"iwl105-firmware",
"iwl135-firmware",
"iwl2000-firmware",
"iwl2030-firmware",
"iwl3160-firmware",
"iwl5000-firmware",
"iwl5150-firmware",
"iwl6000g2a-firmware",
"iwl6000g2b-firmware",
"iwl6050-firmware",
"iwl7260-firmware",
"jomolhari-fonts",
"kbd",
"kbd-misc",
"kdump-anaconda-addon",
"kernel",
"less",
"libblockdev-lvm-dbus",
"libibverbs",
"librsvg2",
"linux-firmware",
"lldpad",
"lsof",
"madan-fonts",
"mtr",
"mt-st",
"net-tools",
"nfs-utils",
"nmap-ncat",
"nm-connection-editor",
"nss-tools",
"openssh-clients",
"openssh-server",
// the package is not yet available on c10s / el10
//"oscap-anaconda-addon",
"ostree",
"pciutils",
"perl-interpreter",
"pigz",
"plymouth",
"prefixdevname",
"python3-pyatspi",
"rdma-core",
"redhat-release-eula",
"rng-tools",
"rpcbind",
"rpm-ostree",
"rsync",
"rsyslog",
"selinux-policy-targeted",
"sg3_utils",
"sil-padauk-fonts",
"smartmontools",
"spice-vdagent",
"strace",
"systemd",
"tar",
"udisks2",
"udisks2-iscsi",
"usbutils",
"vim-minimal",
"volume_key",
"wget",
"xfsdump",
"xfsprogs",
"xz",
},
})
ps = ps.Append(anacondaBootPackageSet(t))
switch t.Arch().Name() {
case arch.ARCH_X86_64.String():
ps = ps.Append(rpmmd.PackageSet{
Include: []string{
"biosdevname",
"dmidecode",
"grub2-tools-efi",
"memtest86+",
},
})
case arch.ARCH_AARCH64.String():
ps = ps.Append(rpmmd.PackageSet{
Include: []string{
"dmidecode",
},
})
default:
panic(fmt.Sprintf("unsupported arch: %s", t.Arch().Name()))
}
return ps
}

View file

@ -2,6 +2,7 @@ package rhel10
import (
"fmt"
"strings"
"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/pkg/arch"
@ -36,6 +37,18 @@ var (
}
)
func distroISOLabelFunc(t *rhel.ImageType) string {
const RHEL_ISO_LABEL = "RHEL-%s-%s-0-BaseOS-%s"
const CS_ISO_LABEL = "CentOS-Stream-%s-BaseOS-%s"
if t.IsRHEL() {
osVer := strings.Split(t.Arch().Distro().OsVersion(), ".")
return fmt.Sprintf(RHEL_ISO_LABEL, osVer[0], osVer[1], t.Arch().Name())
} else {
return fmt.Sprintf(CS_ISO_LABEL, t.Arch().Distro().Releasever(), t.Arch().Name())
}
}
func defaultDistroImageConfig(d *rhel.Distribution) *distro.ImageConfig {
return &distro.ImageConfig{
Timezone: common.ToPtr("America/New_York"),
@ -202,6 +215,48 @@ func newDistro(name string, major, minor int) *rhel.Distribution {
aarch64.AddImageTypes(azureAarch64Platform, mkAzureImgType())
}
gceX86Platform := &platform.X86{
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_GCE,
},
}
x86_64.AddImageTypes(
gceX86Platform,
mkGCEImageType(),
)
x86_64.AddImageTypes(
&platform.X86{
BasePlatform: platform.BasePlatform{
FirmwarePackages: []string{
"microcode_ctl", // ??
"iwl1000-firmware",
"iwl100-firmware",
"iwl105-firmware",
"iwl135-firmware",
"iwl2000-firmware",
"iwl2030-firmware",
"iwl3160-firmware",
"iwl5000-firmware",
"iwl5150-firmware",
"iwl6050-firmware",
},
},
BIOS: true,
UEFIVendor: rd.Vendor(),
},
mkImageInstallerImgType(),
)
aarch64.AddImageTypes(
&platform.Aarch64{
BasePlatform: platform.BasePlatform{},
UEFIVendor: rd.Vendor(),
},
mkImageInstallerImgType(),
)
rd.AddArches(x86_64, aarch64, ppc64le, s390x)
return rd
}

View file

@ -0,0 +1,226 @@
package rhel10
import (
"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/distro/rhel"
"github.com/osbuild/images/pkg/osbuild"
"github.com/osbuild/images/pkg/rpmmd"
)
const gceKernelOptions = "biosdevname=0 scsi_mod.use_blk_mq=Y console=ttyS0,38400n8d"
func mkGCEImageType() *rhel.ImageType {
it := rhel.NewImageType(
"gce",
"image.tar.gz",
"application/gzip",
map[string]rhel.PackageSetFunc{
rhel.OSPkgsKey: gcePackageSet,
},
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "archive"},
[]string{"archive"},
)
it.DefaultImageConfig = baseGCEImageConfig()
it.KernelOptions = gceKernelOptions
it.DefaultSize = 20 * common.GibiByte
it.Bootable = true
// TODO: the base partition table still contains the BIOS boot partition, but the image is UEFI-only
it.BasePartitionTables = defaultBasePartitionTables
return it
}
func baseGCEImageConfig() *distro.ImageConfig {
ic := &distro.ImageConfig{
Timezone: common.ToPtr("UTC"),
TimeSynchronization: &osbuild.ChronyStageOptions{
Servers: []osbuild.ChronyConfigServer{{Hostname: "metadata.google.internal"}},
},
Firewall: &osbuild.FirewallStageOptions{
DefaultZone: "trusted",
},
EnabledServices: []string{
"sshd",
"rngd",
"dnf-automatic.timer",
// TODO: remove cloud-init services once we switch back to GCP guest tools
"cloud-init",
"cloud-init-local",
"cloud-config",
"cloud-final",
},
DisabledServices: []string{
"sshd-keygen@",
"reboot.target",
},
DefaultTarget: common.ToPtr("multi-user.target"),
Locale: common.ToPtr("en_US.UTF-8"),
Keyboard: &osbuild.KeymapStageOptions{
Keymap: "us",
},
DNFConfig: []*osbuild.DNFConfigStageOptions{
{
Config: &osbuild.DNFConfig{
Main: &osbuild.DNFConfigMain{
IPResolve: "4",
},
},
},
},
DNFAutomaticConfig: &osbuild.DNFAutomaticConfigStageOptions{
Config: &osbuild.DNFAutomaticConfig{
Commands: &osbuild.DNFAutomaticConfigCommands{
ApplyUpdates: common.ToPtr(true),
UpgradeType: osbuild.DNFAutomaticUpgradeTypeSecurity,
},
},
},
YUMRepos: []*osbuild.YumReposStageOptions{
{
Filename: "google-cloud.repo",
Repos: []osbuild.YumRepository{
{
Id: "google-compute-engine",
Name: "Google Compute Engine",
// TODO: use el10 repo once it's available
BaseURLs: []string{"https://packages.cloud.google.com/yum/repos/google-compute-engine-el9-x86_64-stable"},
Enabled: common.ToPtr(true),
// TODO: enable GPG check once Google stops using SHA-1 in their keys
// https://issuetracker.google.com/issues/360905189
GPGCheck: common.ToPtr(false),
RepoGPGCheck: common.ToPtr(false),
GPGKey: []string{
"https://packages.cloud.google.com/yum/doc/yum-key.gpg",
"https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg",
},
},
},
},
},
SshdConfig: &osbuild.SshdConfigStageOptions{
Config: osbuild.SshdConfigConfig{
PasswordAuthentication: common.ToPtr(false),
ClientAliveInterval: common.ToPtr(420),
PermitRootLogin: osbuild.PermitRootLoginValueNo,
},
},
Sysconfig: []*osbuild.SysconfigStageOptions{
{
Kernel: &osbuild.SysconfigKernelOptions{
DefaultKernel: "kernel-core",
UpdateDefault: true,
},
},
},
Modprobe: []*osbuild.ModprobeStageOptions{
{
Filename: "blacklist-floppy.conf",
Commands: osbuild.ModprobeConfigCmdList{
osbuild.NewModprobeConfigCmdBlacklist("floppy"),
},
},
},
GCPGuestAgentConfig: &osbuild.GcpGuestAgentConfigOptions{
ConfigScope: osbuild.GcpGuestAgentConfigScopeDistro,
Config: &osbuild.GcpGuestAgentConfig{
InstanceSetup: &osbuild.GcpGuestAgentConfigInstanceSetup{
SetBotoConfig: common.ToPtr(false),
},
},
},
}
return ic
}
func gceCommonPackageSet(t *rhel.ImageType) rpmmd.PackageSet {
ps := rpmmd.PackageSet{
Include: []string{
"@core",
"langpacks-en", // not in Google's KS
"acpid",
"dnf-automatic",
"net-tools",
"python3",
"rng-tools",
"tar",
"vim",
// GCE guest tools
// TODO: uncomment once the package is available
// the el9 version depends on libboost_regex.so.1.75.0()(64bit), which is not available on el10
//"google-compute-engine",
"google-osconfig-agent",
"gce-disk-expand",
// cloud-init is a replacement for "google-compute-engine", remove once the package is available
"cloud-init",
// Not explicitly included in GCP kickstart, but present on the image
// for time synchronization
"chrony",
"timedatex",
// EFI
"grub2-tools",
"grub2-tools-minimal",
// Performance tuning
"tuned",
},
Exclude: []string{
"alsa-utils",
"b43-fwcutter",
"dmraid",
"dracut-config-rescue",
"eject",
"gpm",
"irqbalance",
"microcode_ctl",
"smartmontools",
"aic94xx-firmware",
"atmel-firmware",
"b43-openfwwf",
"bfa-firmware",
"ipw2100-firmware",
"ipw2200-firmware",
"ivtv-firmware",
"iwl100-firmware",
"iwl105-firmware",
"iwl135-firmware",
"iwl1000-firmware",
"iwl2000-firmware",
"iwl2030-firmware",
"iwl3160-firmware",
"iwl3945-firmware",
"iwl4965-firmware",
"iwl5000-firmware",
"iwl5150-firmware",
"iwl6000-firmware",
"iwl6000g2a-firmware",
"iwl6050-firmware",
"iwl7260-firmware",
"kernel-firmware",
"libertas-usb8388-firmware",
"ql2100-firmware",
"ql2200-firmware",
"ql23xx-firmware",
"ql2400-firmware",
"ql2500-firmware",
"rt61pci-firmware",
"rt73usb-firmware",
"xorg-x11-drv-ati-firmware",
"zd1211-firmware",
// RHBZ#2075815
"qemu-guest-agent",
},
}.Append(distroSpecificPackageSet(t))
return ps
}
// GCE image
func gcePackageSet(t *rhel.ImageType) rpmmd.PackageSet {
return gceCommonPackageSet(t)
}

View file

@ -3,6 +3,8 @@ package rhel10
// This file defines package sets that are used by more than one image type.
import (
"fmt"
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/distro/rhel"
"github.com/osbuild/images/pkg/rpmmd"
@ -63,6 +65,58 @@ func ppc64leBuildPackageSet(t *rhel.ImageType) rpmmd.PackageSet {
}
}
// installer boot package sets, needed for booting and
// also in the build host
func anacondaBootPackageSet(t *rhel.ImageType) rpmmd.PackageSet {
ps := rpmmd.PackageSet{}
grubCommon := rpmmd.PackageSet{
Include: []string{
"grub2-tools",
"grub2-tools-extra",
"grub2-tools-minimal",
},
}
efiCommon := rpmmd.PackageSet{
Include: []string{
"efibootmgr",
},
}
switch t.Arch().Name() {
case arch.ARCH_X86_64.String():
ps = ps.Append(grubCommon)
ps = ps.Append(efiCommon)
ps = ps.Append(rpmmd.PackageSet{
Include: []string{
"grub2-efi-x64",
"grub2-efi-x64-cdboot",
"grub2-pc",
"grub2-pc-modules",
"shim-x64",
"syslinux",
"syslinux-nonlinux",
},
})
case arch.ARCH_AARCH64.String():
ps = ps.Append(grubCommon)
ps = ps.Append(efiCommon)
ps = ps.Append(rpmmd.PackageSet{
Include: []string{
"grub2-efi-aa64-cdboot",
"grub2-efi-aa64",
"shim-aa64",
},
})
default:
panic(fmt.Sprintf("unsupported arch: %s", t.Arch().Name()))
}
return ps
}
// OS package sets
// packages that are only in some (sub)-distributions

View file

@ -110,7 +110,6 @@ func qcow2CommonPackageSet(t *rhel.ImageType) rpmmd.PackageSet {
"langpacks-*",
"langpacks-en",
"libertas-sd8787-firmware",
"nss",
"plymouth",
"rng-tools",
"udisks2",

View file

@ -106,14 +106,12 @@ func baseGCEImageConfig() *distro.ImageConfig {
Filename: "google-cloud.repo",
Repos: []osbuild.YumRepository{
{
Id: "google-compute-engine",
Name: "Google Compute Engine",
BaseURLs: []string{"https://packages.cloud.google.com/yum/repos/google-compute-engine-el9-x86_64-stable"},
Enabled: common.ToPtr(true),
// TODO: enable GPG check once Google stops using SHA-1 in their keys
// https://issuetracker.google.com/issues/223626963
GPGCheck: common.ToPtr(false),
RepoGPGCheck: common.ToPtr(false),
Id: "google-compute-engine",
Name: "Google Compute Engine",
BaseURLs: []string{"https://packages.cloud.google.com/yum/repos/google-compute-engine-el9-x86_64-stable"},
Enabled: common.ToPtr(true),
GPGCheck: common.ToPtr(true),
RepoGPGCheck: common.ToPtr(true),
GPGKey: []string{
"https://packages.cloud.google.com/yum/doc/yum-key.gpg",
"https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg",

View file

@ -9,6 +9,7 @@ import (
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/manifest"
"github.com/osbuild/images/pkg/ostree"
"github.com/osbuild/images/pkg/policies"
"github.com/osbuild/images/pkg/rpmmd"
)
@ -240,15 +241,9 @@ func (t *TestImageType) Manifest(b *blueprint.Blueprint, options distro.ImageOpt
if b != nil {
mountpoints := b.Customizations.GetFilesystems()
invalidMountpoints := []string{}
for _, m := range mountpoints {
if m.Mountpoint != "/" {
invalidMountpoints = append(invalidMountpoints, m.Mountpoint)
}
}
if len(invalidMountpoints) > 0 {
return nil, nil, fmt.Errorf("The following custom mountpoints are not supported %+q", invalidMountpoints)
err := blueprint.CheckMountpointsPolicy(mountpoints, policies.MountpointPolicies)
if err != nil {
return nil, nil, err
}
bpPkgs = b.GetPackages()

View file

@ -678,7 +678,11 @@ func (p *OS) serialize() osbuild.Pipeline {
pipeline = prependKernelCmdlineStage(pipeline, strings.Join(kernelOptions, " "), pt)
}
pipeline.AddStage(osbuild.NewFSTabStage(osbuild.NewFSTabStageOptions(pt)))
opts, err := osbuild.NewFSTabStageOptions(pt)
if err != nil {
panic(err)
}
pipeline.AddStage(osbuild.NewFSTabStage(opts))
var bootloader *osbuild.Stage
switch p.platform.GetArch() {

View file

@ -330,7 +330,10 @@ func (p *OSTreeDeployment) serialize() osbuild.Pipeline {
configStage.MountOSTree(p.osName, ref, 0)
pipeline.AddStage(configStage)
fstabOptions := osbuild.NewFSTabStageOptions(p.PartitionTable)
fstabOptions, err := osbuild.NewFSTabStageOptions(p.PartitionTable)
if err != nil {
panic(err)
}
fstabStage := osbuild.NewFSTabStage(fstabOptions)
fstabStage.MountOSTree(p.osName, ref, 0)
pipeline.AddStage(fstabStage)

View file

@ -166,7 +166,11 @@ func (p *RawBootcImage) serialize() osbuild.Pipeline {
mounts = append(mounts, *osbuild.NewBindMount("bind-ostree-deployment-to-tree", "mount://", "tree://"))
// we always include the fstab stage
fstabStage := osbuild.NewFSTabStage(osbuild.NewFSTabStageOptions(pt))
fstabOpts, err := osbuild.NewFSTabStageOptions(pt)
if err != nil {
panic(err)
}
fstabStage := osbuild.NewFSTabStage(fstabOpts)
fstabStage.Mounts = mounts
fstabStage.Devices = devices
pipeline.AddStage(fstabStage)

View file

@ -30,7 +30,7 @@ type DracutStageOptions struct {
// Add custom files to the initramfs
// What (keys) to include where (values)
Include map[string]string `json:"include,omitempty"`
Include []map[string]string `json:"include,omitempty"`
// Install the specified files
Install []string `json:"install,omitempty"`

View file

@ -56,11 +56,14 @@ func (options *FSTabStageOptions) AddFilesystem(id string, vfsType string, path
})
}
func NewFSTabStageOptions(pt *disk.PartitionTable) *FSTabStageOptions {
func NewFSTabStageOptions(pt *disk.PartitionTable) (*FSTabStageOptions, error) {
var options FSTabStageOptions
genOption := func(mnt disk.Mountable, path []disk.Entity) error {
fsSpec := mnt.GetFSSpec()
fsOptions := mnt.GetFSTabOptions()
fsOptions, err := mnt.GetFSTabOptions()
if err != nil {
return err
}
options.AddFilesystem(fsSpec.UUID, mnt.GetFSType(), mnt.GetMountpoint(), fsOptions.MntOps, fsOptions.Freq, fsOptions.PassNo)
return nil
}
@ -69,10 +72,14 @@ func NewFSTabStageOptions(pt *disk.PartitionTable) *FSTabStageOptions {
return fmt.Sprintf("%d%s", fs.PassNo, fs.Path)
}
_ = pt.ForEachMountable(genOption) // genOption always returns nil
err := pt.ForEachMountable(genOption)
if err != nil {
return nil, err
}
// sort the entries by PassNo to maintain backward compatibility
sort.Slice(options.FileSystems, func(i, j int) bool {
return key(options.FileSystems[i]) < key(options.FileSystems[j])
})
return &options
return &options, nil
}

View file

@ -10,43 +10,36 @@ type PathPolicy struct {
Exact bool // require and exact match, no subdirs
}
type PathPolicies = PathTrie
type PathPolicies struct {
pathTrie *pathTrie[PathPolicy]
}
// Create a new PathPolicies trie from a map of path to PathPolicy
func NewPathPolicies(entries map[string]PathPolicy) *PathPolicies {
noType := make(map[string]interface{}, len(entries))
for k, v := range entries {
noType[k] = v
return &PathPolicies{
pathTrie: newPathTrieFromMap[PathPolicy](entries),
}
return NewPathTrieFromMap(noType)
}
// Check a given path against the PathPolicies
func (pol *PathPolicies) Check(fsPath string) error {
// Quickly check we have a path and it is absolute
if fsPath == "" || fsPath[0] != '/' {
return fmt.Errorf("path must be absolute")
return fmt.Errorf("path %q must be absolute", fsPath)
}
// ensure that only clean paths are valid
if fsPath != path.Clean(fsPath) {
return fmt.Errorf("path must be canonical")
return fmt.Errorf("path %q must be canonical", fsPath)
}
node, left := pol.Lookup(fsPath)
policy, ok := node.Payload.(PathPolicy)
if !ok {
panic("programming error: invalid path trie payload")
}
node, left := pol.pathTrie.Lookup(fsPath)
policy := node.Payload
// 1) path is explicitly not allowed or
// 2) a subpath was match but an explicit match is required
if policy.Deny || (policy.Exact && len(left) > 0) {
return fmt.Errorf("path '%s ' is not allowed", fsPath)
return fmt.Errorf("path %q is not allowed", fsPath)
}
// exact match or recursive path allowed

View file

@ -16,14 +16,14 @@ func pathTrieSplitPath(path string) []string {
return strings.Split(path, "/")
}
type PathTrie struct {
type pathTrie[T any] struct {
Name []string
Paths []*PathTrie
Payload interface{}
Paths []*pathTrie[T]
Payload T
}
// match checks if the given trie is a prefix of path
func (trie *PathTrie) match(path []string) bool {
func (trie *pathTrie[T]) match(path []string) bool {
if len(trie.Name) > len(path) {
return false
}
@ -37,12 +37,12 @@ func (trie *PathTrie) match(path []string) bool {
return true
}
func (trie *PathTrie) get(path []string) (*PathTrie, []string) {
func (trie *pathTrie[T]) get(path []string) (*pathTrie[T], []string) {
if len(path) < 1 {
panic("programming error: expected root node")
}
var node *PathTrie
var node *pathTrie[T]
for i := range trie.Paths {
if trie.Paths[i].match(path) {
node = trie.Paths[i]
@ -67,11 +67,11 @@ func (trie *PathTrie) get(path []string) (*PathTrie, []string) {
return node.get(path[prefix:])
}
func (trie *PathTrie) add(path []string) *PathTrie {
node := &PathTrie{Name: path}
func (trie *pathTrie[T]) add(path []string) *pathTrie[T] {
node := &pathTrie[T]{Name: path}
if trie.Paths == nil {
trie.Paths = make([]*PathTrie, 0, 1)
trie.Paths = make([]*pathTrie[T], 0, 1)
}
trie.Paths = append(trie.Paths, node)
@ -81,8 +81,8 @@ func (trie *PathTrie) add(path []string) *PathTrie {
// Construct a new trie from a map of paths to their payloads.
// Returns the root node of the trie.
func NewPathTrieFromMap(entries map[string]interface{}) *PathTrie {
root := &PathTrie{Name: []string{}}
func newPathTrieFromMap[T any](entries map[string]T) *pathTrie[T] {
root := &pathTrie[T]{Name: []string{}}
keys := make([]string, 0, len(entries))
for k := range entries {
@ -107,7 +107,7 @@ func NewPathTrieFromMap(entries map[string]interface{}) *PathTrie {
// Lookup returns the node that is the prefix of path and
// the unmatched path segment. Must be called on the root
// trie node.
func (root *PathTrie) Lookup(path string) (*PathTrie, []string) {
func (root *pathTrie[T]) Lookup(path string) (*pathTrie[T], []string) {
if len(root.Name) != 0 {
panic("programming error: lookup on non-root trie node")

View file

@ -4,8 +4,6 @@ import (
"github.com/osbuild/images/pkg/arch"
)
type X86BootLoader uint64
type X86 struct {
BasePlatform
BIOS bool