Using basic types as values in the `ImageConfig` structure makes it impossible to distinguish if the empty value for the type was set intentionally or if it is just the value the variable was initialized to. This is very bad especially for `bool` type. While working on unifying `vhd` and `azure-rhui` image types I found out, that some newly added variables in the `ImageConfig` structure were forgotten in the `InheritFrom()` method. This makes it impossible to inherit their values from a parent configuration. This is however required for the unification of `vhd` and `azure-rhui` image types. As described above, it would be impossible to decide whether a `bool` value should be inherited from the parent configuration or not. The only solution is to use a pointer to the type. For consistency, use pointer for all basic types. Adjust distro implementations accordingly.
275 lines
7.2 KiB
Go
275 lines
7.2 KiB
Go
package fedora
|
|
|
|
import (
|
|
"math/rand"
|
|
|
|
"github.com/osbuild/osbuild-composer/internal/blueprint"
|
|
"github.com/osbuild/osbuild-composer/internal/distro"
|
|
"github.com/osbuild/osbuild-composer/internal/image"
|
|
"github.com/osbuild/osbuild-composer/internal/manifest"
|
|
"github.com/osbuild/osbuild-composer/internal/osbuild"
|
|
"github.com/osbuild/osbuild-composer/internal/rpmmd"
|
|
"github.com/osbuild/osbuild-composer/internal/workload"
|
|
)
|
|
|
|
// HELPERS
|
|
|
|
func osCustomizations(
|
|
t *imageType,
|
|
osPackageSet rpmmd.PackageSet,
|
|
c *blueprint.Customizations) manifest.OSCustomizations {
|
|
|
|
imageConfig := t.getDefaultImageConfig()
|
|
|
|
osc := manifest.OSCustomizations{}
|
|
|
|
if t.bootable || t.rpmOstree {
|
|
osc.KernelName = c.GetKernel().Name
|
|
|
|
var kernelOptions []string
|
|
if t.kernelOptions != "" {
|
|
kernelOptions = append(kernelOptions, t.kernelOptions)
|
|
}
|
|
if bpKernel := c.GetKernel(); bpKernel.Append != "" {
|
|
kernelOptions = append(kernelOptions, bpKernel.Append)
|
|
}
|
|
osc.KernelOptionsAppend = kernelOptions
|
|
}
|
|
|
|
osc.ExtraBasePackages = osPackageSet.Include
|
|
osc.ExcludeBasePackages = osPackageSet.Exclude
|
|
osc.ExtraBaseRepos = osPackageSet.Repositories
|
|
|
|
osc.GPGKeyFiles = imageConfig.GPGKeyFiles
|
|
if imageConfig.ExcludeDocs != nil {
|
|
osc.ExcludeDocs = *imageConfig.ExcludeDocs
|
|
}
|
|
|
|
if !t.bootISO {
|
|
// don't put users and groups in the payload of an installer
|
|
// add them via kickstart instead
|
|
osc.Groups = c.GetGroups()
|
|
osc.Users = c.GetUsers()
|
|
}
|
|
|
|
osc.EnabledServices = imageConfig.EnabledServices
|
|
osc.DisabledServices = imageConfig.DisabledServices
|
|
if imageConfig.DefaultTarget != nil {
|
|
osc.DefaultTarget = *imageConfig.DefaultTarget
|
|
}
|
|
|
|
osc.Firewall = c.GetFirewall()
|
|
|
|
language, keyboard := c.GetPrimaryLocale()
|
|
if language != nil {
|
|
osc.Language = *language
|
|
} else if imageConfig.Locale != nil {
|
|
osc.Language = *imageConfig.Locale
|
|
}
|
|
if keyboard != nil {
|
|
osc.Keyboard = keyboard
|
|
} else if imageConfig.Keyboard != nil {
|
|
osc.Keyboard = &imageConfig.Keyboard.Keymap
|
|
}
|
|
|
|
if hostname := c.GetHostname(); hostname != nil {
|
|
osc.Hostname = *hostname
|
|
} else {
|
|
osc.Hostname = "localhost.localdomain"
|
|
}
|
|
|
|
timezone, ntpServers := c.GetTimezoneSettings()
|
|
if timezone != nil {
|
|
osc.Timezone = *timezone
|
|
} else if imageConfig.Timezone != nil {
|
|
osc.Timezone = *imageConfig.Timezone
|
|
}
|
|
|
|
if len(ntpServers) > 0 {
|
|
osc.NTPServers = ntpServers
|
|
} else if imageConfig.TimeSynchronization != nil {
|
|
osc.NTPServers = imageConfig.TimeSynchronization.Timeservers
|
|
}
|
|
|
|
// Relabel the tree, unless the `NoSElinux` flag is explicitly set to `true`
|
|
if imageConfig.NoSElinux == nil || imageConfig.NoSElinux != nil && !*imageConfig.NoSElinux {
|
|
osc.SElinux = "targeted"
|
|
}
|
|
|
|
if oscapConfig := c.GetOpenSCAP(); oscapConfig != nil {
|
|
if t.rpmOstree {
|
|
panic("unexpected oscap options for ostree image type")
|
|
}
|
|
osc.OpenSCAPConfig = osbuild.NewOscapRemediationStageOptions(
|
|
osbuild.OscapConfig{
|
|
Datastream: oscapConfig.DataStream,
|
|
ProfileID: oscapConfig.ProfileID,
|
|
},
|
|
)
|
|
}
|
|
|
|
osc.Grub2Config = imageConfig.Grub2Config
|
|
osc.Sysconfig = imageConfig.Sysconfig
|
|
osc.SystemdLogind = imageConfig.SystemdLogind
|
|
osc.CloudInit = imageConfig.CloudInit
|
|
osc.Modprobe = imageConfig.Modprobe
|
|
osc.DracutConf = imageConfig.DracutConf
|
|
osc.SystemdUnit = imageConfig.SystemdUnit
|
|
osc.Authselect = imageConfig.Authselect
|
|
osc.SELinuxConfig = imageConfig.SELinuxConfig
|
|
osc.Tuned = imageConfig.Tuned
|
|
osc.Tmpfilesd = imageConfig.Tmpfilesd
|
|
osc.PamLimitsConf = imageConfig.PamLimitsConf
|
|
osc.Sysctld = imageConfig.Sysctld
|
|
osc.DNFConfig = imageConfig.DNFConfig
|
|
osc.SshdConfig = imageConfig.SshdConfig
|
|
osc.AuthConfig = imageConfig.Authconfig
|
|
osc.PwQuality = imageConfig.PwQuality
|
|
|
|
return osc
|
|
}
|
|
|
|
// IMAGES
|
|
|
|
func liveImage(workload workload.Workload,
|
|
t *imageType,
|
|
customizations *blueprint.Customizations,
|
|
options distro.ImageOptions,
|
|
packageSets map[string]rpmmd.PackageSet,
|
|
rng *rand.Rand) (image.ImageKind, error) {
|
|
|
|
img := image.NewLiveImage()
|
|
img.Platform = t.platform
|
|
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], customizations)
|
|
img.Environment = t.environment
|
|
img.Workload = workload
|
|
// TODO: move generation into LiveImage
|
|
pt, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
img.PartitionTable = pt
|
|
|
|
img.Filename = t.Filename()
|
|
|
|
return img, nil
|
|
}
|
|
|
|
func containerImage(workload workload.Workload,
|
|
t *imageType,
|
|
c *blueprint.Customizations,
|
|
options distro.ImageOptions,
|
|
packageSets map[string]rpmmd.PackageSet,
|
|
rng *rand.Rand) (image.ImageKind, error) {
|
|
img := image.NewBaseContainer()
|
|
|
|
img.Platform = t.platform
|
|
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], c)
|
|
img.Environment = t.environment
|
|
img.Workload = workload
|
|
|
|
img.Filename = t.Filename()
|
|
|
|
return img, nil
|
|
}
|
|
|
|
func iotCommitImage(workload workload.Workload,
|
|
t *imageType,
|
|
customizations *blueprint.Customizations,
|
|
options distro.ImageOptions,
|
|
packageSets map[string]rpmmd.PackageSet,
|
|
rng *rand.Rand) (image.ImageKind, error) {
|
|
|
|
img := image.NewOSTreeArchive()
|
|
|
|
img.Platform = t.platform
|
|
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], customizations)
|
|
img.Environment = t.environment
|
|
img.Workload = workload
|
|
|
|
var parent *manifest.OSTreeParent
|
|
if options.OSTree.Parent != "" && options.OSTree.URL != "" {
|
|
parent = &manifest.OSTreeParent{
|
|
Checksum: options.OSTree.Parent,
|
|
URL: options.OSTree.URL,
|
|
}
|
|
}
|
|
img.OSTreeParent = manifest.OSTree{
|
|
Parent: parent,
|
|
}
|
|
|
|
img.OSTreeRef = options.OSTree.Ref
|
|
img.OSVersion = t.arch.distro.osVersion
|
|
|
|
img.Filename = t.Filename()
|
|
|
|
return img, nil
|
|
}
|
|
|
|
func iotContainerImage(workload workload.Workload,
|
|
t *imageType,
|
|
customizations *blueprint.Customizations,
|
|
options distro.ImageOptions,
|
|
packageSets map[string]rpmmd.PackageSet,
|
|
rng *rand.Rand) (image.ImageKind, error) {
|
|
|
|
img := image.NewOSTreeContainer()
|
|
|
|
img.Platform = t.platform
|
|
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], customizations)
|
|
img.ContainerLanguage = img.OSCustomizations.Language
|
|
img.Environment = t.environment
|
|
img.Workload = workload
|
|
|
|
var parent *manifest.OSTreeParent
|
|
if options.OSTree.Parent != "" && options.OSTree.URL != "" {
|
|
parent = &manifest.OSTreeParent{
|
|
Checksum: options.OSTree.Parent,
|
|
URL: options.OSTree.URL,
|
|
}
|
|
}
|
|
img.OSTreeParent = manifest.OSTree{
|
|
Parent: parent,
|
|
}
|
|
|
|
img.OSTreeRef = options.OSTree.Ref
|
|
img.OSVersion = t.arch.distro.osVersion
|
|
|
|
img.ExtraContainerPackages = packageSets[containerPkgsKey]
|
|
|
|
img.Filename = t.Filename()
|
|
|
|
return img, nil
|
|
}
|
|
|
|
func iotInstallerImage(workload workload.Workload,
|
|
t *imageType,
|
|
customizations *blueprint.Customizations,
|
|
options distro.ImageOptions,
|
|
packageSets map[string]rpmmd.PackageSet,
|
|
rng *rand.Rand) (image.ImageKind, error) {
|
|
|
|
d := t.arch.distro
|
|
|
|
img := image.NewOSTreeInstaller()
|
|
|
|
img.Platform = t.platform
|
|
img.ExtraBasePackages = packageSets[installerPkgsKey]
|
|
img.Users = customizations.GetUsers()
|
|
img.Groups = customizations.GetGroups()
|
|
|
|
img.ISOLabelTempl = d.isolabelTmpl
|
|
img.Product = d.product
|
|
img.Variant = "IoT"
|
|
img.OSName = "fedora"
|
|
img.OSVersion = d.osVersion
|
|
img.Release = "202010217.n.0" // ???
|
|
|
|
img.OSTreeURL = options.OSTree.URL
|
|
img.OSTreeRef = options.OSTree.Ref
|
|
img.OSTreeCommit = options.OSTree.Parent
|
|
|
|
img.Filename = t.Filename()
|
|
|
|
return img, nil
|
|
}
|