Blame internal/distro/fedora31/distro.go

Packit 63bb0d
package fedora31
Packit 63bb0d
Packit 63bb0d
import (
Packit 63bb0d
	"encoding/json"
Packit 63bb0d
	"errors"
Packit 63bb0d
	"sort"
Packit 63bb0d
Packit 63bb0d
	"github.com/osbuild/osbuild-composer/internal/distro"
Packit 63bb0d
	"github.com/osbuild/osbuild-composer/internal/osbuild"
Packit 63bb0d
Packit 63bb0d
	"github.com/google/uuid"
Packit 63bb0d
Packit 63bb0d
	"github.com/osbuild/osbuild-composer/internal/blueprint"
Packit 63bb0d
	"github.com/osbuild/osbuild-composer/internal/crypt"
Packit 63bb0d
	"github.com/osbuild/osbuild-composer/internal/rpmmd"
Packit 63bb0d
)
Packit 63bb0d
Packit 63bb0d
const name = "fedora-31"
Packit 63bb0d
const modulePlatformID = "platform:f31"
Packit 63bb0d
Packit 63bb0d
type Fedora31 struct {
Packit 63bb0d
	arches        map[string]arch
Packit 63bb0d
	buildPackages []string
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
type imageType struct {
Packit 63bb0d
	arch             *arch
Packit 63bb0d
	name             string
Packit 63bb0d
	filename         string
Packit 63bb0d
	mimeType         string
Packit 63bb0d
	packages         []string
Packit 63bb0d
	excludedPackages []string
Packit 63bb0d
	enabledServices  []string
Packit 63bb0d
	disabledServices []string
Packit 63bb0d
	kernelOptions    string
Packit 63bb0d
	bootable         bool
Packit 63bb0d
	defaultSize      uint64
Packit 63bb0d
	assembler        func(uefi bool, size uint64) *osbuild.Assembler
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
type arch struct {
Packit 63bb0d
	distro             *Fedora31
Packit 63bb0d
	name               string
Packit 63bb0d
	bootloaderPackages []string
Packit 63bb0d
	buildPackages      []string
Packit 63bb0d
	legacy             string
Packit 63bb0d
	uefi               bool
Packit 63bb0d
	imageTypes         map[string]imageType
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (a *arch) Distro() distro.Distro {
Packit 63bb0d
	return a.distro
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (t *imageType) Arch() distro.Arch {
Packit 63bb0d
	return t.arch
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (d *Fedora31) ListArches() []string {
Packit 63bb0d
	archs := make([]string, 0, len(d.arches))
Packit 63bb0d
	for name := range d.arches {
Packit 63bb0d
		archs = append(archs, name)
Packit 63bb0d
	}
Packit 63bb0d
	sort.Strings(archs)
Packit 63bb0d
	return archs
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (d *Fedora31) GetArch(arch string) (distro.Arch, error) {
Packit 63bb0d
	a, exists := d.arches[arch]
Packit 63bb0d
	if !exists {
Packit 63bb0d
		return nil, errors.New("invalid architecture: " + arch)
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	return &a, nil
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (d *Fedora31) setArches(arches ...arch) {
Packit 63bb0d
	d.arches = map[string]arch{}
Packit 63bb0d
	for _, a := range arches {
Packit 63bb0d
		d.arches[a.name] = arch{
Packit 63bb0d
			distro:             d,
Packit 63bb0d
			name:               a.name,
Packit 63bb0d
			bootloaderPackages: a.bootloaderPackages,
Packit 63bb0d
			buildPackages:      a.buildPackages,
Packit 63bb0d
			uefi:               a.uefi,
Packit 63bb0d
			imageTypes:         a.imageTypes,
Packit 63bb0d
		}
Packit 63bb0d
	}
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (a *arch) Name() string {
Packit 63bb0d
	return a.name
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (a *arch) ListImageTypes() []string {
Packit 63bb0d
	formats := make([]string, 0, len(a.imageTypes))
Packit 63bb0d
	for name := range a.imageTypes {
Packit 63bb0d
		formats = append(formats, name)
Packit 63bb0d
	}
Packit 63bb0d
	sort.Strings(formats)
Packit 63bb0d
	return formats
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (a *arch) GetImageType(imageType string) (distro.ImageType, error) {
Packit 63bb0d
	t, exists := a.imageTypes[imageType]
Packit 63bb0d
	if !exists {
Packit 63bb0d
		return nil, errors.New("invalid image type: " + imageType)
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	return &t, nil
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (a *arch) setImageTypes(imageTypes ...imageType) {
Packit 63bb0d
	a.imageTypes = map[string]imageType{}
Packit 63bb0d
	for _, it := range imageTypes {
Packit 63bb0d
		a.imageTypes[it.name] = imageType{
Packit 63bb0d
			arch:             a,
Packit 63bb0d
			name:             it.name,
Packit 63bb0d
			filename:         it.filename,
Packit 63bb0d
			mimeType:         it.mimeType,
Packit 63bb0d
			packages:         it.packages,
Packit 63bb0d
			excludedPackages: it.excludedPackages,
Packit 63bb0d
			enabledServices:  it.enabledServices,
Packit 63bb0d
			disabledServices: it.disabledServices,
Packit 63bb0d
			kernelOptions:    it.kernelOptions,
Packit 63bb0d
			bootable:         it.bootable,
Packit 63bb0d
			defaultSize:      it.defaultSize,
Packit 63bb0d
			assembler:        it.assembler,
Packit 63bb0d
		}
Packit 63bb0d
	}
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (t *imageType) Name() string {
Packit 63bb0d
	return t.name
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (t *imageType) Filename() string {
Packit 63bb0d
	return t.filename
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (t *imageType) MIMEType() string {
Packit 63bb0d
	return t.mimeType
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (t *imageType) Size(size uint64) uint64 {
Packit 63bb0d
	const MegaByte = 1024 * 1024
Packit 63bb0d
	// Microsoft Azure requires vhd images to be rounded up to the nearest MB
Packit 63bb0d
	if t.name == "vhd" && size%MegaByte != 0 {
Packit 63bb0d
		size = (size/MegaByte + 1) * MegaByte
Packit 63bb0d
	}
Packit 63bb0d
	if size == 0 {
Packit 63bb0d
		size = t.defaultSize
Packit 63bb0d
	}
Packit 63bb0d
	return size
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (t *imageType) Packages(bp blueprint.Blueprint) ([]string, []string) {
Packit 63bb0d
	packages := append(t.packages, bp.GetPackages()...)
Packit 63bb0d
	timezone, _ := bp.Customizations.GetTimezoneSettings()
Packit 63bb0d
	if timezone != nil {
Packit 63bb0d
		packages = append(packages, "chrony")
Packit 63bb0d
	}
Packit 63bb0d
	if t.bootable {
Packit 63bb0d
		packages = append(packages, t.arch.bootloaderPackages...)
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	return packages, t.excludedPackages
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (t *imageType) BuildPackages() []string {
Packit 63bb0d
	return append(t.arch.distro.buildPackages, t.arch.buildPackages...)
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (t *imageType) Manifest(c *blueprint.Customizations,
Packit 63bb0d
	options distro.ImageOptions,
Packit 63bb0d
	repos []rpmmd.RepoConfig,
Packit 63bb0d
	packageSpecs,
Packit 63bb0d
	buildPackageSpecs []rpmmd.PackageSpec) (distro.Manifest, error) {
Packit 63bb0d
	pipeline, err := t.pipeline(c, repos, packageSpecs, buildPackageSpecs, options.Size)
Packit 63bb0d
	if err != nil {
Packit 63bb0d
		return distro.Manifest{}, err
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	return json.Marshal(
Packit 63bb0d
		osbuild.Manifest{
Packit 63bb0d
			Sources:  *sources(append(packageSpecs, buildPackageSpecs...)),
Packit 63bb0d
			Pipeline: *pipeline,
Packit 63bb0d
		},
Packit 63bb0d
	)
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func New() *Fedora31 {
Packit 63bb0d
	const GigaByte = 1024 * 1024 * 1024
Packit 63bb0d
Packit 63bb0d
	amiImgType := imageType{
Packit 63bb0d
		name:     "ami",
Packit 63bb0d
		filename: "image.raw",
Packit 63bb0d
		mimeType: "application/octet-stream",
Packit 63bb0d
		packages: []string{
Packit 63bb0d
			"@Core",
Packit 63bb0d
			"chrony",
Packit 63bb0d
			"kernel",
Packit 63bb0d
			"selinux-policy-targeted",
Packit 63bb0d
			"langpacks-en",
Packit 63bb0d
			"libxcrypt-compat",
Packit 63bb0d
			"xfsprogs",
Packit 63bb0d
			"cloud-init",
Packit 63bb0d
			"checkpolicy",
Packit 63bb0d
			"net-tools",
Packit 63bb0d
		},
Packit 63bb0d
		excludedPackages: []string{
Packit 63bb0d
			"dracut-config-rescue",
Packit 63bb0d
		},
Packit 63bb0d
		enabledServices: []string{
Packit 63bb0d
			"cloud-init.service",
Packit 63bb0d
		},
Packit 63bb0d
		kernelOptions: "ro no_timer_check console=ttyS0,115200n8 console=tty1 biosdevname=0 net.ifnames=0 console=ttyS0,115200",
Packit 63bb0d
		bootable:      true,
Packit 63bb0d
		defaultSize:   6 * GigaByte,
Packit 63bb0d
		assembler: func(uefi bool, size uint64) *osbuild.Assembler {
Packit 63bb0d
			return qemuAssembler("raw", "image.raw", uefi, size)
Packit 63bb0d
		},
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	qcow2ImageType := imageType{
Packit 63bb0d
		name:     "qcow2",
Packit 63bb0d
		filename: "disk.qcow2",
Packit 63bb0d
		mimeType: "application/x-qemu-disk",
Packit 63bb0d
		packages: []string{
Packit 63bb0d
			"kernel-core",
Packit 63bb0d
			"@Fedora Cloud Server",
Packit 63bb0d
			"chrony",
Packit 63bb0d
			"polkit",
Packit 63bb0d
			"systemd-udev",
Packit 63bb0d
			"selinux-policy-targeted",
Packit 63bb0d
			"langpacks-en",
Packit 63bb0d
		},
Packit 63bb0d
		excludedPackages: []string{
Packit 63bb0d
			"dracut-config-rescue",
Packit 63bb0d
			"etables",
Packit 63bb0d
			"firewalld",
Packit 63bb0d
			"gobject-introspection",
Packit 63bb0d
			"plymouth",
Packit 63bb0d
		},
Packit 63bb0d
		enabledServices: []string{
Packit 63bb0d
			"cloud-init.service",
Packit 63bb0d
			"cloud-config.service",
Packit 63bb0d
			"cloud-final.service",
Packit 63bb0d
			"cloud-init-local.service",
Packit 63bb0d
		},
Packit 63bb0d
		kernelOptions: "ro biosdevname=0 net.ifnames=0",
Packit 63bb0d
		bootable:      true,
Packit 63bb0d
		defaultSize:   2 * GigaByte,
Packit 63bb0d
		assembler: func(uefi bool, size uint64) *osbuild.Assembler {
Packit 63bb0d
			return qemuAssembler("qcow2", "disk.qcow2", uefi, size)
Packit 63bb0d
		},
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	openstackImgType := imageType{
Packit 63bb0d
		name:     "openstack",
Packit 63bb0d
		filename: "disk.qcow2",
Packit 63bb0d
		mimeType: "application/x-qemu-disk",
Packit 63bb0d
		packages: []string{
Packit 63bb0d
			"@Core",
Packit 63bb0d
			"chrony",
Packit 63bb0d
			"kernel",
Packit 63bb0d
			"selinux-policy-targeted",
Packit 63bb0d
			"spice-vdagent",
Packit 63bb0d
			"qemu-guest-agent",
Packit 63bb0d
			"xen-libs",
Packit 63bb0d
			"langpacks-en",
Packit 63bb0d
			"cloud-init",
Packit 63bb0d
			"libdrm",
Packit 63bb0d
		},
Packit 63bb0d
		excludedPackages: []string{
Packit 63bb0d
			"dracut-config-rescue",
Packit 63bb0d
		},
Packit 63bb0d
		enabledServices: []string{
Packit 63bb0d
			"cloud-init.service",
Packit 63bb0d
			"cloud-config.service",
Packit 63bb0d
			"cloud-final.service",
Packit 63bb0d
			"cloud-init-local.service",
Packit 63bb0d
		},
Packit 63bb0d
		kernelOptions: "ro biosdevname=0 net.ifnames=0",
Packit 63bb0d
		bootable:      true,
Packit 63bb0d
		defaultSize:   2 * GigaByte,
Packit 63bb0d
		assembler: func(uefi bool, size uint64) *osbuild.Assembler {
Packit 63bb0d
			return qemuAssembler("qcow2", "disk.qcow2", uefi, size)
Packit 63bb0d
		},
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	vhdImgType := imageType{
Packit 63bb0d
		name:     "vhd",
Packit 63bb0d
		filename: "disk.vhd",
Packit 63bb0d
		mimeType: "application/x-vhd",
Packit 63bb0d
		packages: []string{
Packit 63bb0d
			"@Core",
Packit 63bb0d
			"chrony",
Packit 63bb0d
			"kernel",
Packit 63bb0d
			"selinux-policy-targeted",
Packit 63bb0d
			"langpacks-en",
Packit 63bb0d
			"net-tools",
Packit 63bb0d
			"ntfsprogs",
Packit 63bb0d
			"WALinuxAgent",
Packit 63bb0d
			"libxcrypt-compat",
Packit 63bb0d
			"initscripts",
Packit 63bb0d
			"glibc-all-langpacks",
Packit 63bb0d
		},
Packit 63bb0d
		excludedPackages: []string{
Packit 63bb0d
			"dracut-config-rescue",
Packit 63bb0d
		},
Packit 63bb0d
		enabledServices: []string{
Packit 63bb0d
			"sshd",
Packit 63bb0d
			"waagent", // needed to run in Azure
Packit 63bb0d
		},
Packit 63bb0d
		disabledServices: []string{
Packit 63bb0d
			"proc-sys-fs-binfmt_misc.mount",
Packit 63bb0d
			"loadmodules.service",
Packit 63bb0d
		},
Packit 63bb0d
		// These kernel parameters are required by Azure documentation
Packit 63bb0d
		kernelOptions: "ro biosdevname=0 rootdelay=300 console=ttyS0 earlyprintk=ttyS0 net.ifnames=0",
Packit 63bb0d
		bootable:      true,
Packit 63bb0d
		defaultSize:   2 * GigaByte,
Packit 63bb0d
		assembler: func(uefi bool, size uint64) *osbuild.Assembler {
Packit 63bb0d
			return qemuAssembler("vpc", "disk.vhd", uefi, size)
Packit 63bb0d
		},
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	vmdkImgType := imageType{
Packit 63bb0d
		name:     "vmdk",
Packit 63bb0d
		filename: "disk.vmdk",
Packit 63bb0d
		mimeType: "application/x-vmdk",
Packit 63bb0d
		packages: []string{
Packit 63bb0d
			"@core",
Packit 63bb0d
			"chrony",
Packit 63bb0d
			"firewalld",
Packit 63bb0d
			"kernel",
Packit 63bb0d
			"langpacks-en",
Packit 63bb0d
			"open-vm-tools",
Packit 63bb0d
			"selinux-policy-targeted",
Packit 63bb0d
		},
Packit 63bb0d
		excludedPackages: []string{
Packit 63bb0d
			"dracut-config-rescue",
Packit 63bb0d
		},
Packit 63bb0d
		kernelOptions: "ro biosdevname=0 net.ifnames=0",
Packit 63bb0d
		bootable:      true,
Packit 63bb0d
		defaultSize:   2 * GigaByte,
Packit 63bb0d
		assembler: func(uefi bool, size uint64) *osbuild.Assembler {
Packit 63bb0d
			return qemuAssembler("vmdk", "disk.vmdk", uefi, size)
Packit 63bb0d
		},
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	r := Fedora31{
Packit 63bb0d
		buildPackages: []string{
Packit 63bb0d
			"dnf",
Packit 63bb0d
			"dosfstools",
Packit 63bb0d
			"e2fsprogs",
Packit 63bb0d
			"policycoreutils",
Packit 63bb0d
			"qemu-img",
Packit 63bb0d
			"systemd",
Packit 63bb0d
			"tar",
Packit 63bb0d
			"xz",
Packit 63bb0d
		},
Packit 63bb0d
	}
Packit 63bb0d
	x8664 := arch{
Packit 63bb0d
		distro: &r,
Packit 63bb0d
		name:   "x86_64",
Packit 63bb0d
		bootloaderPackages: []string{
Packit 63bb0d
			"dracut-config-generic",
Packit 63bb0d
			"grub2-pc",
Packit 63bb0d
		},
Packit 63bb0d
		buildPackages: []string{
Packit 63bb0d
			"grub2-pc",
Packit 63bb0d
		},
Packit 63bb0d
		legacy: "i386-pc",
Packit 63bb0d
	}
Packit 63bb0d
	x8664.setImageTypes(
Packit 63bb0d
		amiImgType,
Packit 63bb0d
		qcow2ImageType,
Packit 63bb0d
		openstackImgType,
Packit 63bb0d
		vhdImgType,
Packit 63bb0d
		vmdkImgType,
Packit 63bb0d
	)
Packit 63bb0d
Packit 63bb0d
	aarch64 := arch{
Packit 63bb0d
		distro: &r,
Packit 63bb0d
		name:   "aarch64",
Packit 63bb0d
		bootloaderPackages: []string{
Packit 63bb0d
			"dracut-config-generic",
Packit 63bb0d
			"efibootmgr",
Packit 63bb0d
			"grub2-efi-aa64",
Packit 63bb0d
			"grub2-tools",
Packit 63bb0d
			"shim-aa64",
Packit 63bb0d
		},
Packit 63bb0d
		uefi: true,
Packit 63bb0d
	}
Packit 63bb0d
	aarch64.setImageTypes(
Packit 63bb0d
		amiImgType,
Packit 63bb0d
		qcow2ImageType,
Packit 63bb0d
		openstackImgType,
Packit 63bb0d
	)
Packit 63bb0d
Packit 63bb0d
	r.setArches(x8664, aarch64)
Packit 63bb0d
Packit 63bb0d
	return &r
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (r *Fedora31) Name() string {
Packit 63bb0d
	return name
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (r *Fedora31) ModulePlatformID() string {
Packit 63bb0d
	return modulePlatformID
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func sources(packages []rpmmd.PackageSpec) *osbuild.Sources {
Packit 63bb0d
	files := &osbuild.FilesSource{
Packit 63bb0d
		URLs: make(map[string]osbuild.FileSource),
Packit 63bb0d
	}
Packit 63bb0d
	for _, pkg := range packages {
Packit 63bb0d
		fileSource := osbuild.FileSource{
Packit 63bb0d
			URL: pkg.RemoteLocation,
Packit 63bb0d
		}
Packit 63bb0d
		files.URLs[pkg.Checksum] = fileSource
Packit 63bb0d
	}
Packit 63bb0d
	return &osbuild.Sources{
Packit 63bb0d
		"org.osbuild.files": files,
Packit 63bb0d
	}
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (t *imageType) pipeline(c *blueprint.Customizations, repos []rpmmd.RepoConfig, packageSpecs, buildPackageSpecs []rpmmd.PackageSpec, size uint64) (*osbuild.Pipeline, error) {
Packit 63bb0d
	p := &osbuild.Pipeline{}
Packit 63bb0d
	p.SetBuild(t.buildPipeline(repos, *t.arch, buildPackageSpecs), "org.osbuild.fedora31")
Packit 63bb0d
Packit 63bb0d
	p.AddStage(osbuild.NewRPMStage(t.rpmStageOptions(repos, packageSpecs)))
Packit 63bb0d
	p.AddStage(osbuild.NewFixBLSStage())
Packit 63bb0d
Packit 63bb0d
	// TODO support setting all languages and install corresponding langpack-* package
Packit 63bb0d
	language, keyboard := c.GetPrimaryLocale()
Packit 63bb0d
Packit 63bb0d
	if language != nil {
Packit 63bb0d
		p.AddStage(osbuild.NewLocaleStage(&osbuild.LocaleStageOptions{*language}))
Packit 63bb0d
	} else {
Packit 63bb0d
		p.AddStage(osbuild.NewLocaleStage(&osbuild.LocaleStageOptions{"en_US"}))
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	if keyboard != nil {
Packit 63bb0d
		p.AddStage(osbuild.NewKeymapStage(&osbuild.KeymapStageOptions{*keyboard}))
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	if hostname := c.GetHostname(); hostname != nil {
Packit 63bb0d
		p.AddStage(osbuild.NewHostnameStage(&osbuild.HostnameStageOptions{*hostname}))
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	timezone, ntpServers := c.GetTimezoneSettings()
Packit 63bb0d
Packit 63bb0d
	if timezone != nil {
Packit 63bb0d
		p.AddStage(osbuild.NewTimezoneStage(&osbuild.TimezoneStageOptions{*timezone}))
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	if len(ntpServers) > 0 {
Packit 63bb0d
		p.AddStage(osbuild.NewChronyStage(&osbuild.ChronyStageOptions{ntpServers}))
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	if groups := c.GetGroups(); len(groups) > 0 {
Packit 63bb0d
		p.AddStage(osbuild.NewGroupsStage(t.groupStageOptions(groups)))
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	if users := c.GetUsers(); len(users) > 0 {
Packit 63bb0d
		options, err := t.userStageOptions(users)
Packit 63bb0d
		if err != nil {
Packit 63bb0d
			return nil, err
Packit 63bb0d
		}
Packit 63bb0d
		p.AddStage(osbuild.NewUsersStage(options))
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	if t.bootable {
Packit 63bb0d
		p.AddStage(osbuild.NewFSTabStage(t.fsTabStageOptions(t.arch.uefi)))
Packit 63bb0d
		p.AddStage(osbuild.NewGRUB2Stage(t.grub2StageOptions(t.kernelOptions, c.GetKernel(), t.arch.uefi)))
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	if services := c.GetServices(); services != nil || t.enabledServices != nil {
Packit 63bb0d
		p.AddStage(osbuild.NewSystemdStage(t.systemdStageOptions(t.enabledServices, t.disabledServices, services)))
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	if firewall := c.GetFirewall(); firewall != nil {
Packit 63bb0d
		p.AddStage(osbuild.NewFirewallStage(t.firewallStageOptions(firewall)))
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	p.AddStage(osbuild.NewSELinuxStage(t.selinuxStageOptions()))
Packit 63bb0d
Packit 63bb0d
	p.Assembler = t.assembler(t.arch.uefi, size)
Packit 63bb0d
Packit 63bb0d
	return p, nil
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (r *imageType) buildPipeline(repos []rpmmd.RepoConfig, arch arch, buildPackageSpecs []rpmmd.PackageSpec) *osbuild.Pipeline {
Packit 63bb0d
	p := &osbuild.Pipeline{}
Packit 63bb0d
	p.AddStage(osbuild.NewRPMStage(r.rpmStageOptions(repos, buildPackageSpecs)))
Packit 63bb0d
	return p
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (r *imageType) rpmStageOptions(repos []rpmmd.RepoConfig, specs []rpmmd.PackageSpec) *osbuild.RPMStageOptions {
Packit 63bb0d
	var gpgKeys []string
Packit 63bb0d
	for _, repo := range repos {
Packit 63bb0d
		if repo.GPGKey == "" {
Packit 63bb0d
			continue
Packit 63bb0d
		}
Packit 63bb0d
		gpgKeys = append(gpgKeys, repo.GPGKey)
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	var packages []osbuild.RPMPackage
Packit 63bb0d
	for _, spec := range specs {
Packit 63bb0d
		pkg := osbuild.RPMPackage{
Packit 63bb0d
			Checksum: spec.Checksum,
Packit 63bb0d
			CheckGPG: spec.CheckGPG,
Packit 63bb0d
		}
Packit 63bb0d
		packages = append(packages, pkg)
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	return &osbuild.RPMStageOptions{
Packit 63bb0d
		GPGKeys:  gpgKeys,
Packit 63bb0d
		Packages: packages,
Packit 63bb0d
	}
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (r *imageType) userStageOptions(users []blueprint.UserCustomization) (*osbuild.UsersStageOptions, error) {
Packit 63bb0d
	options := osbuild.UsersStageOptions{
Packit 63bb0d
		Users: make(map[string]osbuild.UsersStageOptionsUser),
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	for _, c := range users {
Packit 63bb0d
		if c.Password != nil && !crypt.PasswordIsCrypted(*c.Password) {
Packit 63bb0d
			cryptedPassword, err := crypt.CryptSHA512(*c.Password)
Packit 63bb0d
			if err != nil {
Packit 63bb0d
				return nil, err
Packit 63bb0d
			}
Packit 63bb0d
Packit 63bb0d
			c.Password = &cryptedPassword
Packit 63bb0d
		}
Packit 63bb0d
Packit 63bb0d
		user := osbuild.UsersStageOptionsUser{
Packit 63bb0d
			Groups:      c.Groups,
Packit 63bb0d
			Description: c.Description,
Packit 63bb0d
			Home:        c.Home,
Packit 63bb0d
			Shell:       c.Shell,
Packit 63bb0d
			Password:    c.Password,
Packit 63bb0d
			Key:         c.Key,
Packit 63bb0d
		}
Packit 63bb0d
Packit 63bb0d
		user.UID = c.UID
Packit 63bb0d
		user.GID = c.GID
Packit 63bb0d
Packit 63bb0d
		options.Users[c.Name] = user
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	return &options, nil
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (r *imageType) groupStageOptions(groups []blueprint.GroupCustomization) *osbuild.GroupsStageOptions {
Packit 63bb0d
	options := osbuild.GroupsStageOptions{
Packit 63bb0d
		Groups: map[string]osbuild.GroupsStageOptionsGroup{},
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	for _, group := range groups {
Packit 63bb0d
		groupData := osbuild.GroupsStageOptionsGroup{
Packit 63bb0d
			Name: group.Name,
Packit 63bb0d
		}
Packit 63bb0d
		groupData.GID = group.GID
Packit 63bb0d
Packit 63bb0d
		options.Groups[group.Name] = groupData
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	return &options
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (r *imageType) firewallStageOptions(firewall *blueprint.FirewallCustomization) *osbuild.FirewallStageOptions {
Packit 63bb0d
	options := osbuild.FirewallStageOptions{
Packit 63bb0d
		Ports: firewall.Ports,
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	if firewall.Services != nil {
Packit 63bb0d
		options.EnabledServices = firewall.Services.Enabled
Packit 63bb0d
		options.DisabledServices = firewall.Services.Disabled
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	return &options
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (r *imageType) systemdStageOptions(enabledServices, disabledServices []string, s *blueprint.ServicesCustomization) *osbuild.SystemdStageOptions {
Packit 63bb0d
	if s != nil {
Packit 63bb0d
		enabledServices = append(enabledServices, s.Enabled...)
Packit 63bb0d
		disabledServices = append(disabledServices, s.Disabled...)
Packit 63bb0d
	}
Packit 63bb0d
	return &osbuild.SystemdStageOptions{
Packit 63bb0d
		EnabledServices:  enabledServices,
Packit 63bb0d
		DisabledServices: disabledServices,
Packit 63bb0d
	}
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (r *imageType) fsTabStageOptions(uefi bool) *osbuild.FSTabStageOptions {
Packit 63bb0d
	options := osbuild.FSTabStageOptions{}
Packit 63bb0d
	options.AddFilesystem("76a22bf4-f153-4541-b6c7-0332c0dfaeac", "ext4", "/", "defaults", 1, 1)
Packit 63bb0d
	if uefi {
Packit 63bb0d
		options.AddFilesystem("46BB-8120", "vfat", "/boot/efi", "umask=0077,shortname=winnt", 0, 2)
Packit 63bb0d
	}
Packit 63bb0d
	return &options
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (r *imageType) grub2StageOptions(kernelOptions string, kernel *blueprint.KernelCustomization, uefi bool) *osbuild.GRUB2StageOptions {
Packit 63bb0d
	id := uuid.MustParse("76a22bf4-f153-4541-b6c7-0332c0dfaeac")
Packit 63bb0d
Packit 63bb0d
	if kernel != nil {
Packit 63bb0d
		kernelOptions += " " + kernel.Append
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	var uefiOptions *osbuild.GRUB2UEFI
Packit 63bb0d
	if uefi {
Packit 63bb0d
		uefiOptions = &osbuild.GRUB2UEFI{
Packit 63bb0d
			Vendor: "fedora",
Packit 63bb0d
		}
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	var legacy string
Packit 63bb0d
	if !uefi {
Packit 63bb0d
		legacy = r.arch.legacy
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	return &osbuild.GRUB2StageOptions{
Packit 63bb0d
		RootFilesystemUUID: id,
Packit 63bb0d
		KernelOptions:      kernelOptions,
Packit 63bb0d
		Legacy:             legacy,
Packit 63bb0d
		UEFI:               uefiOptions,
Packit 63bb0d
	}
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (r *imageType) selinuxStageOptions() *osbuild.SELinuxStageOptions {
Packit 63bb0d
	return &osbuild.SELinuxStageOptions{
Packit 63bb0d
		FileContexts: "etc/selinux/targeted/contexts/files/file_contexts",
Packit 63bb0d
	}
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func qemuAssembler(format string, filename string, uefi bool, size uint64) *osbuild.Assembler {
Packit 63bb0d
	var options osbuild.QEMUAssemblerOptions
Packit 63bb0d
	if uefi {
Packit 63bb0d
		options = osbuild.QEMUAssemblerOptions{
Packit 63bb0d
			Format:   format,
Packit 63bb0d
			Filename: filename,
Packit 63bb0d
			Size:     size,
Packit 63bb0d
			PTUUID:   "8DFDFF87-C96E-EA48-A3A6-9408F1F6B1EF",
Packit 63bb0d
			PTType:   "gpt",
Packit 63bb0d
			Partitions: []osbuild.QEMUPartition{
Packit 63bb0d
				{
Packit 63bb0d
					Start: 2048,
Packit 63bb0d
					Size:  972800,
Packit 63bb0d
					Type:  "c12a7328-f81f-11d2-ba4b-00a0c93ec93b",
Packit 63bb0d
					UUID:  "02C1E068-1D2F-4DA3-91FD-8DD76A955C9D",
Packit 63bb0d
					Filesystem: &osbuild.QEMUFilesystem{
Packit 63bb0d
						Type:       "vfat",
Packit 63bb0d
						UUID:       "46BB-8120",
Packit 63bb0d
						Label:      "EFI System Partition",
Packit 63bb0d
						Mountpoint: "/boot/efi",
Packit 63bb0d
					},
Packit 63bb0d
				},
Packit 63bb0d
				{
Packit 63bb0d
					Start: 976896,
Packit 63bb0d
					UUID:  "8D760010-FAAE-46D1-9E5B-4A2EAC5030CD",
Packit 63bb0d
					Filesystem: &osbuild.QEMUFilesystem{
Packit 63bb0d
						Type:       "ext4",
Packit 63bb0d
						UUID:       "76a22bf4-f153-4541-b6c7-0332c0dfaeac",
Packit 63bb0d
						Mountpoint: "/",
Packit 63bb0d
					},
Packit 63bb0d
				},
Packit 63bb0d
			},
Packit 63bb0d
		}
Packit 63bb0d
	} else {
Packit 63bb0d
		options = osbuild.QEMUAssemblerOptions{
Packit 63bb0d
			Format:   format,
Packit 63bb0d
			Filename: filename,
Packit 63bb0d
			Size:     size,
Packit 63bb0d
			PTUUID:   "0x14fc63d2",
Packit 63bb0d
			PTType:   "mbr",
Packit 63bb0d
			Partitions: []osbuild.QEMUPartition{
Packit 63bb0d
				{
Packit 63bb0d
					Start:    2048,
Packit 63bb0d
					Bootable: true,
Packit 63bb0d
					Filesystem: &osbuild.QEMUFilesystem{
Packit 63bb0d
						Type:       "ext4",
Packit 63bb0d
						UUID:       "76a22bf4-f153-4541-b6c7-0332c0dfaeac",
Packit 63bb0d
						Mountpoint: "/",
Packit 63bb0d
					},
Packit 63bb0d
				},
Packit 63bb0d
			},
Packit 63bb0d
		}
Packit 63bb0d
	}
Packit 63bb0d
	return osbuild.NewQEMUAssembler(&options)
Packit 63bb0d
}