From ee7479aee9ceb96d627fbd0842d31e5eee087f3d Mon Sep 17 00:00:00 2001 From: Simon de Vlieger Date: Thu, 14 Dec 2023 15:01:32 +0100 Subject: [PATCH 1/7] iso: be able to build the ISO Adds another type which will build an ISO with the container embedded for Anaconda to do the rest. --- bib/cmd/bootc-image-builder/image.go | 191 +++++++++++++++++++++++++++ bib/cmd/bootc-image-builder/main.go | 5 +- 2 files changed, 195 insertions(+), 1 deletion(-) diff --git a/bib/cmd/bootc-image-builder/image.go b/bib/cmd/bootc-image-builder/image.go index 6a6370b8..34786a0d 100644 --- a/bib/cmd/bootc-image-builder/image.go +++ b/bib/cmd/bootc-image-builder/image.go @@ -55,6 +55,8 @@ func Manifest(c *ManifestConfig) (*manifest.Manifest, error) { fallthrough case "ami": img, err = pipelinesForDiskImage(c, rng) + case "iso": + img, err = pipelinesForISO(c, rng) default: fail(fmt.Sprintf("Manifest(): unsupported image type %q", c.ImgType)) } @@ -154,6 +156,195 @@ func pipelinesForDiskImage(c *ManifestConfig, rng *rand.Rand) (image.ImageKind, return img, nil } +func pipelinesForISO(c *ManifestConfig, rng *rand.Rand) (image.ImageKind, error) { + if c.Imgref == "" { + fail("pipeline: no base image defined") + } + ref := "ostree/1/1/0" + tlsVerify := true + containerSource := container.SourceSpec{ + Source: c.Imgref, + Name: c.Imgref, + TLSVerify: &tlsVerify, + } + + img := image.NewAnacondaContainerInstaller(containerSource, ref) + img.ExtraBasePackages = rpmmd.PackageSet{ + Include: []string{ + "anaconda-dracut", + "atheros-firmware", + "brcmfmac-firmware", + "curl", + "dracut-config-generic", + "dracut-network", + "hostname", + "iwlwifi-dvm-firmware", + "iwlwifi-mvm-firmware", + "kernel", + "linux-firmware", + "less", + "nfs-utils", + "openssh-clients", + "ostree", + "plymouth", + "realtek-firmware", + "rng-tools", + "rpcbind", + "selinux-policy-targeted", + "systemd", + "tar", + "xfsprogs", + "xz", + }, + } + + img.ExtraBasePackages = img.ExtraBasePackages.Append(rpmmd.PackageSet{ + Include: []string{ + "aajohan-comfortaa-fonts", + "abattis-cantarell-fonts", + "alsa-firmware", + "alsa-tools-firmware", + "anaconda", + "anaconda-dracut", + "anaconda-install-env-deps", + "anaconda-widgets", + "atheros-firmware", + "audit", + "bind-utils", + "bitmap-fangsongti-fonts", + "brcmfmac-firmware", + "bzip2", + "cryptsetup", + "curl", + "dbus-x11", + "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", + "gdisk", + "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", + "iwlwifi-dvm-firmware", + "iwlwifi-mvm-firmware", + "jomolhari-fonts", + "kbd", + "kbd-misc", + "kdump-anaconda-addon", + "kernel", + "khmeros-base-fonts", + "less", + "libblockdev-lvm-dbus", + "libibverbs", + "libreport-plugin-bugzilla", + "libreport-plugin-reportuploader", + "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", + "ostree", + "pciutils", + "perl-interpreter", + "pigz", + "plymouth", + "python3-pyatspi", + "rdma-core", + "realtek-firmware", + "rit-meera-new-fonts", + "rng-tools", + "rpcbind", + "rpm-ostree", + "rsync", + "rsyslog", + "selinux-policy-targeted", + "sg3_utils", + "sil-abyssinica-fonts", + "sil-padauk-fonts", + "smartmontools", + "spice-vdagent", + "strace", + "systemd", + "tar", + "tigervnc-server-minimal", + "tigervnc-server-module", + "udisks2", + "udisks2-iscsi", + "usbutils", + "vim-minimal", + "volume_key", + "wget", + "xfsdump", + "xfsprogs", + "xorg-x11-drivers", + "xorg-x11-fonts-misc", + "xorg-x11-server-Xorg", + "xorg-x11-xauth", + "xrdb", + "xz", + }, + }) + img.ISOLabelTempl = "Container-Installer-%s" + + var customizations *blueprint.Customizations + if c.Config != nil && c.Config.Blueprint != nil { + customizations = c.Config.Blueprint.Customizations + } + + img.Users = users.UsersFromBP(customizations.GetUsers()) + img.Groups = users.GroupsFromBP(customizations.GetGroups()) + + switch c.Architecture { + case arch.ARCH_X86_64: + img.Platform = &platform.X86{ + BasePlatform: platform.BasePlatform{ + ImageFormat: platform.FORMAT_ISO, + }, + BIOS: true, + UEFIVendor: "fedora", + } + case arch.ARCH_AARCH64: + img.Platform = &platform.Aarch64{ + BasePlatform: platform.BasePlatform{ + ImageFormat: platform.FORMAT_ISO, + }, + UEFIVendor: "fedora", + } + } + + img.OSName = "default" + img.Filename = "install.iso" + + return img, nil +} + func createRand() *rand.Rand { seed, err := cryptorand.Int(cryptorand.Reader, big.NewInt(math.MaxInt64)) if err != nil { diff --git a/bib/cmd/bootc-image-builder/main.go b/bib/cmd/bootc-image-builder/main.go index 984d9bfc..1db9f1a4 100644 --- a/bib/cmd/bootc-image-builder/main.go +++ b/bib/cmd/bootc-image-builder/main.go @@ -130,6 +130,7 @@ func makeManifest(c *ManifestConfig, cacheRoot string) (manifest.OSBuildManifest return nil, err } } + mf, err := manifest.Serialize(depsolvedSets, containerSpecs, nil) if err != nil { fail(fmt.Sprintf("[ERROR] manifest serialization failed: %s", err.Error())) @@ -200,8 +201,10 @@ func build(cmd *cobra.Command, args []string) { exports = []string{"qcow2"} case "ami": exports = []string{"image"} + case "iso": + exports = []string{"bootiso"} default: - fail(fmt.Sprintf("valid types are 'qcow2', 'ami', not: '%s'", imgType)) + fail(fmt.Sprintf("valid types are 'qcow2', 'ami', 'iso', not: '%s'", imgType)) } manifest_fname := fmt.Sprintf("manifest-%s.json", imgType) From 0d35f67977a7a6ec89c18339345ca1eb1c4b5c6e Mon Sep 17 00:00:00 2001 From: Simon de Vlieger Date: Wed, 10 Jan 2024 13:21:07 +0100 Subject: [PATCH 2/7] bug: tlsverify pointer --- bib/cmd/bootc-image-builder/image.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bib/cmd/bootc-image-builder/image.go b/bib/cmd/bootc-image-builder/image.go index 34786a0d..254a86cc 100644 --- a/bib/cmd/bootc-image-builder/image.go +++ b/bib/cmd/bootc-image-builder/image.go @@ -161,11 +161,10 @@ func pipelinesForISO(c *ManifestConfig, rng *rand.Rand) (image.ImageKind, error) fail("pipeline: no base image defined") } ref := "ostree/1/1/0" - tlsVerify := true containerSource := container.SourceSpec{ Source: c.Imgref, Name: c.Imgref, - TLSVerify: &tlsVerify, + TLSVerify: &c.TLSVerify, } img := image.NewAnacondaContainerInstaller(containerSource, ref) From dd80d32f848214ddcd8682496a41c6310dd1b30e Mon Sep 17 00:00:00 2001 From: Simon de Vlieger Date: Wed, 10 Jan 2024 13:23:09 +0100 Subject: [PATCH 3/7] iso: consolidate package lists There is no need to have them separate. --- bib/cmd/bootc-image-builder/image.go | 36 ++++------------------------ 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/bib/cmd/bootc-image-builder/image.go b/bib/cmd/bootc-image-builder/image.go index 254a86cc..2ba09371 100644 --- a/bib/cmd/bootc-image-builder/image.go +++ b/bib/cmd/bootc-image-builder/image.go @@ -169,35 +169,6 @@ func pipelinesForISO(c *ManifestConfig, rng *rand.Rand) (image.ImageKind, error) img := image.NewAnacondaContainerInstaller(containerSource, ref) img.ExtraBasePackages = rpmmd.PackageSet{ - Include: []string{ - "anaconda-dracut", - "atheros-firmware", - "brcmfmac-firmware", - "curl", - "dracut-config-generic", - "dracut-network", - "hostname", - "iwlwifi-dvm-firmware", - "iwlwifi-mvm-firmware", - "kernel", - "linux-firmware", - "less", - "nfs-utils", - "openssh-clients", - "ostree", - "plymouth", - "realtek-firmware", - "rng-tools", - "rpcbind", - "selinux-policy-targeted", - "systemd", - "tar", - "xfsprogs", - "xz", - }, - } - - img.ExtraBasePackages = img.ExtraBasePackages.Append(rpmmd.PackageSet{ Include: []string{ "aajohan-comfortaa-fonts", "abattis-cantarell-fonts", @@ -260,12 +231,12 @@ func pipelinesForISO(c *ManifestConfig, rng *rand.Rand) (image.ImageKind, error) "lldpad", "lsof", "madan-fonts", - "mtr", "mt-st", + "mtr", "net-tools", "nfs-utils", - "nmap-ncat", "nm-connection-editor", + "nmap-ncat", "nss-tools", "openssh-clients", "openssh-server", @@ -309,7 +280,8 @@ func pipelinesForISO(c *ManifestConfig, rng *rand.Rand) (image.ImageKind, error) "xrdb", "xz", }, - }) + } + img.ISOLabelTempl = "Container-Installer-%s" var customizations *blueprint.Customizations From 70c8edeba2c42146a45c77f9ae05ace4c63dc8d0 Mon Sep 17 00:00:00 2001 From: Simon de Vlieger Date: Wed, 10 Jan 2024 14:57:10 +0100 Subject: [PATCH 4/7] ci: apt update before install --- .github/workflows/tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8d66fc44..c426468c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -67,6 +67,8 @@ jobs: ref: ${{ github.event.pull_request.head.sha }} - name: Setup up python uses: actions/setup-python@v5 + - name: Apt update + run: sudo apt update - name: Install test dependencies run: | sudo apt update From 1fe3f3b9075b8dd349179d5a3163662c24d90c50 Mon Sep 17 00:00:00 2001 From: Simon de Vlieger Date: Wed, 10 Jan 2024 18:11:15 +0100 Subject: [PATCH 5/7] iso: compress squashfs with `zstd` `zstd` compression leads to a faster build. --- bib/cmd/bootc-image-builder/image.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bib/cmd/bootc-image-builder/image.go b/bib/cmd/bootc-image-builder/image.go index 2ba09371..819c2cde 100644 --- a/bib/cmd/bootc-image-builder/image.go +++ b/bib/cmd/bootc-image-builder/image.go @@ -168,6 +168,8 @@ func pipelinesForISO(c *ManifestConfig, rng *rand.Rand) (image.ImageKind, error) } img := image.NewAnacondaContainerInstaller(containerSource, ref) + img.SquashfsCompression = "zstd" + img.ExtraBasePackages = rpmmd.PackageSet{ Include: []string{ "aajohan-comfortaa-fonts", From 3b865eb08a8ee6501f20bd4b886f95e2104fb28b Mon Sep 17 00:00:00 2001 From: Simon de Vlieger Date: Wed, 10 Jan 2024 18:28:48 +0100 Subject: [PATCH 6/7] bib: document `iso` option for `type` --- README.md | 1 + bib/cmd/bootc-image-builder/main.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c80a302a..b09d3f14 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,7 @@ The following image types are currently available via the `--type` argument: |-----------------------|---------------------------------------------------------------------------------------| | `ami` | [Amazon Machine Image](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html) | | `qcow2` **(default)** | [QEMU](https://www.qemu.org/) | +| `iso` | An unattended Anaconda installer that installs to the first disk found. | ## ☁️ Cloud uploaders diff --git a/bib/cmd/bootc-image-builder/main.go b/bib/cmd/bootc-image-builder/main.go index 1db9f1a4..85460095 100644 --- a/bib/cmd/bootc-image-builder/main.go +++ b/bib/cmd/bootc-image-builder/main.go @@ -269,7 +269,7 @@ func main() { buildCmd.Flags().String("store", ".osbuild", "osbuild store for intermediate pipeline trees") buildCmd.Flags().String("rpmmd", "/var/cache/osbuild/rpmmd", "rpm metadata cache directory") buildCmd.Flags().String("config", "", "build config file") - buildCmd.Flags().String("type", "qcow2", "image type to build [qcow2, ami]") + buildCmd.Flags().String("type", "qcow2", "image type to build [qcow2, ami, iso]") buildCmd.Flags().Bool("tls-verify", true, "require HTTPS and verify certificates when contacting registries") buildCmd.Flags().String("aws-region", "", "target region for AWS uploads (only for type=ami)") buildCmd.Flags().String("aws-bucket", "", "target S3 bucket name for intermediate storage when creating AMI (only for type=ami)") From 502b40152db63e6ca9fbaa41ab16505556f0d165 Mon Sep 17 00:00:00 2001 From: Simon de Vlieger Date: Thu, 11 Jan 2024 12:42:52 +0100 Subject: [PATCH 7/7] image: remove `ref` We'll be removing the `ref` from the constructor(s) in `images` at a later point in time as well. --- bib/cmd/bootc-image-builder/image.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bib/cmd/bootc-image-builder/image.go b/bib/cmd/bootc-image-builder/image.go index 819c2cde..e61bef00 100644 --- a/bib/cmd/bootc-image-builder/image.go +++ b/bib/cmd/bootc-image-builder/image.go @@ -160,14 +160,16 @@ func pipelinesForISO(c *ManifestConfig, rng *rand.Rand) (image.ImageKind, error) if c.Imgref == "" { fail("pipeline: no base image defined") } - ref := "ostree/1/1/0" + containerSource := container.SourceSpec{ Source: c.Imgref, Name: c.Imgref, TLSVerify: &c.TLSVerify, } - img := image.NewAnacondaContainerInstaller(containerSource, ref) + // The ref is not needed and will be removed from the ctor later + // in time + img := image.NewAnacondaContainerInstaller(containerSource, "") img.SquashfsCompression = "zstd" img.ExtraBasePackages = rpmmd.PackageSet{