New image type that generates a Boot ISO. The ISO contains a RHEL Edge commit and an installer. On Boot, it sets up a new RHEL Edge system with the commit. The RHEL Edge commit (ostree commit) is downloaded during build from a URL that should be supplied with the compose request. The commit's hash and URL need to be added to the Sources list in the Manifest. Unlike other types, the new image type defines its own "build" package set that is added to the distro and arch build package lists.
1578 lines
40 KiB
Go
1578 lines
40 KiB
Go
package rhel84
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"math/rand"
|
|
"sort"
|
|
|
|
"github.com/osbuild/osbuild-composer/internal/disk"
|
|
"github.com/osbuild/osbuild-composer/internal/distro"
|
|
osbuild "github.com/osbuild/osbuild-composer/internal/osbuild1"
|
|
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/osbuild/osbuild-composer/internal/blueprint"
|
|
"github.com/osbuild/osbuild-composer/internal/crypt"
|
|
"github.com/osbuild/osbuild-composer/internal/rpmmd"
|
|
)
|
|
|
|
const name = "rhel-84"
|
|
const centosName = "centos-8"
|
|
const modulePlatformID = "platform:el8"
|
|
const ostreeRef = "rhel/8/%s/edge"
|
|
|
|
type distribution struct {
|
|
arches map[string]architecture
|
|
imageTypes map[string]distro.ImageType
|
|
buildPackages []string
|
|
isCentos bool
|
|
}
|
|
|
|
type architecture struct {
|
|
distro *distribution
|
|
name string
|
|
bootloaderPackages []string
|
|
buildPackages []string
|
|
legacy string
|
|
uefi bool
|
|
imageTypes map[string]distro.ImageType
|
|
}
|
|
|
|
type imageType struct {
|
|
arch *architecture
|
|
name string
|
|
filename string
|
|
mimeType string
|
|
packages []string
|
|
excludedPackages []string
|
|
enabledServices []string
|
|
disabledServices []string
|
|
defaultTarget string
|
|
kernelOptions string
|
|
bootable bool
|
|
rpmOstree bool
|
|
defaultSize uint64
|
|
partitionTableGenerator func(imageOptions distro.ImageOptions, arch distro.Arch, rng *rand.Rand) disk.PartitionTable
|
|
assembler func(pt *disk.PartitionTable, options distro.ImageOptions, arch distro.Arch) *osbuild.Assembler
|
|
}
|
|
|
|
func (a *architecture) Distro() distro.Distro {
|
|
return a.distro
|
|
}
|
|
|
|
func (t *imageType) Arch() distro.Arch {
|
|
return t.arch
|
|
}
|
|
|
|
func (d *distribution) ListArches() []string {
|
|
archs := make([]string, 0, len(d.arches))
|
|
for name := range d.arches {
|
|
archs = append(archs, name)
|
|
}
|
|
sort.Strings(archs)
|
|
return archs
|
|
}
|
|
|
|
func (d *distribution) GetArch(arch string) (distro.Arch, error) {
|
|
a, exists := d.arches[arch]
|
|
if !exists {
|
|
return nil, errors.New("invalid architecture: " + arch)
|
|
}
|
|
|
|
return &a, nil
|
|
}
|
|
|
|
func (d *distribution) addArches(arches ...architecture) {
|
|
if d.arches == nil {
|
|
d.arches = map[string]architecture{}
|
|
}
|
|
|
|
for _, a := range arches {
|
|
d.arches[a.name] = architecture{
|
|
distro: d,
|
|
name: a.name,
|
|
bootloaderPackages: a.bootloaderPackages,
|
|
buildPackages: a.buildPackages,
|
|
uefi: a.uefi,
|
|
imageTypes: a.imageTypes,
|
|
}
|
|
}
|
|
}
|
|
|
|
func (a *architecture) Name() string {
|
|
return a.name
|
|
}
|
|
|
|
func (a *architecture) ListImageTypes() []string {
|
|
formats := make([]string, 0, len(a.imageTypes))
|
|
for name := range a.imageTypes {
|
|
formats = append(formats, name)
|
|
}
|
|
sort.Strings(formats)
|
|
return formats
|
|
}
|
|
|
|
func (a *architecture) GetImageType(imageType string) (distro.ImageType, error) {
|
|
t, exists := a.imageTypes[imageType]
|
|
if !exists {
|
|
return nil, errors.New("invalid image type: " + imageType)
|
|
}
|
|
|
|
return t, nil
|
|
}
|
|
|
|
func (a *architecture) addImageTypes(imageTypes ...imageType) {
|
|
if a.imageTypes == nil {
|
|
a.imageTypes = map[string]distro.ImageType{}
|
|
}
|
|
for _, it := range imageTypes {
|
|
a.imageTypes[it.name] = &imageType{
|
|
arch: a,
|
|
name: it.name,
|
|
filename: it.filename,
|
|
mimeType: it.mimeType,
|
|
packages: it.packages,
|
|
excludedPackages: it.excludedPackages,
|
|
enabledServices: it.enabledServices,
|
|
disabledServices: it.disabledServices,
|
|
defaultTarget: it.defaultTarget,
|
|
kernelOptions: it.kernelOptions,
|
|
bootable: it.bootable,
|
|
rpmOstree: it.rpmOstree,
|
|
defaultSize: it.defaultSize,
|
|
partitionTableGenerator: it.partitionTableGenerator,
|
|
assembler: it.assembler,
|
|
}
|
|
}
|
|
}
|
|
|
|
// For the secondary implementation of image type.
|
|
// Temporary; for supporting the new Manifest schema, until everything is
|
|
// ported.
|
|
func (a *architecture) addS2ImageTypes(imageTypes ...imageTypeS2) {
|
|
for _, it := range imageTypes {
|
|
a.imageTypes[it.name] = &imageTypeS2{
|
|
arch: a,
|
|
name: it.name,
|
|
filename: it.filename,
|
|
mimeType: it.mimeType,
|
|
packageSets: it.packageSets,
|
|
enabledServices: it.enabledServices,
|
|
disabledServices: it.disabledServices,
|
|
defaultTarget: it.defaultTarget,
|
|
kernelOptions: it.kernelOptions,
|
|
bootable: it.bootable,
|
|
rpmOstree: it.rpmOstree,
|
|
defaultSize: it.defaultSize,
|
|
bootISO: it.bootISO,
|
|
}
|
|
}
|
|
}
|
|
|
|
func (t *imageType) Name() string {
|
|
return t.name
|
|
}
|
|
|
|
func (t *imageType) Filename() string {
|
|
return t.filename
|
|
}
|
|
|
|
func (t *imageType) MIMEType() string {
|
|
return t.mimeType
|
|
}
|
|
|
|
func (t *imageType) OSTreeRef() string {
|
|
if t.rpmOstree {
|
|
return fmt.Sprintf(ostreeRef, t.arch.name)
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (t *imageType) Size(size uint64) uint64 {
|
|
const MegaByte = 1024 * 1024
|
|
// Microsoft Azure requires vhd images to be rounded up to the nearest MB
|
|
if t.name == "vhd" && size%MegaByte != 0 {
|
|
size = (size/MegaByte + 1) * MegaByte
|
|
}
|
|
if size == 0 {
|
|
size = t.defaultSize
|
|
}
|
|
return size
|
|
}
|
|
|
|
func (t *imageType) Packages(bp blueprint.Blueprint) ([]string, []string) {
|
|
packages := append(t.packages, bp.GetPackages()...)
|
|
timezone, _ := bp.Customizations.GetTimezoneSettings()
|
|
if timezone != nil {
|
|
packages = append(packages, "chrony")
|
|
}
|
|
if t.bootable {
|
|
packages = append(packages, t.arch.bootloaderPackages...)
|
|
}
|
|
|
|
if t.arch.distro.isCentos {
|
|
// drop insights from centos, it's not available there
|
|
packages = removePackage(packages, "insights-client")
|
|
}
|
|
|
|
return packages, t.excludedPackages
|
|
}
|
|
|
|
func (t *imageType) BuildPackages() []string {
|
|
packages := append(t.arch.distro.buildPackages, t.arch.buildPackages...)
|
|
if t.rpmOstree {
|
|
packages = append(packages, "rpm-ostree")
|
|
}
|
|
return packages
|
|
}
|
|
|
|
func (t *imageType) PackageSets(bp blueprint.Blueprint) map[string]rpmmd.PackageSet {
|
|
includePackages, excludePackages := t.Packages(bp)
|
|
return map[string]rpmmd.PackageSet{
|
|
"packages": {
|
|
Include: includePackages,
|
|
Exclude: excludePackages,
|
|
},
|
|
"build-packages": {
|
|
Include: t.BuildPackages(),
|
|
},
|
|
}
|
|
}
|
|
|
|
func (t *imageType) Exports() []string {
|
|
return []string{"assembler"}
|
|
}
|
|
|
|
func (t *imageType) Manifest(c *blueprint.Customizations,
|
|
options distro.ImageOptions,
|
|
repos []rpmmd.RepoConfig,
|
|
packageSpecSets map[string][]rpmmd.PackageSpec,
|
|
seed int64) (distro.Manifest, error) {
|
|
source := rand.NewSource(seed)
|
|
rng := rand.New(source)
|
|
pipeline, err := t.pipeline(c, options, repos, packageSpecSets["packages"], packageSpecSets["build-packages"], rng)
|
|
if err != nil {
|
|
return distro.Manifest{}, err
|
|
}
|
|
|
|
return json.Marshal(
|
|
osbuild.Manifest{
|
|
Sources: *sources(append(packageSpecSets["packages"], packageSpecSets["build-packages"]...)),
|
|
Pipeline: *pipeline,
|
|
},
|
|
)
|
|
}
|
|
|
|
func (d *distribution) Name() string {
|
|
if d.isCentos {
|
|
return centosName
|
|
}
|
|
return name
|
|
}
|
|
|
|
func (d *distribution) ModulePlatformID() string {
|
|
return modulePlatformID
|
|
}
|
|
|
|
func sources(packages []rpmmd.PackageSpec) *osbuild.Sources {
|
|
files := &osbuild.FilesSource{
|
|
URLs: make(map[string]osbuild.FileSource),
|
|
}
|
|
for _, pkg := range packages {
|
|
fileSource := osbuild.FileSource{
|
|
URL: pkg.RemoteLocation,
|
|
}
|
|
if pkg.Secrets == "org.osbuild.rhsm" {
|
|
fileSource.Secrets = &osbuild.Secret{
|
|
Name: "org.osbuild.rhsm",
|
|
}
|
|
}
|
|
files.URLs[pkg.Checksum] = fileSource
|
|
}
|
|
return &osbuild.Sources{
|
|
"org.osbuild.files": files,
|
|
}
|
|
}
|
|
|
|
func (t *imageType) pipeline(c *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSpecs, buildPackageSpecs []rpmmd.PackageSpec, rng *rand.Rand) (*osbuild.Pipeline, error) {
|
|
|
|
if kernelOpts := c.GetKernel(); kernelOpts != nil && kernelOpts.Append != "" && t.rpmOstree {
|
|
return nil, fmt.Errorf("kernel boot parameter customizations are not supported for ostree types")
|
|
}
|
|
|
|
var pt *disk.PartitionTable
|
|
if t.partitionTableGenerator != nil {
|
|
table := t.partitionTableGenerator(options, t.arch, rng)
|
|
pt = &table
|
|
}
|
|
|
|
p := &osbuild.Pipeline{}
|
|
if t.arch.distro.isCentos {
|
|
p.SetBuild(t.buildPipeline(repos, *t.arch, buildPackageSpecs), "org.osbuild.centos8")
|
|
} else {
|
|
p.SetBuild(t.buildPipeline(repos, *t.arch, buildPackageSpecs), "org.osbuild.rhel84")
|
|
}
|
|
|
|
if t.arch.Name() == "s390x" {
|
|
if pt == nil {
|
|
panic("s390x image must have a partition table, this is a programming error")
|
|
}
|
|
|
|
rootPartition := pt.RootPartition()
|
|
if rootPartition == nil {
|
|
panic("s390x image must have a root partition, this is a programming error")
|
|
}
|
|
|
|
p.AddStage(osbuild.NewKernelCmdlineStage(&osbuild.KernelCmdlineStageOptions{
|
|
RootFsUUID: rootPartition.Filesystem.UUID,
|
|
KernelOpts: t.kernelOptions,
|
|
}))
|
|
}
|
|
|
|
p.AddStage(osbuild.NewRPMStage(t.rpmStageOptions(*t.arch, repos, packageSpecs)))
|
|
p.AddStage(osbuild.NewFixBLSStage())
|
|
|
|
if pt != nil {
|
|
p.AddStage(osbuild.NewFSTabStage(pt.FSTabStageOptions()))
|
|
}
|
|
|
|
if t.bootable {
|
|
if t.arch.Name() != "s390x" {
|
|
p.AddStage(osbuild.NewGRUB2Stage(t.grub2StageOptions(pt, t.kernelOptions, c.GetKernel(), packageSpecs, t.arch.uefi, t.arch.legacy)))
|
|
}
|
|
}
|
|
|
|
// TODO support setting all languages and install corresponding langpack-* package
|
|
language, keyboard := c.GetPrimaryLocale()
|
|
|
|
if language != nil {
|
|
p.AddStage(osbuild.NewLocaleStage(&osbuild.LocaleStageOptions{Language: *language}))
|
|
} else {
|
|
p.AddStage(osbuild.NewLocaleStage(&osbuild.LocaleStageOptions{Language: "en_US.UTF-8"}))
|
|
}
|
|
|
|
if keyboard != nil {
|
|
p.AddStage(osbuild.NewKeymapStage(&osbuild.KeymapStageOptions{Keymap: *keyboard}))
|
|
}
|
|
|
|
if hostname := c.GetHostname(); hostname != nil {
|
|
p.AddStage(osbuild.NewHostnameStage(&osbuild.HostnameStageOptions{Hostname: *hostname}))
|
|
}
|
|
|
|
timezone, ntpServers := c.GetTimezoneSettings()
|
|
|
|
if timezone != nil {
|
|
p.AddStage(osbuild.NewTimezoneStage(&osbuild.TimezoneStageOptions{Zone: *timezone}))
|
|
} else {
|
|
p.AddStage(osbuild.NewTimezoneStage(&osbuild.TimezoneStageOptions{Zone: "America/New_York"}))
|
|
}
|
|
|
|
if len(ntpServers) > 0 {
|
|
p.AddStage(osbuild.NewChronyStage(&osbuild.ChronyStageOptions{Timeservers: ntpServers}))
|
|
}
|
|
|
|
if groups := c.GetGroups(); len(groups) > 0 {
|
|
p.AddStage(osbuild.NewGroupsStage(t.groupStageOptions(groups)))
|
|
}
|
|
|
|
if users := c.GetUsers(); len(users) > 0 {
|
|
options, err := t.userStageOptions(users)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
p.AddStage(osbuild.NewUsersStage(options))
|
|
}
|
|
|
|
if services := c.GetServices(); services != nil || t.enabledServices != nil || t.disabledServices != nil || t.defaultTarget != "" {
|
|
p.AddStage(osbuild.NewSystemdStage(t.systemdStageOptions(t.enabledServices, t.disabledServices, services, t.defaultTarget)))
|
|
}
|
|
|
|
if firewall := c.GetFirewall(); firewall != nil {
|
|
p.AddStage(osbuild.NewFirewallStage(t.firewallStageOptions(firewall)))
|
|
}
|
|
|
|
if t.arch.Name() == "s390x" {
|
|
p.AddStage(osbuild.NewZiplStage(&osbuild.ZiplStageOptions{}))
|
|
}
|
|
|
|
p.AddStage(osbuild.NewSELinuxStage(t.selinuxStageOptions()))
|
|
|
|
// These are the current defaults for the sysconfig stage. This can be changed to be image type exclusive if different configs are needed.
|
|
p.AddStage(osbuild.NewSysconfigStage(&osbuild.SysconfigStageOptions{
|
|
Kernel: osbuild.SysconfigKernelOptions{
|
|
UpdateDefault: true,
|
|
DefaultKernel: "kernel",
|
|
},
|
|
Network: osbuild.SysconfigNetworkOptions{
|
|
Networking: true,
|
|
NoZeroConf: true,
|
|
},
|
|
}))
|
|
|
|
if t.rpmOstree {
|
|
p.AddStage(osbuild.NewRPMOSTreeStage(&osbuild.RPMOSTreeStageOptions{
|
|
EtcGroupMembers: []string{
|
|
// NOTE: We may want to make this configurable.
|
|
"wheel", "docker",
|
|
},
|
|
}))
|
|
}
|
|
|
|
if options.Subscription != nil {
|
|
commands := []string{
|
|
fmt.Sprintf("/usr/sbin/subscription-manager register --org=%d --activationkey=%s --serverurl %s --baseurl %s", options.Subscription.Organization, options.Subscription.ActivationKey, options.Subscription.ServerUrl, options.Subscription.BaseUrl),
|
|
}
|
|
if options.Subscription.Insights {
|
|
commands = append(commands, "/usr/bin/insights-client --register")
|
|
}
|
|
|
|
p.AddStage(osbuild.NewFirstBootStage(&osbuild.FirstBootStageOptions{
|
|
Commands: commands,
|
|
WaitForNetwork: true,
|
|
},
|
|
))
|
|
} else {
|
|
// RHSM DNF plugins should be by default disabled on RHEL Guest KVM images
|
|
if t.Name() == "qcow2" {
|
|
p.AddStage(osbuild.NewRHSMStage(&osbuild.RHSMStageOptions{
|
|
DnfPlugins: &osbuild.RHSMStageOptionsDnfPlugins{
|
|
ProductID: &osbuild.RHSMStageOptionsDnfPlugin{
|
|
Enabled: false,
|
|
},
|
|
SubscriptionManager: &osbuild.RHSMStageOptionsDnfPlugin{
|
|
Enabled: false,
|
|
},
|
|
},
|
|
}))
|
|
}
|
|
}
|
|
|
|
p.Assembler = t.assembler(pt, options, t.arch)
|
|
|
|
return p, nil
|
|
}
|
|
|
|
func (t *imageType) buildPipeline(repos []rpmmd.RepoConfig, arch architecture, buildPackageSpecs []rpmmd.PackageSpec) *osbuild.Pipeline {
|
|
p := &osbuild.Pipeline{}
|
|
p.AddStage(osbuild.NewRPMStage(t.rpmStageOptions(arch, repos, buildPackageSpecs)))
|
|
p.AddStage(osbuild.NewSELinuxStage(t.selinuxStageOptions()))
|
|
return p
|
|
}
|
|
|
|
func (t *imageType) rpmStageOptions(arch architecture, repos []rpmmd.RepoConfig, specs []rpmmd.PackageSpec) *osbuild.RPMStageOptions {
|
|
var gpgKeys []string
|
|
for _, repo := range repos {
|
|
if repo.GPGKey == "" {
|
|
continue
|
|
}
|
|
gpgKeys = append(gpgKeys, repo.GPGKey)
|
|
}
|
|
|
|
var packages []osbuild.RPMPackage
|
|
for _, spec := range specs {
|
|
pkg := osbuild.RPMPackage{
|
|
Checksum: spec.Checksum,
|
|
CheckGPG: spec.CheckGPG,
|
|
}
|
|
packages = append(packages, pkg)
|
|
}
|
|
|
|
return &osbuild.RPMStageOptions{
|
|
GPGKeys: gpgKeys,
|
|
Packages: packages,
|
|
}
|
|
}
|
|
|
|
func (t *imageType) userStageOptions(users []blueprint.UserCustomization) (*osbuild.UsersStageOptions, error) {
|
|
options := osbuild.UsersStageOptions{
|
|
Users: make(map[string]osbuild.UsersStageOptionsUser),
|
|
}
|
|
|
|
for _, c := range users {
|
|
if c.Password != nil && !crypt.PasswordIsCrypted(*c.Password) {
|
|
cryptedPassword, err := crypt.CryptSHA512(*c.Password)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
c.Password = &cryptedPassword
|
|
}
|
|
|
|
user := osbuild.UsersStageOptionsUser{
|
|
Groups: c.Groups,
|
|
Description: c.Description,
|
|
Home: c.Home,
|
|
Shell: c.Shell,
|
|
Password: c.Password,
|
|
Key: c.Key,
|
|
}
|
|
|
|
user.UID = c.UID
|
|
user.GID = c.GID
|
|
|
|
options.Users[c.Name] = user
|
|
}
|
|
|
|
return &options, nil
|
|
}
|
|
|
|
func (t *imageType) groupStageOptions(groups []blueprint.GroupCustomization) *osbuild.GroupsStageOptions {
|
|
options := osbuild.GroupsStageOptions{
|
|
Groups: map[string]osbuild.GroupsStageOptionsGroup{},
|
|
}
|
|
|
|
for _, group := range groups {
|
|
groupData := osbuild.GroupsStageOptionsGroup{
|
|
Name: group.Name,
|
|
}
|
|
groupData.GID = group.GID
|
|
|
|
options.Groups[group.Name] = groupData
|
|
}
|
|
|
|
return &options
|
|
}
|
|
|
|
func (t *imageType) firewallStageOptions(firewall *blueprint.FirewallCustomization) *osbuild.FirewallStageOptions {
|
|
options := osbuild.FirewallStageOptions{
|
|
Ports: firewall.Ports,
|
|
}
|
|
|
|
if firewall.Services != nil {
|
|
options.EnabledServices = firewall.Services.Enabled
|
|
options.DisabledServices = firewall.Services.Disabled
|
|
}
|
|
|
|
return &options
|
|
}
|
|
|
|
func (t *imageType) systemdStageOptions(enabledServices, disabledServices []string, s *blueprint.ServicesCustomization, target string) *osbuild.SystemdStageOptions {
|
|
if s != nil {
|
|
enabledServices = append(enabledServices, s.Enabled...)
|
|
disabledServices = append(disabledServices, s.Disabled...)
|
|
}
|
|
return &osbuild.SystemdStageOptions{
|
|
EnabledServices: enabledServices,
|
|
DisabledServices: disabledServices,
|
|
DefaultTarget: target,
|
|
}
|
|
}
|
|
|
|
func (t *imageType) grub2StageOptions(pt *disk.PartitionTable, kernelOptions string, kernel *blueprint.KernelCustomization, packages []rpmmd.PackageSpec, uefi bool, legacy string) *osbuild.GRUB2StageOptions {
|
|
if pt == nil {
|
|
panic("partition table must be defined for grub2 stage, this is a programming error")
|
|
}
|
|
rootPartition := pt.RootPartition()
|
|
if rootPartition == nil {
|
|
panic("root partition must be defined for grub2 stage, this is a programming error")
|
|
}
|
|
|
|
stageOptions := osbuild.GRUB2StageOptions{
|
|
RootFilesystemUUID: uuid.MustParse(rootPartition.Filesystem.UUID),
|
|
KernelOptions: kernelOptions,
|
|
Legacy: legacy,
|
|
}
|
|
|
|
if uefi {
|
|
var vendor string
|
|
if t.arch.distro.isCentos {
|
|
vendor = "centos"
|
|
} else {
|
|
vendor = "redhat"
|
|
}
|
|
stageOptions.UEFI = &osbuild.GRUB2UEFI{
|
|
Vendor: vendor,
|
|
}
|
|
}
|
|
|
|
if !uefi {
|
|
stageOptions.Legacy = t.arch.legacy
|
|
}
|
|
|
|
if kernel != nil {
|
|
if kernel.Append != "" {
|
|
stageOptions.KernelOptions += " " + kernel.Append
|
|
}
|
|
for _, pkg := range packages {
|
|
if pkg.Name == kernel.Name {
|
|
stageOptions.SavedEntry = "ffffffffffffffffffffffffffffffff-" + pkg.Version + "-" + pkg.Release + "." + pkg.Arch
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
return &stageOptions
|
|
}
|
|
|
|
func (t *imageType) selinuxStageOptions() *osbuild.SELinuxStageOptions {
|
|
return &osbuild.SELinuxStageOptions{
|
|
FileContexts: "etc/selinux/targeted/contexts/files/file_contexts",
|
|
}
|
|
}
|
|
|
|
func defaultPartitionTable(imageOptions distro.ImageOptions, arch distro.Arch, rng *rand.Rand) disk.PartitionTable {
|
|
if arch.Name() == "x86_64" {
|
|
return disk.PartitionTable{
|
|
Size: imageOptions.Size,
|
|
UUID: "D209C89E-EA5E-4FBD-B161-B461CCE297E0",
|
|
Type: "gpt",
|
|
Partitions: []disk.Partition{
|
|
{
|
|
Bootable: true,
|
|
Size: 2048,
|
|
Start: 2048,
|
|
Type: "21686148-6449-6E6F-744E-656564454649",
|
|
UUID: "FAC7F1FB-3E8D-4137-A512-961DE09A5549",
|
|
},
|
|
{
|
|
Start: 4096,
|
|
Size: 204800,
|
|
Type: "C12A7328-F81F-11D2-BA4B-00A0C93EC93B",
|
|
UUID: "68B2905B-DF3E-4FB3-80FA-49D1E773AA33",
|
|
Filesystem: &disk.Filesystem{
|
|
Type: "vfat",
|
|
UUID: "7B77-95E7",
|
|
Mountpoint: "/boot/efi",
|
|
FSTabOptions: "defaults,uid=0,gid=0,umask=077,shortname=winnt",
|
|
FSTabFreq: 0,
|
|
FSTabPassNo: 2,
|
|
},
|
|
},
|
|
{
|
|
Start: 208896,
|
|
Type: "0FC63DAF-8483-4772-8E79-3D69D8477DE4",
|
|
UUID: "6264D520-3FB9-423F-8AB8-7A0A8E3D3562",
|
|
Filesystem: &disk.Filesystem{
|
|
Type: "xfs",
|
|
UUID: uuid.Must(newRandomUUIDFromReader(rng)).String(),
|
|
Label: "root",
|
|
Mountpoint: "/",
|
|
FSTabOptions: "defaults",
|
|
FSTabFreq: 0,
|
|
FSTabPassNo: 0,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
} else if arch.Name() == "aarch64" {
|
|
return disk.PartitionTable{
|
|
Size: imageOptions.Size,
|
|
UUID: "D209C89E-EA5E-4FBD-B161-B461CCE297E0",
|
|
Type: "gpt",
|
|
Partitions: []disk.Partition{
|
|
{
|
|
Start: 2048,
|
|
Size: 204800,
|
|
Type: "C12A7328-F81F-11D2-BA4B-00A0C93EC93B",
|
|
UUID: "68B2905B-DF3E-4FB3-80FA-49D1E773AA33",
|
|
Filesystem: &disk.Filesystem{
|
|
Type: "vfat",
|
|
UUID: "7B77-95E7",
|
|
Mountpoint: "/boot/efi",
|
|
FSTabOptions: "defaults,uid=0,gid=0,umask=077,shortname=winnt",
|
|
FSTabFreq: 0,
|
|
FSTabPassNo: 2,
|
|
},
|
|
},
|
|
{
|
|
Start: 206848,
|
|
Type: "0FC63DAF-8483-4772-8E79-3D69D8477DE4",
|
|
UUID: "6264D520-3FB9-423F-8AB8-7A0A8E3D3562",
|
|
Filesystem: &disk.Filesystem{
|
|
Type: "xfs",
|
|
UUID: uuid.Must(newRandomUUIDFromReader(rng)).String(),
|
|
Label: "root",
|
|
Mountpoint: "/",
|
|
FSTabOptions: "defaults",
|
|
FSTabFreq: 0,
|
|
FSTabPassNo: 0,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
} else if arch.Name() == "ppc64le" {
|
|
return disk.PartitionTable{
|
|
Size: imageOptions.Size,
|
|
UUID: "0x14fc63d2",
|
|
Type: "dos",
|
|
Partitions: []disk.Partition{
|
|
{
|
|
Size: 8192,
|
|
Type: "41",
|
|
Bootable: true,
|
|
},
|
|
{
|
|
Start: 10240,
|
|
Filesystem: &disk.Filesystem{
|
|
Type: "xfs",
|
|
UUID: uuid.Must(newRandomUUIDFromReader(rng)).String(),
|
|
Mountpoint: "/",
|
|
FSTabOptions: "defaults",
|
|
FSTabFreq: 0,
|
|
FSTabPassNo: 0,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
} else if arch.Name() == "s390x" {
|
|
return disk.PartitionTable{
|
|
Size: imageOptions.Size,
|
|
UUID: "0x14fc63d2",
|
|
Type: "dos",
|
|
Partitions: []disk.Partition{
|
|
{
|
|
Start: 2048,
|
|
Bootable: true,
|
|
Filesystem: &disk.Filesystem{
|
|
Type: "xfs",
|
|
UUID: uuid.Must(newRandomUUIDFromReader(rng)).String(),
|
|
Mountpoint: "/",
|
|
FSTabOptions: "defaults",
|
|
FSTabFreq: 0,
|
|
FSTabPassNo: 0,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
panic("unknown arch: " + arch.Name())
|
|
}
|
|
|
|
func qemuAssembler(pt *disk.PartitionTable, format string, filename string, imageOptions distro.ImageOptions, arch distro.Arch) *osbuild.Assembler {
|
|
options := pt.QEMUAssemblerOptions()
|
|
|
|
options.Format = format
|
|
options.Filename = filename
|
|
|
|
if arch.Name() == "x86_64" {
|
|
options.Bootloader = &osbuild.QEMUBootloader{
|
|
Type: "grub2",
|
|
}
|
|
} else if arch.Name() == "ppc64le" {
|
|
options.Bootloader = &osbuild.QEMUBootloader{
|
|
Type: "grub2",
|
|
Platform: "powerpc-ieee1275",
|
|
}
|
|
} else if arch.Name() == "s390x" {
|
|
options.Bootloader = &osbuild.QEMUBootloader{
|
|
Type: "zipl",
|
|
}
|
|
}
|
|
return osbuild.NewQEMUAssembler(&options)
|
|
}
|
|
|
|
func tarAssembler(filename, compression string) *osbuild.Assembler {
|
|
return osbuild.NewTarAssembler(
|
|
&osbuild.TarAssemblerOptions{
|
|
Filename: filename,
|
|
Compression: compression,
|
|
})
|
|
}
|
|
|
|
func ostreeCommitAssembler(options distro.ImageOptions, arch distro.Arch) *osbuild.Assembler {
|
|
return osbuild.NewOSTreeCommitAssembler(
|
|
&osbuild.OSTreeCommitAssemblerOptions{
|
|
Ref: options.OSTree.Ref,
|
|
Parent: options.OSTree.Parent,
|
|
Tar: osbuild.OSTreeCommitAssemblerTarOptions{
|
|
Filename: "commit.tar",
|
|
},
|
|
},
|
|
)
|
|
}
|
|
|
|
func newRandomUUIDFromReader(r io.Reader) (uuid.UUID, error) {
|
|
var id uuid.UUID
|
|
_, err := io.ReadFull(r, id[:])
|
|
if err != nil {
|
|
return uuid.Nil, err
|
|
}
|
|
id[6] = (id[6] & 0x0f) | 0x40 // Version 4
|
|
id[8] = (id[8] & 0x3f) | 0x80 // Variant is 10
|
|
return id, nil
|
|
}
|
|
|
|
func removePackage(packages []string, packageToRemove string) []string {
|
|
for i, pkg := range packages {
|
|
if pkg == packageToRemove {
|
|
// override the package with the last one from the list
|
|
packages[i] = packages[len(packages)-1]
|
|
|
|
// drop the last package from the slice
|
|
return packages[:len(packages)-1]
|
|
}
|
|
}
|
|
return packages
|
|
}
|
|
|
|
// New creates a new distro object, defining the supported architectures and image types
|
|
func New() distro.Distro {
|
|
return newDistro(false)
|
|
}
|
|
|
|
func NewCentos() distro.Distro {
|
|
return newDistro(true)
|
|
}
|
|
|
|
func newDistro(isCentos bool) distro.Distro {
|
|
const GigaByte = 1024 * 1024 * 1024
|
|
|
|
edgeImgTypeX86_64 := imageType{
|
|
name: "rhel-edge-commit",
|
|
filename: "commit.tar",
|
|
mimeType: "application/x-tar",
|
|
packages: []string{
|
|
"redhat-release", // TODO: is this correct for Edge?
|
|
"glibc", "glibc-minimal-langpack", "nss-altfiles",
|
|
"dracut-config-generic", "dracut-network",
|
|
"basesystem", "bash", "platform-python",
|
|
"shadow-utils", "chrony", "setup", "shadow-utils",
|
|
"sudo", "systemd", "coreutils", "util-linux",
|
|
"curl", "vim-minimal",
|
|
"rpm", "rpm-ostree", "polkit",
|
|
"lvm2", "cryptsetup", "pinentry",
|
|
"e2fsprogs", "dosfstools",
|
|
"keyutils", "gnupg2",
|
|
"attr", "xz", "gzip",
|
|
"firewalld", "iptables",
|
|
"NetworkManager", "NetworkManager-wifi", "NetworkManager-wwan",
|
|
"wpa_supplicant",
|
|
"dnsmasq", "traceroute",
|
|
"hostname", "iproute", "iputils",
|
|
"openssh-clients", "procps-ng", "rootfiles",
|
|
"openssh-server", "passwd",
|
|
"policycoreutils", "policycoreutils-python-utils",
|
|
"selinux-policy-targeted", "setools-console",
|
|
"less", "tar", "rsync",
|
|
"fwupd", "usbguard",
|
|
"bash-completion", "tmux",
|
|
"ima-evm-utils",
|
|
"audit",
|
|
"podman", "container-selinux", "skopeo", "criu",
|
|
"slirp4netns", "fuse-overlayfs",
|
|
"clevis", "clevis-dracut", "clevis-luks",
|
|
"greenboot", "greenboot-grub2", "greenboot-rpm-ostree-grub2", "greenboot-reboot", "greenboot-status",
|
|
// x86 specific
|
|
"grub2", "grub2-efi-x64", "efibootmgr", "shim-x64", "microcode_ctl",
|
|
"iwl1000-firmware", "iwl100-firmware", "iwl105-firmware", "iwl135-firmware",
|
|
"iwl2000-firmware", "iwl2030-firmware", "iwl3160-firmware", "iwl5000-firmware",
|
|
"iwl5150-firmware", "iwl6000-firmware", "iwl6050-firmware", "iwl7260-firmware",
|
|
},
|
|
excludedPackages: []string{
|
|
"rng-tools",
|
|
},
|
|
enabledServices: []string{
|
|
"NetworkManager.service", "firewalld.service", "sshd.service",
|
|
"greenboot-grub2-set-counter", "greenboot-grub2-set-success", "greenboot-healthcheck",
|
|
"greenboot-rpm-ostree-grub2-check-fallback", "greenboot-status", "greenboot-task-runner",
|
|
"redboot-auto-reboot", "redboot-task-runner",
|
|
},
|
|
rpmOstree: true,
|
|
assembler: func(pt *disk.PartitionTable, options distro.ImageOptions, arch distro.Arch) *osbuild.Assembler {
|
|
return ostreeCommitAssembler(options, arch)
|
|
},
|
|
}
|
|
edgeImgTypeAarch64 := imageType{
|
|
name: "rhel-edge-commit",
|
|
filename: "commit.tar",
|
|
mimeType: "application/x-tar",
|
|
packages: []string{
|
|
"redhat-release", // TODO: is this correct for Edge?
|
|
"glibc", "glibc-minimal-langpack", "nss-altfiles",
|
|
"dracut-config-generic", "dracut-network",
|
|
"basesystem", "bash", "platform-python",
|
|
"shadow-utils", "chrony", "setup", "shadow-utils",
|
|
"sudo", "systemd", "coreutils", "util-linux",
|
|
"curl", "vim-minimal",
|
|
"rpm", "rpm-ostree", "polkit",
|
|
"lvm2", "cryptsetup", "pinentry",
|
|
"e2fsprogs", "dosfstools",
|
|
"keyutils", "gnupg2",
|
|
"attr", "xz", "gzip",
|
|
"firewalld", "iptables",
|
|
"NetworkManager", "NetworkManager-wifi", "NetworkManager-wwan",
|
|
"wpa_supplicant",
|
|
"dnsmasq", "traceroute",
|
|
"hostname", "iproute", "iputils",
|
|
"openssh-clients", "procps-ng", "rootfiles",
|
|
"openssh-server", "passwd",
|
|
"policycoreutils", "policycoreutils-python-utils",
|
|
"selinux-policy-targeted", "setools-console",
|
|
"less", "tar", "rsync",
|
|
"fwupd", "usbguard",
|
|
"bash-completion", "tmux",
|
|
"ima-evm-utils",
|
|
"audit",
|
|
"podman", "container-selinux", "skopeo", "criu",
|
|
"slirp4netns", "fuse-overlayfs",
|
|
"clevis", "clevis-dracut", "clevis-luks",
|
|
"greenboot", "greenboot-grub2", "greenboot-rpm-ostree-grub2", "greenboot-reboot", "greenboot-status",
|
|
// aarch64 specific
|
|
"grub2-efi-aa64", "efibootmgr", "shim-aa64",
|
|
"iwl7260-firmware",
|
|
},
|
|
excludedPackages: []string{
|
|
"rng-tools",
|
|
},
|
|
enabledServices: []string{
|
|
"NetworkManager.service", "firewalld.service", "sshd.service",
|
|
"greenboot-grub2-set-counter", "greenboot-grub2-set-success", "greenboot-healthcheck",
|
|
"greenboot-rpm-ostree-grub2-check-fallback", "greenboot-status", "greenboot-task-runner",
|
|
"redboot-auto-reboot", "redboot-task-runner",
|
|
},
|
|
rpmOstree: true,
|
|
assembler: func(pt *disk.PartitionTable, options distro.ImageOptions, arch distro.Arch) *osbuild.Assembler {
|
|
return ostreeCommitAssembler(options, arch)
|
|
},
|
|
}
|
|
amiImgType := imageType{
|
|
name: "ami",
|
|
filename: "image.raw",
|
|
mimeType: "application/octet-stream",
|
|
packages: []string{
|
|
"checkpolicy",
|
|
"chrony",
|
|
"cloud-init",
|
|
"cloud-init",
|
|
"cloud-utils-growpart",
|
|
"@core",
|
|
"dhcp-client",
|
|
"gdisk",
|
|
"insights-client",
|
|
"langpacks-en",
|
|
"net-tools",
|
|
"NetworkManager",
|
|
"redhat-release",
|
|
"redhat-release-eula",
|
|
"rsync",
|
|
"selinux-policy-targeted",
|
|
"tar",
|
|
"yum-utils",
|
|
|
|
// TODO this doesn't exist in BaseOS or AppStream
|
|
// "rh-amazon-rhui-client",
|
|
},
|
|
excludedPackages: []string{
|
|
"aic94xx-firmware",
|
|
"alsa-firmware",
|
|
"alsa-lib",
|
|
"alsa-tools-firmware",
|
|
"biosdevname",
|
|
"dracut-config-rescue",
|
|
"firewalld",
|
|
"iprutils",
|
|
"ivtv-firmware",
|
|
"iwl1000-firmware",
|
|
"iwl100-firmware",
|
|
"iwl105-firmware",
|
|
"iwl135-firmware",
|
|
"iwl2000-firmware",
|
|
"iwl2030-firmware",
|
|
"iwl3160-firmware",
|
|
"iwl3945-firmware",
|
|
"iwl4965-firmware",
|
|
"iwl5000-firmware",
|
|
"iwl5150-firmware",
|
|
"iwl6000-firmware",
|
|
"iwl6000g2a-firmware",
|
|
"iwl6000g2b-firmware",
|
|
"iwl6050-firmware",
|
|
"iwl7260-firmware",
|
|
"libertas-sd8686-firmware",
|
|
"libertas-sd8787-firmware",
|
|
"libertas-usb8388-firmware",
|
|
"plymouth",
|
|
"rng-tools",
|
|
|
|
// TODO this cannot be removed, because the kernel (?)
|
|
// depends on it. The ec2 kickstart force-removes it.
|
|
// "linux-firmware",
|
|
|
|
// TODO setfiles failes because of usr/sbin/timedatex. Exlude until
|
|
// https://errata.devel.redhat.com/advisory/47339 lands
|
|
"timedatex",
|
|
},
|
|
defaultTarget: "multi-user.target",
|
|
kernelOptions: "console=ttyS0,115200n8 console=tty0 net.ifnames=0 rd.blacklist=nouveau nvme_core.io_timeout=4294967295 crashkernel=auto",
|
|
bootable: true,
|
|
defaultSize: 6 * GigaByte,
|
|
partitionTableGenerator: defaultPartitionTable,
|
|
assembler: func(pt *disk.PartitionTable, options distro.ImageOptions, arch distro.Arch) *osbuild.Assembler {
|
|
return qemuAssembler(pt, "raw", "image.raw", options, arch)
|
|
},
|
|
}
|
|
|
|
qcow2ImageType := imageType{
|
|
name: "qcow2",
|
|
filename: "disk.qcow2",
|
|
mimeType: "application/x-qemu-disk",
|
|
packages: []string{
|
|
"@core",
|
|
"authselect-compat",
|
|
"chrony",
|
|
"cloud-init",
|
|
"cloud-utils-growpart",
|
|
"cockpit-system",
|
|
"cockpit-ws",
|
|
"dhcp-client",
|
|
"dnf",
|
|
"dnf-utils",
|
|
"dosfstools",
|
|
"dracut-norescue",
|
|
"insights-client",
|
|
"NetworkManager",
|
|
"net-tools",
|
|
"nfs-utils",
|
|
"oddjob",
|
|
"oddjob-mkhomedir",
|
|
"psmisc",
|
|
"python3-jsonschema",
|
|
"qemu-guest-agent",
|
|
"redhat-release",
|
|
"redhat-release-eula",
|
|
"rsync",
|
|
"subscription-manager-cockpit",
|
|
"tar",
|
|
"tcpdump",
|
|
"yum",
|
|
},
|
|
excludedPackages: []string{
|
|
"aic94xx-firmware",
|
|
"alsa-firmware",
|
|
"alsa-lib",
|
|
"alsa-tools-firmware",
|
|
"biosdevname",
|
|
"dnf-plugin-spacewalk",
|
|
"dracut-config-rescue",
|
|
"fedora-release",
|
|
"fedora-repos",
|
|
"firewalld",
|
|
"fwupd",
|
|
"iprutils",
|
|
"ivtv-firmware",
|
|
"iwl100-firmware",
|
|
"iwl1000-firmware",
|
|
"iwl105-firmware",
|
|
"iwl135-firmware",
|
|
"iwl2000-firmware",
|
|
"iwl2030-firmware",
|
|
"iwl3160-firmware",
|
|
"iwl3945-firmware",
|
|
"iwl4965-firmware",
|
|
"iwl5000-firmware",
|
|
"iwl5150-firmware",
|
|
"iwl6000-firmware",
|
|
"iwl6000g2a-firmware",
|
|
"iwl6000g2b-firmware",
|
|
"iwl6050-firmware",
|
|
"iwl7260-firmware",
|
|
"langpacks-*",
|
|
"langpacks-en",
|
|
"langpacks-en",
|
|
"libertas-sd8686-firmware",
|
|
"libertas-sd8787-firmware",
|
|
"libertas-usb8388-firmware",
|
|
"nss",
|
|
"plymouth",
|
|
"rng-tools",
|
|
"udisks2",
|
|
},
|
|
defaultTarget: "multi-user.target",
|
|
kernelOptions: "console=tty0 console=ttyS0,115200n8 no_timer_check net.ifnames=0 crashkernel=auto",
|
|
bootable: true,
|
|
defaultSize: 10 * GigaByte,
|
|
partitionTableGenerator: defaultPartitionTable,
|
|
assembler: func(pt *disk.PartitionTable, options distro.ImageOptions, arch distro.Arch) *osbuild.Assembler {
|
|
return qemuAssembler(pt, "qcow2", "disk.qcow2", options, arch)
|
|
},
|
|
}
|
|
|
|
openstackImgType := imageType{
|
|
name: "openstack",
|
|
filename: "disk.qcow2",
|
|
mimeType: "application/x-qemu-disk",
|
|
packages: []string{
|
|
// Defaults
|
|
"@Core",
|
|
"langpacks-en",
|
|
|
|
// From the lorax kickstart
|
|
"selinux-policy-targeted",
|
|
"cloud-init",
|
|
"qemu-guest-agent",
|
|
"spice-vdagent",
|
|
},
|
|
excludedPackages: []string{
|
|
"dracut-config-rescue",
|
|
"rng-tools",
|
|
},
|
|
kernelOptions: "ro net.ifnames=0",
|
|
bootable: true,
|
|
defaultSize: 4 * GigaByte,
|
|
partitionTableGenerator: defaultPartitionTable,
|
|
assembler: func(pt *disk.PartitionTable, options distro.ImageOptions, arch distro.Arch) *osbuild.Assembler {
|
|
return qemuAssembler(pt, "qcow2", "disk.qcow2", options, arch)
|
|
},
|
|
}
|
|
|
|
tarImgType := imageType{
|
|
name: "tar",
|
|
filename: "root.tar.xz",
|
|
mimeType: "application/x-tar",
|
|
packages: []string{
|
|
"policycoreutils",
|
|
"selinux-policy-targeted",
|
|
},
|
|
excludedPackages: []string{
|
|
"rng-tools",
|
|
},
|
|
bootable: false,
|
|
kernelOptions: "ro net.ifnames=0",
|
|
assembler: func(pt *disk.PartitionTable, options distro.ImageOptions, arch distro.Arch) *osbuild.Assembler {
|
|
return tarAssembler("root.tar.xz", "xz")
|
|
},
|
|
}
|
|
|
|
vhdImgType := imageType{
|
|
name: "vhd",
|
|
filename: "disk.vhd",
|
|
mimeType: "application/x-vhd",
|
|
packages: []string{
|
|
// Defaults
|
|
"@Core",
|
|
"langpacks-en",
|
|
|
|
// From the lorax kickstart
|
|
"selinux-policy-targeted",
|
|
"chrony",
|
|
"WALinuxAgent",
|
|
"python3",
|
|
"net-tools",
|
|
"cloud-init",
|
|
"cloud-utils-growpart",
|
|
"gdisk",
|
|
},
|
|
excludedPackages: []string{
|
|
"dracut-config-rescue",
|
|
"rng-tools",
|
|
|
|
// TODO setfiles failes because of usr/sbin/timedatex. Exlude until
|
|
// https://errata.devel.redhat.com/advisory/47339 lands
|
|
"timedatex",
|
|
},
|
|
enabledServices: []string{
|
|
"sshd",
|
|
"waagent",
|
|
},
|
|
defaultTarget: "multi-user.target",
|
|
kernelOptions: "ro biosdevname=0 rootdelay=300 console=ttyS0 earlyprintk=ttyS0 net.ifnames=0",
|
|
bootable: true,
|
|
defaultSize: 4 * GigaByte,
|
|
partitionTableGenerator: defaultPartitionTable,
|
|
assembler: func(pt *disk.PartitionTable, options distro.ImageOptions, arch distro.Arch) *osbuild.Assembler {
|
|
return qemuAssembler(pt, "vpc", "disk.vhd", options, arch)
|
|
},
|
|
}
|
|
|
|
vmdkImgType := imageType{
|
|
name: "vmdk",
|
|
filename: "disk.vmdk",
|
|
mimeType: "application/x-vmdk",
|
|
packages: []string{
|
|
"@core",
|
|
"chrony",
|
|
"firewalld",
|
|
"langpacks-en",
|
|
"open-vm-tools",
|
|
"selinux-policy-targeted",
|
|
},
|
|
excludedPackages: []string{
|
|
"dracut-config-rescue",
|
|
"rng-tools",
|
|
|
|
// TODO setfiles failes because of usr/sbin/timedatex. Exlude until
|
|
// https://errata.devel.redhat.com/advisory/47339 lands
|
|
"timedatex",
|
|
},
|
|
kernelOptions: "ro net.ifnames=0",
|
|
bootable: true,
|
|
defaultSize: 4 * GigaByte,
|
|
partitionTableGenerator: defaultPartitionTable,
|
|
assembler: func(pt *disk.PartitionTable, options distro.ImageOptions, arch distro.Arch) *osbuild.Assembler {
|
|
return qemuAssembler(pt, "vmdk", "disk.vmdk", options, arch)
|
|
},
|
|
}
|
|
|
|
r := distribution{
|
|
imageTypes: map[string]distro.ImageType{},
|
|
buildPackages: []string{
|
|
"dnf",
|
|
"dosfstools",
|
|
"e2fsprogs",
|
|
"glibc",
|
|
"policycoreutils",
|
|
"python36",
|
|
"python3-iniparse", // dependency of org.osbuild.rhsm stage
|
|
"qemu-img",
|
|
"selinux-policy-targeted",
|
|
"systemd",
|
|
"tar",
|
|
"xfsprogs",
|
|
"xz",
|
|
},
|
|
isCentos: isCentos,
|
|
}
|
|
x8664 := architecture{
|
|
distro: &r,
|
|
name: "x86_64",
|
|
bootloaderPackages: []string{
|
|
"dracut-config-generic",
|
|
"grub2-pc",
|
|
"grub2-efi-x64",
|
|
"shim-x64",
|
|
},
|
|
buildPackages: []string{
|
|
"grub2-pc",
|
|
},
|
|
legacy: "i386-pc",
|
|
uefi: true,
|
|
}
|
|
|
|
edgeOCIImgTypeX86_64 := imageTypeS2{
|
|
name: "rhel-edge-container",
|
|
filename: "rhel84-container.tar",
|
|
mimeType: "application/x-tar",
|
|
packageSets: map[string]rpmmd.PackageSet{
|
|
"packages": {
|
|
Include: edgeImgTypeX86_64.packages,
|
|
Exclude: edgeImgTypeX86_64.excludedPackages,
|
|
},
|
|
"container": {Include: []string{"httpd"}},
|
|
},
|
|
enabledServices: edgeImgTypeX86_64.enabledServices,
|
|
rpmOstree: true,
|
|
bootISO: false,
|
|
}
|
|
|
|
edgeBuildPkgs := []string{
|
|
"dnf",
|
|
"dosfstools",
|
|
"e2fsprogs",
|
|
"grub2-pc",
|
|
"policycoreutils",
|
|
"python36",
|
|
"python3-iniparse",
|
|
"qemu-img",
|
|
"rpm-ostree",
|
|
"systemd",
|
|
"tar",
|
|
"xfsprogs",
|
|
"xz",
|
|
"selinux-policy-targeted",
|
|
"genisoimage",
|
|
"isomd5sum",
|
|
"xorriso",
|
|
"syslinux",
|
|
"lorax-templates-generic",
|
|
"lorax-templates-rhel",
|
|
"syslinux-nonlinux",
|
|
"squashfs-tools",
|
|
"grub2-pc-modules",
|
|
"grub2-tools",
|
|
"grub2-efi-x64",
|
|
"shim-x64",
|
|
"efibootmgr",
|
|
"grub2-tools-minimal",
|
|
"grub2-tools-extra",
|
|
"grub2-tools-efi",
|
|
"grub2-efi-x64",
|
|
"grub2-efi-x64-cdboot",
|
|
"shim-ia32",
|
|
"grub2-efi-ia32-cdboot",
|
|
}
|
|
|
|
edgeInstallerPkgs := []string{
|
|
"anaconda",
|
|
"anaconda-widgets",
|
|
"kdump-anaconda-addon",
|
|
"anaconda-install-env-deps",
|
|
"oscap-anaconda-addon",
|
|
"redhat-release-eula",
|
|
"dnf",
|
|
"rpm-ostree",
|
|
"ostree",
|
|
"ostree",
|
|
"pigz",
|
|
"kernel",
|
|
"kernel-modules",
|
|
"kernel-modules-extra",
|
|
"grubby",
|
|
"iwl100-firmware",
|
|
"iwl1000-firmware",
|
|
"iwl105-firmware",
|
|
"iwl135-firmware",
|
|
"iwl2000-firmware",
|
|
"iwl2030-firmware",
|
|
"iwl3160-firmware",
|
|
"iwl3945-firmware",
|
|
"iwl4965-firmware",
|
|
"iwl5000-firmware",
|
|
"iwl5150-firmware",
|
|
"iwl6000-firmware",
|
|
"iwl6000g2a-firmware",
|
|
"iwl6000g2b-firmware",
|
|
"iwl6050-firmware",
|
|
"iwl7260-firmware",
|
|
"libertas-sd8686-firmware",
|
|
"libertas-sd8787-firmware",
|
|
"libertas-usb8388-firmware",
|
|
"libertas-usb8388-olpc-firmware",
|
|
"linux-firmware",
|
|
"alsa-firmware",
|
|
"alsa-tools-firmware",
|
|
"glibc-all-langpacks",
|
|
"grub2-tools-efi",
|
|
"efibootmgr",
|
|
"shim-x64",
|
|
"grub2-efi-x64-cdboot",
|
|
"shim-ia32",
|
|
"grub2-efi-ia32-cdboot",
|
|
"biosdevname",
|
|
"memtest86+",
|
|
"syslinux",
|
|
"grub2-tools",
|
|
"grub2-tools-minimal",
|
|
"grub2-tools-extra",
|
|
"plymouth",
|
|
"anaconda-dracut",
|
|
"dracut-network",
|
|
"dracut-config-generic",
|
|
"initscripts",
|
|
"cryptsetup",
|
|
"rpcbind",
|
|
"kbd",
|
|
"kbd-misc",
|
|
"tar",
|
|
"xz",
|
|
"curl",
|
|
"bzip2",
|
|
"systemd",
|
|
"systemd",
|
|
"rsyslog",
|
|
"xorg-x11-drivers",
|
|
"xorg-x11-server-Xorg",
|
|
"xorg-x11-server-utils",
|
|
"xorg-x11-xauth",
|
|
"dbus-x11",
|
|
"metacity",
|
|
"metacity",
|
|
"gsettings-desktop-schemas",
|
|
"gsettings-desktop-schemas",
|
|
"nm-connection-editor",
|
|
"librsvg2",
|
|
"librsvg2",
|
|
"xfsprogs",
|
|
"xfsprogs",
|
|
"gfs2-utils",
|
|
"system-storage-manager",
|
|
"device-mapper-persistent-data",
|
|
"xfsdump",
|
|
"udisks2",
|
|
"udisks2-iscsi",
|
|
"hostname",
|
|
"libblockdev-lvm-dbus",
|
|
"libblockdev-lvm-dbus",
|
|
"volume_key",
|
|
"nss-tools",
|
|
"selinux-policy-targeted",
|
|
"audit",
|
|
"ethtool",
|
|
"openssh-server",
|
|
"nfs-utils",
|
|
"openssh-clients",
|
|
"tigervnc-server-minimal",
|
|
"tigervnc-server-module",
|
|
"net-tools",
|
|
"nmap-ncat",
|
|
"prefixdevname",
|
|
"pciutils",
|
|
"usbutils",
|
|
"ipmitool",
|
|
"mt-st",
|
|
"smartmontools",
|
|
"hdparm",
|
|
"libibverbs",
|
|
"libibverbs",
|
|
"rdma-core",
|
|
"rdma-core",
|
|
"rng-tools",
|
|
"dmidecode",
|
|
"bitmap-fangsongti-fonts",
|
|
"dejavu-sans-fonts",
|
|
"dejavu-sans-mono-fonts",
|
|
"kacst-farsi-fonts",
|
|
"kacst-qurn-fonts",
|
|
"lklug-fonts",
|
|
"lohit-assamese-fonts",
|
|
"lohit-bengali-fonts",
|
|
"lohit-devanagari-fonts",
|
|
"lohit-gujarati-fonts",
|
|
"lohit-gurmukhi-fonts",
|
|
"lohit-kannada-fonts",
|
|
"lohit-odia-fonts",
|
|
"lohit-tamil-fonts",
|
|
"lohit-telugu-fonts",
|
|
"madan-fonts",
|
|
"smc-meera-fonts",
|
|
"thai-scalable-waree-fonts",
|
|
"sil-abyssinica-fonts",
|
|
"xorg-x11-fonts-misc",
|
|
"aajohan-comfortaa-fonts",
|
|
"abattis-cantarell-fonts",
|
|
"sil-scheherazade-fonts",
|
|
"jomolhari-fonts",
|
|
"khmeros-base-fonts",
|
|
"sil-padauk-fonts",
|
|
"google-noto-sans-cjk-ttc-fonts",
|
|
"gdb-gdbserver",
|
|
"libreport-plugin-bugzilla",
|
|
"libreport-plugin-reportuploader",
|
|
"libreport-rhel-anaconda-bugzilla",
|
|
"python3-pyatspi",
|
|
"vim-minimal",
|
|
"strace",
|
|
"lsof",
|
|
"dump",
|
|
"xz",
|
|
"less",
|
|
"rsync",
|
|
"bind-utils",
|
|
"ftp",
|
|
"mtr",
|
|
"wget",
|
|
"spice-vdagent",
|
|
"gdisk",
|
|
"hexedit",
|
|
"sg3_utils",
|
|
"perl-interpreter",
|
|
}
|
|
edgeInstImgTypeX86_64 := imageTypeS2{
|
|
name: "rhel-edge-installer",
|
|
filename: "rhel84-boot.iso",
|
|
mimeType: "application/x-iso9660-image",
|
|
packageSets: map[string]rpmmd.PackageSet{
|
|
"build": {
|
|
Include: edgeBuildPkgs,
|
|
},
|
|
"packages": {
|
|
Include: edgeImgTypeX86_64.packages,
|
|
Exclude: edgeImgTypeX86_64.excludedPackages,
|
|
},
|
|
"installer": {Include: edgeInstallerPkgs},
|
|
},
|
|
enabledServices: edgeImgTypeX86_64.enabledServices,
|
|
rpmOstree: true,
|
|
bootISO: true,
|
|
}
|
|
|
|
edgeOCIImgTypeAarch64 := imageTypeS2{
|
|
name: "rhel-edge-container",
|
|
filename: "rhel84-container.tar",
|
|
mimeType: "application/x-tar",
|
|
packageSets: map[string]rpmmd.PackageSet{
|
|
"packages": {
|
|
Include: edgeImgTypeAarch64.packages,
|
|
Exclude: edgeImgTypeAarch64.excludedPackages,
|
|
},
|
|
"container": {Include: []string{"httpd"}},
|
|
},
|
|
enabledServices: edgeImgTypeAarch64.enabledServices,
|
|
rpmOstree: true,
|
|
bootISO: false,
|
|
}
|
|
|
|
x8664.addImageTypes(
|
|
amiImgType,
|
|
qcow2ImageType,
|
|
openstackImgType,
|
|
tarImgType,
|
|
vhdImgType,
|
|
vmdkImgType,
|
|
)
|
|
|
|
if !isCentos {
|
|
x8664.addImageTypes(edgeImgTypeX86_64)
|
|
x8664.addS2ImageTypes(edgeOCIImgTypeX86_64, edgeInstImgTypeX86_64)
|
|
}
|
|
|
|
aarch64 := architecture{
|
|
distro: &r,
|
|
name: "aarch64",
|
|
bootloaderPackages: []string{
|
|
"dracut-config-generic",
|
|
"efibootmgr",
|
|
"grub2-efi-aa64",
|
|
"grub2-tools",
|
|
"shim-aa64",
|
|
},
|
|
uefi: true,
|
|
}
|
|
aarch64.addImageTypes(
|
|
amiImgType,
|
|
qcow2ImageType,
|
|
openstackImgType,
|
|
tarImgType,
|
|
)
|
|
|
|
if !isCentos {
|
|
aarch64.addImageTypes(edgeImgTypeAarch64)
|
|
aarch64.addS2ImageTypes(edgeOCIImgTypeAarch64)
|
|
}
|
|
|
|
ppc64le := architecture{
|
|
distro: &r,
|
|
name: "ppc64le",
|
|
bootloaderPackages: []string{
|
|
"dracut-config-generic",
|
|
"powerpc-utils",
|
|
"grub2-ppc64le",
|
|
"grub2-ppc64le-modules",
|
|
},
|
|
buildPackages: []string{
|
|
"grub2-ppc64le",
|
|
"grub2-ppc64le-modules",
|
|
},
|
|
legacy: "powerpc-ieee1275",
|
|
uefi: false,
|
|
}
|
|
ppc64le.addImageTypes(
|
|
qcow2ImageType,
|
|
tarImgType,
|
|
)
|
|
|
|
s390x := architecture{
|
|
distro: &r,
|
|
name: "s390x",
|
|
bootloaderPackages: []string{
|
|
"dracut-config-generic",
|
|
"s390utils-base",
|
|
},
|
|
uefi: false,
|
|
}
|
|
s390x.addImageTypes(
|
|
tarImgType,
|
|
qcow2ImageType,
|
|
)
|
|
|
|
r.addArches(x8664, aarch64, ppc64le)
|
|
|
|
if !isCentos {
|
|
r.addArches(s390x)
|
|
}
|
|
|
|
return &r
|
|
}
|