go.mod: update osbuild/images to v0.174.0

Also update the minimum required osbuild version by the osbuild/images
library.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
This commit is contained in:
Tomáš Hozza 2025-08-11 13:40:51 +02:00 committed by Tomáš Hozza
parent 3d0110f14e
commit 74d2edb772
110 changed files with 1218 additions and 1104 deletions

View file

@ -1,5 +1,11 @@
# Release History
## 1.18.2 (2025-07-31)
### Bugs Fixed
* Fixed a case in which `BearerTokenPolicy` didn't ensure an authentication error is non-retriable
## 1.18.1 (2025-07-10)
### Bugs Fixed

View file

@ -40,5 +40,5 @@ const (
Module = "azcore"
// Version is the semantic version (see http://semver.org) of this module.
Version = "v1.18.1"
Version = "v1.18.2"
)

View file

@ -97,7 +97,9 @@ func (b *BearerTokenPolicy) authenticateAndAuthorize(req *policy.Request) func(p
as := acquiringResourceState{p: b, req: req, tro: tro}
tk, err := b.mainResource.Get(as)
if err != nil {
return err
// consider this error non-retriable because if it could be resolved by
// retrying authentication, the credential would have done so already
return errorinfo.NonRetriableError(err)
}
req.Raw().Header.Set(shared.HeaderAuthorization, shared.BearerTokenPrefix+tk.Token)
return nil

View file

@ -1,5 +1,23 @@
# Release History
## 1.11.0 (2025-08-05)
### Other Changes
- `DefaultAzureCredential` tries its next credential when a dev tool credential such as
`AzureCLICredential` returns an error
## 1.11.0-beta.1 (2025-07-15)
### Features Added
- `DefaultAzureCredential` allows selecting one of its credential types by name via environment variable
`AZURE_TOKEN_CREDENTIALS`. It will use only the selected type at runtime. For example, set
`AZURE_TOKEN_CREDENTIALS=WorkloadIdentityCredential` to have `DefaultAzureCredential` use only
`WorkloadIdentityCredential`.
### Other Changes
- By default, `ManagedIdentityCredential` retries IMDS requests for a maximum of ~70 seconds as recommended
in IMDS documentation. In previous versions, it would stop retrying after ~54 seconds by default.
## 1.10.1 (2025-06-10)
### Bugs Fixed

View file

@ -86,6 +86,7 @@ azlog.SetEvents(azidentity.EventAuthentication)
|"DefaultAzureCredential failed to acquire a token"|No credential in the `DefaultAzureCredential` chain provided a token|<ul><li>[Enable logging](#enable-and-configure-logging) to get further diagnostic information.</li><li>Consult the troubleshooting guide for underlying credential types for more information.</li><ul><li>[EnvironmentCredential](#troubleshoot-environmentcredential-authentication-issues)</li><li>[ManagedIdentityCredential](#troubleshoot-managedidentitycredential-authentication-issues)</li><li>[AzureCLICredential](#troubleshoot-azureclicredential-authentication-issues)</li></ul>|
|Error from the client with a status code of 401 or 403|Authentication succeeded but the authorizing Azure service responded with a 401 (Unauthorized), or 403 (Forbidden) status code|<ul><li>[Enable logging](#enable-and-configure-logging) to determine which credential in the chain returned the authenticating token.</li><li>If an unexpected credential is returning a token, check application configuration such as environment variables.</li><li>Ensure the correct role is assigned to the authenticated identity. For example, a service specific role rather than the subscription Owner role.</li></ul>|
|"managed identity timed out"|`DefaultAzureCredential` sets a short timeout on its first managed identity authentication attempt to prevent very long timeouts during local development when no managed identity is available. That timeout causes this error in production when an application requests a token before the hosting environment is ready to provide one.|Use [ManagedIdentityCredential](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#ManagedIdentityCredential) directly, at least in production. It doesn't set a timeout on its authentication attempts.|
|invalid AZURE_TOKEN_CREDENTIALS value "..."|AZURE_TOKEN_CREDENTIALS has an unexpected value|Specify a valid value as described in [DefaultAzureCredential documentation](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#DefaultAzureCredential)
## Troubleshoot EnvironmentCredential authentication issues

View file

@ -43,4 +43,4 @@ extends:
Selection: sparse
MatrixReplace:
- Pool=.*LINUXPOOL.*/azsdk-pool-mms-ubuntu-2204-identitymsi
- OSVmImage=.*LINUXNEXTVMIMAGE.*/azsdk-pool-mms-ubuntu-2204-1espt
- OSVmImage=.*LINUXVMIMAGE.*/azsdk-pool-mms-ubuntu-2204-1espt

View file

@ -19,6 +19,15 @@ import (
const azureTokenCredentials = "AZURE_TOKEN_CREDENTIALS"
// bit flags NewDefaultAzureCredential uses to parse AZURE_TOKEN_CREDENTIALS
const (
env = uint8(1) << iota
workloadIdentity
managedIdentity
az
azd
)
// DefaultAzureCredentialOptions contains optional parameters for DefaultAzureCredential.
// These options may not apply to all credentials in the chain.
type DefaultAzureCredentialOptions struct {
@ -63,6 +72,16 @@ type DefaultAzureCredentialOptions struct {
// Once a credential has successfully authenticated, DefaultAzureCredential will use that credential for
// every subsequent authentication.
//
// # Selecting credentials
//
// Set environment variable AZURE_TOKEN_CREDENTIALS to select a subset of the credential chain described above.
// DefaultAzureCredential will try only the specified credential(s), but its other behavior remains the same.
// Valid values for AZURE_TOKEN_CREDENTIALS are the name of any single type in the above chain, for example
// "EnvironmentCredential" or "AzureCLICredential", and these special values:
//
// - "dev": try [AzureCLICredential] and [AzureDeveloperCLICredential], in that order
// - "prod": try [EnvironmentCredential], [WorkloadIdentityCredential], and [ManagedIdentityCredential], in that order
//
// [DefaultAzureCredential overview]: https://aka.ms/azsdk/go/identity/credential-chains#defaultazurecredential-overview
type DefaultAzureCredential struct {
chain *ChainedTokenCredential
@ -71,19 +90,29 @@ type DefaultAzureCredential struct {
// NewDefaultAzureCredential creates a DefaultAzureCredential. Pass nil for options to accept defaults.
func NewDefaultAzureCredential(options *DefaultAzureCredentialOptions) (*DefaultAzureCredential, error) {
var (
creds []azcore.TokenCredential
errorMessages []string
includeDev, includeProd = true, true
creds []azcore.TokenCredential
errorMessages []string
selected = env | workloadIdentity | managedIdentity | az | azd
)
if c, ok := os.LookupEnv(azureTokenCredentials); ok {
switch c {
case "dev":
includeProd = false
case "prod":
includeDev = false
if atc, ok := os.LookupEnv(azureTokenCredentials); ok {
switch {
case atc == "dev":
selected = az | azd
case atc == "prod":
selected = env | workloadIdentity | managedIdentity
case strings.EqualFold(atc, credNameEnvironment):
selected = env
case strings.EqualFold(atc, credNameWorkloadIdentity):
selected = workloadIdentity
case strings.EqualFold(atc, credNameManagedIdentity):
selected = managedIdentity
case strings.EqualFold(atc, credNameAzureCLI):
selected = az
case strings.EqualFold(atc, credNameAzureDeveloperCLI):
selected = azd
default:
return nil, fmt.Errorf(`invalid %s value %q. Valid values are "dev" and "prod"`, azureTokenCredentials, c)
return nil, fmt.Errorf(`invalid %s value %q. Valid values are "dev", "prod", or the name of any credential type in the default chain. See https://aka.ms/azsdk/go/identity/docs#DefaultAzureCredential for more information`, azureTokenCredentials, atc)
}
}
@ -96,8 +125,7 @@ func NewDefaultAzureCredential(options *DefaultAzureCredentialOptions) (*Default
additionalTenants = strings.Split(tenants, ";")
}
}
if includeProd {
if selected&env != 0 {
envCred, err := NewEnvironmentCredential(&EnvironmentCredentialOptions{
ClientOptions: options.ClientOptions,
DisableInstanceDiscovery: options.DisableInstanceDiscovery,
@ -107,9 +135,10 @@ func NewDefaultAzureCredential(options *DefaultAzureCredentialOptions) (*Default
creds = append(creds, envCred)
} else {
errorMessages = append(errorMessages, "EnvironmentCredential: "+err.Error())
creds = append(creds, &defaultCredentialErrorReporter{credType: "EnvironmentCredential", err: err})
creds = append(creds, &defaultCredentialErrorReporter{credType: credNameEnvironment, err: err})
}
}
if selected&workloadIdentity != 0 {
wic, err := NewWorkloadIdentityCredential(&WorkloadIdentityCredentialOptions{
AdditionallyAllowedTenants: additionalTenants,
ClientOptions: options.ClientOptions,
@ -122,7 +151,8 @@ func NewDefaultAzureCredential(options *DefaultAzureCredentialOptions) (*Default
errorMessages = append(errorMessages, credNameWorkloadIdentity+": "+err.Error())
creds = append(creds, &defaultCredentialErrorReporter{credType: credNameWorkloadIdentity, err: err})
}
}
if selected&managedIdentity != 0 {
o := &ManagedIdentityCredentialOptions{ClientOptions: options.ClientOptions, dac: true}
if ID, ok := os.LookupEnv(azureClientID); ok {
o.ID = ClientID(ID)
@ -135,18 +165,24 @@ func NewDefaultAzureCredential(options *DefaultAzureCredentialOptions) (*Default
creds = append(creds, &defaultCredentialErrorReporter{credType: credNameManagedIdentity, err: err})
}
}
if includeDev {
azCred, err := NewAzureCLICredential(&AzureCLICredentialOptions{AdditionallyAllowedTenants: additionalTenants, TenantID: options.TenantID})
if selected&az != 0 {
azCred, err := NewAzureCLICredential(&AzureCLICredentialOptions{
AdditionallyAllowedTenants: additionalTenants,
TenantID: options.TenantID,
inDefaultChain: true,
})
if err == nil {
creds = append(creds, azCred)
} else {
errorMessages = append(errorMessages, credNameAzureCLI+": "+err.Error())
creds = append(creds, &defaultCredentialErrorReporter{credType: credNameAzureCLI, err: err})
}
}
if selected&azd != 0 {
azdCred, err := NewAzureDeveloperCLICredential(&AzureDeveloperCLICredentialOptions{
AdditionallyAllowedTenants: additionalTenants,
TenantID: options.TenantID,
inDefaultChain: true,
})
if err == nil {
creds = append(creds, azdCred)

View file

@ -18,7 +18,10 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/internal/log"
)
const envVarSendCertChain = "AZURE_CLIENT_SEND_CERTIFICATE_CHAIN"
const (
credNameEnvironment = "EnvironmentCredential"
envVarSendCertChain = "AZURE_CLIENT_SEND_CERTIFICATE_CHAIN"
)
// EnvironmentCredentialOptions contains optional parameters for EnvironmentCredential
type EnvironmentCredentialOptions struct {

View file

@ -4,7 +4,7 @@
"Agent": {
"msi_image": {
"ArmTemplateParameters": "@{deployResources = $true}",
"OSVmImage": "env:LINUXNEXTVMIMAGE",
"OSVmImage": "env:LINUXVMIMAGE",
"Pool": "env:LINUXPOOL"
}
},

View file

@ -54,10 +54,10 @@ type managedIdentityClient struct {
// setIMDSRetryOptionDefaults sets zero-valued fields to default values appropriate for IMDS
func setIMDSRetryOptionDefaults(o *policy.RetryOptions) {
if o.MaxRetries == 0 {
o.MaxRetries = 5
o.MaxRetries = 6
}
if o.MaxRetryDelay == 0 {
o.MaxRetryDelay = 1 * time.Minute
o.MaxRetryDelay = 25 * time.Second
}
if o.RetryDelay == 0 {
o.RetryDelay = 2 * time.Second

View file

@ -100,7 +100,7 @@ $idName = $DeploymentOutputs['AZIDENTITY_USER_ASSIGNED_IDENTITY_NAME']
$issuer = az aks show -g $rg -n $aksName --query "oidcIssuerProfile.issuerUrl" -otsv
$podName = "azidentity-test"
$serviceAccountName = "workload-identity-sa"
az identity federated-credential create -g $rg --identity-name $idName --issuer $issuer --name $idName --subject system:serviceaccount:default:$serviceAccountName
az identity federated-credential create -g $rg --identity-name $idName --issuer $issuer --name $idName --subject system:serviceaccount:default:$serviceAccountName --audiences api://AzureADTokenExchange
Write-Host "Deploying to AKS"
az aks get-credentials -g $rg -n $aksName
az aks update --attach-acr $DeploymentOutputs['AZIDENTITY_ACR_NAME'] -g $rg -n $aksName

View file

@ -14,5 +14,5 @@ const (
module = "github.com/Azure/azure-sdk-for-go/sdk/" + component
// Version is the semantic version (see http://semver.org) of this module.
version = "v1.10.1"
version = "v1.11.0"
)

View file

@ -6,6 +6,8 @@
package errorinfo
import "errors"
// NonRetriable represents a non-transient error. This works in
// conjunction with the retry policy, indicating that the error condition
// is idempotent, so no retries will be attempted.
@ -15,10 +17,14 @@ type NonRetriable interface {
NonRetriable()
}
// NonRetriableError marks the specified error as non-retriable.
// This function takes an error as input and returns a new error that is marked as non-retriable.
// NonRetriableError ensures the specified error is [NonRetriable]. If
// the error is already [NonRetriable], it returns that error unchanged.
// Otherwise, it returns a new, [NonRetriable] error.
func NonRetriableError(err error) error {
return &nonRetriableError{err}
if !errors.As(err, new(NonRetriable)) {
err = &nonRetriableError{err}
}
return err
}
// nonRetriableError is a struct that embeds the error interface.

View file

@ -8,7 +8,7 @@ const (
// VersionMinor is for functionality in a backwards-compatible manner
VersionMinor = 36
// VersionPatch is for backwards-compatible bug fixes
VersionPatch = 0
VersionPatch = 1
// VersionDev indicates development branch. Releases will be empty string.
VersionDev = ""

View file

@ -1 +1 @@
1.59.0
1.59.1

View file

@ -697,7 +697,10 @@ func (ta *tarWriter) addFile(headers *addFileData) error {
}
if !headers.fi.IsDir() && hasHardlinks(headers.fi) {
ta.SeenFiles[getInodeFromStat(headers.fi.Sys())] = headers.hdr.Name
ino := getInodeFromStat(headers.fi.Sys())
if _, seen := ta.SeenFiles[ino]; !seen {
ta.SeenFiles[ino] = headers.hdr.Name
}
}
return nil

View file

@ -2,6 +2,7 @@ package jwt
import (
"errors"
"fmt"
"strings"
)
@ -47,3 +48,42 @@ func joinErrors(errs ...error) error {
errs: errs,
}
}
// Unwrap implements the multiple error unwrapping for this error type, which is
// possible in Go 1.20.
func (je joinedError) Unwrap() []error {
return je.errs
}
// newError creates a new error message with a detailed error message. The
// message will be prefixed with the contents of the supplied error type.
// Additionally, more errors, that provide more context can be supplied which
// will be appended to the message. This makes use of Go 1.20's possibility to
// include more than one %w formatting directive in [fmt.Errorf].
//
// For example,
//
// newError("no keyfunc was provided", ErrTokenUnverifiable)
//
// will produce the error string
//
// "token is unverifiable: no keyfunc was provided"
func newError(message string, err error, more ...error) error {
var format string
var args []any
if message != "" {
format = "%w: %s"
args = []any{err, message}
} else {
format = "%w"
args = []any{err}
}
for _, e := range more {
format += ": %w"
args = append(args, e)
}
err = fmt.Errorf(format, args...)
return err
}

View file

@ -1,47 +0,0 @@
//go:build go1.20
// +build go1.20
package jwt
import (
"fmt"
)
// Unwrap implements the multiple error unwrapping for this error type, which is
// possible in Go 1.20.
func (je joinedError) Unwrap() []error {
return je.errs
}
// newError creates a new error message with a detailed error message. The
// message will be prefixed with the contents of the supplied error type.
// Additionally, more errors, that provide more context can be supplied which
// will be appended to the message. This makes use of Go 1.20's possibility to
// include more than one %w formatting directive in [fmt.Errorf].
//
// For example,
//
// newError("no keyfunc was provided", ErrTokenUnverifiable)
//
// will produce the error string
//
// "token is unverifiable: no keyfunc was provided"
func newError(message string, err error, more ...error) error {
var format string
var args []any
if message != "" {
format = "%w: %s"
args = []any{err, message}
} else {
format = "%w"
args = []any{err}
}
for _, e := range more {
format += ": %w"
args = append(args, e)
}
err = fmt.Errorf(format, args...)
return err
}

View file

@ -1,78 +0,0 @@
//go:build !go1.20
// +build !go1.20
package jwt
import (
"errors"
"fmt"
)
// Is implements checking for multiple errors using [errors.Is], since multiple
// error unwrapping is not possible in versions less than Go 1.20.
func (je joinedError) Is(err error) bool {
for _, e := range je.errs {
if errors.Is(e, err) {
return true
}
}
return false
}
// wrappedErrors is a workaround for wrapping multiple errors in environments
// where Go 1.20 is not available. It basically uses the already implemented
// functionality of joinedError to handle multiple errors with supplies a
// custom error message that is identical to the one we produce in Go 1.20 using
// multiple %w directives.
type wrappedErrors struct {
msg string
joinedError
}
// Error returns the stored error string
func (we wrappedErrors) Error() string {
return we.msg
}
// newError creates a new error message with a detailed error message. The
// message will be prefixed with the contents of the supplied error type.
// Additionally, more errors, that provide more context can be supplied which
// will be appended to the message. Since we cannot use of Go 1.20's possibility
// to include more than one %w formatting directive in [fmt.Errorf], we have to
// emulate that.
//
// For example,
//
// newError("no keyfunc was provided", ErrTokenUnverifiable)
//
// will produce the error string
//
// "token is unverifiable: no keyfunc was provided"
func newError(message string, err error, more ...error) error {
// We cannot wrap multiple errors here with %w, so we have to be a little
// bit creative. Basically, we are using %s instead of %w to produce the
// same error message and then throw the result into a custom error struct.
var format string
var args []any
if message != "" {
format = "%s: %s"
args = []any{err, message}
} else {
format = "%s"
args = []any{err}
}
errs := []error{err}
for _, e := range more {
format += ": %s"
args = append(args, e)
errs = append(errs, e)
}
err = &wrappedErrors{
msg: fmt.Sprintf(format, args...),
joinedError: joinedError{errs: errs},
}
return err
}

View file

@ -1,6 +1,3 @@
//go:build go1.4
// +build go1.4
package jwt
import (

View file

@ -1 +1 @@
156
157

View file

@ -169,9 +169,13 @@
installer_config: &default_installer_config
additional_anaconda_modules: &install_config_additional_anaconda_modules
- "org.fedoraproject.Anaconda.Modules.Timezone"
enabled_anaconda_modules: &install_config_enabled_anaconda_modules
- "org.fedoraproject.Anaconda.Modules.Localization"
- "org.fedoraproject.Anaconda.Modules.Network"
- "org.fedoraproject.Anaconda.Modules.Payloads"
- "org.fedoraproject.Anaconda.Modules.Runtime"
- "org.fedoraproject.Anaconda.Modules.Storage"
- "org.fedoraproject.Anaconda.Modules.Timezone"
- "org.fedoraproject.Anaconda.Modules.Users"
additional_dracut_modules:
- "net-lib"
@ -604,7 +608,7 @@ image_types:
image_format: "vagrant_virtualbox"
"server-qcow2": &server_qcow2
name_aliases: ["qcow2"]
name_aliases: ["qcow2", "guest-image"]
filename: "disk.qcow2"
mime_type: "application/x-qemu-disk"
environment: *kvm_env
@ -650,7 +654,7 @@ image_types:
"server-ami":
<<: *server_qcow2
name_aliases: ["ami"]
name_aliases: ["ami", "aws"]
filename: "image.raw"
mime_type: "application/octet-stream"
payload_pipelines: ["os", "image"]
@ -684,7 +688,7 @@ image_types:
"server-vhd":
<<: *server_qcow2
name_aliases: ["vhd"]
name_aliases: ["vhd", "azure"]
filename: "disk.vhd"
mime_type: "application/x-vhd"
payload_pipelines: ["os", "image", "vpc"]
@ -708,7 +712,7 @@ image_types:
- "WALinuxAgent"
"server-vmdk": &server_vmdk
name_aliases: ["vmdk"]
name_aliases: ["vmdk", "vsphere"]
filename: "disk.vmdk"
mime_type: "application/x-vmdk"
bootable: true
@ -761,7 +765,7 @@ image_types:
"server-ova":
<<: *server_vmdk
name_aliases: ["ova"]
name_aliases: ["ova", "vsphere-ova"]
filename: "image.ova"
mime_type: "application/ovf"
payload_pipelines: ["os", "image", "vmdk", "ovf", "archive"]
@ -1633,10 +1637,7 @@ image_types:
exports: ["bootiso"]
required_partition_sizes: *default_required_dir_sizes
installer_config:
additional_dracut_modules:
- "net-lib"
- "dbus-broker"
squashfs_rootfs: true
<<: *default_installer_config
# NOTE: this is not supported right now because the
# image-installer on Fedora isn't working when unattended.
# These options are probably necessary but could change.
@ -1645,20 +1646,14 @@ image_types:
kickstart_unattended_extra_kernel_opts:
- "inst.text"
- "inst.noninteractive"
conditions:
"on f40 we use ifcfg instead of net-lib":
when:
version_equal: "40"
shallow_merge:
additional_dracut_modules: &additional_dracut_f40
- "ifcfg"
- "dbus-broker"
squashfs_rootfs: false
"on f41 use squashfs_rootfs":
when:
version_equal: "41"
shallow_merge:
additional_dracut_modules: *additional_dracut_f40
# NOTE the minimal installer uses a different set of enabled modules
# but the why is unclear
enabled_anaconda_modules:
- "org.fedoraproject.Anaconda.Modules.Network"
- "org.fedoraproject.Anaconda.Modules.Payloads"
- "org.fedoraproject.Anaconda.Modules.Runtime"
- "org.fedoraproject.Anaconda.Modules.Storage"
- "org.fedoraproject.Anaconda.Modules.Users"
image_config:
locale: "en_US.UTF-8"
iso_rootfs_type: "squashfs"
@ -1875,8 +1870,7 @@ image_types:
- "bootiso"
exports: ["bootiso"]
required_partition_sizes: *default_required_dir_sizes
installer_config:
<<: *default_installer_config
installer_config: *default_installer_config
image_config:
<<: *image_config_iot
ignition_platform: "metal"

View file

@ -123,6 +123,21 @@
zipl:
- "s390utils-base"
installer_config: &default_installer_config
enabled_anaconda_modules: &install_config_enabled_anaconda_modules
- "org.fedoraproject.Anaconda.Modules.Network"
- "org.fedoraproject.Anaconda.Modules.Payloads"
- "org.fedoraproject.Anaconda.Modules.Runtime"
- "org.fedoraproject.Anaconda.Modules.Storage"
additional_dracut_modules:
- "nvdimm" # non-volatile DIMM firmware (provides nfit, cuse, and nd_e820)
- "net-lib"
additional_drivers:
- "ipmi_devintf"
- "ipmi_msghandler"
# see commit c6bfb22f54, controls the kickstart location
iso_root_kickstart: true
sapapps_image_config: &sapapps_image_config
selinux_config:
state: "permissive"
@ -730,6 +745,7 @@ image_types:
- "subscription-manager-cockpit"
qcow2: &qcow2
name_aliases: ["guest-image"]
filename: "disk.qcow2"
mime_type: "application/x-qemu-disk"
# note that unlike fedora rhel does not use the environment.KVM
@ -838,6 +854,9 @@ image_types:
"vagrant-libvirt": &vagrant_libvirt
<<: *qcow2
# we have to reset the aliases otherwise this type
# will inherit the name aliases causing a conflict
name_aliases: []
filename: "vagrant-libvirt.box"
mime_type: "application/x-tar"
bootable: true
@ -878,12 +897,18 @@ image_types:
oci:
<<: *qcow2
# we have to reset the aliases otherwise this type
# will inherit the name aliases causing a conflict
name_aliases: []
platforms:
- <<: *x86_64_bios_platform
image_format: "qcow2"
vhd: &vhd
<<: *qcow2
# we have to reset the aliases otherwise this type
# will inherit the name aliases causing a conflict
name_aliases: []
filename: "disk.vhd"
mime_type: "application/x-vhd"
default_size: 4_294_967_296 # 4 * datasizes.GibiByte
@ -1153,6 +1178,7 @@ image_types:
- arch: "s390x"
vmdk: &vmdk
name_aliases: ["vshpere"]
filename: "disk.vmdk"
mime_type: "application/x-vmdk"
bootable: true
@ -1186,6 +1212,7 @@ image_types:
ova:
<<: *vmdk
name_aliases: ["vsphere-ova"]
filename: "image.ova"
mime_type: "application/ovf"
payload_pipelines: ["os", "image", "vmdk", "ovf", "archive"]
@ -1195,6 +1222,7 @@ image_types:
image_format: "ova"
ami: &ami
name_aliases: ['aws']
filename: "image.raw"
mime_type: "application/octet-stream"
image_func: "disk"
@ -1376,6 +1404,9 @@ image_types:
# RHEL internal-only x86_64 EC2 image type
ec2: &ec2
<<: *ami
# we have to reset the aliases otherwise this type
# will inherit the name aliases causing a conflict
name_aliases: []
payload_pipelines: ["os", "image", "xz"]
exports: ["xz"]
filename: "image.raw.xz"
@ -1581,18 +1612,20 @@ image_types:
arch: "x86_64"
shallow_merge:
iso_boot_type: "grub2"
installer_config:
additional_dracut_modules:
- "nvdimm" # non-volatile DIMM firmware (provides nfit, cuse, and nd_e820)
- "net-lib"
additional_drivers:
- "ipmi_devintf"
- "ipmi_msghandler"
# see commit c6bfb22f54, controls the kickstart location
iso_root_kickstart: true
installer_config: *default_installer_config
platforms:
- *x86_64_installer_platform
- *aarch64_platform
platforms_override:
conditions:
"RHEL 10.1+ adds FIPS menu":
when:
version_greater_or_equal: "10.1"
override:
- <<: *x86_64_installer_platform
fips_menu: true
- <<: *aarch64_platform
fips_menu: true
package_sets:
<<: *bare_metal_pkgset
installer:
@ -1725,6 +1758,9 @@ image_types:
- "dmidecode"
gce:
# this image type is set to `gcp` in image-builder-crc
# & `osbuild-composer`, so set the alias here
name_aliases: ["gcp"]
filename: "image.tar.gz"
mime_type: "application/gzip"
image_func: "disk"
@ -1983,6 +2019,7 @@ image_types:
- "redhat-release"
- "tpm2-tools"
- "WALinuxAgent"
- "yum-utils"
- exclude:
- "dracut-config-rescue"
- "grubby"

View file

@ -863,6 +863,15 @@
zipl:
- "s390utils-base"
default_installer_config: &default_installer_config
enabled_anaconda_modules: &install_config_enabled_anaconda_modules
- "org.fedoraproject.Anaconda.Modules.Network"
- "org.fedoraproject.Anaconda.Modules.Payloads"
- "org.fedoraproject.Anaconda.Modules.Storage"
iso_root_kickstart: true
additional_dracut_modules:
- "ifcfg"
partitioning:
ids:
- &prep_partition_dosid "41"
@ -1302,6 +1311,9 @@ image_types:
ec2: &ec2
<<: *ami
# we have to reset the aliases otherwise this type
# will inherit the name aliases causing a conflict
name_aliases: []
filename: "image.raw.xz"
mime_type: "application/xz"
compression: "xz"
@ -1408,6 +1420,7 @@ image_types:
- "rh-amazon-rhui-client-sap-bundle"
qcow2: &qcow2
name_aliases: ["guest-image"]
filename: "disk.qcow2"
mime_type: "application/x-qemu-disk"
# note that unlike fedora rhel does not use the environment.KVM
@ -1459,6 +1472,7 @@ image_types:
- *qcow2_common_pkgset
vhd:
name_aliases: ["azure"]
filename: "disk.vhd"
mime_type: "application/x-vhd"
image_func: "disk"
@ -1800,11 +1814,7 @@ image_types:
arch: "x86_64"
shallow_merge:
iso_boot_type: "syslinux"
installer_config:
# see commit c6bfb22f54, controls the kickstart location
iso_root_kickstart: true
additional_dracut_modules:
- "ifcfg"
installer_config: *default_installer_config
platforms:
- *x86_64_installer_platform
- *aarch64_platform
@ -2045,9 +2055,7 @@ image_types:
arch: "x86_64"
shallow_merge:
iso_boot_type: "syslinux"
installer_config:
additional_dracut_modules:
- "ifcfg"
installer_config: *default_installer_config
platforms:
- *x86_64_uefi_platform
- *aarch64_platform
@ -2228,6 +2236,7 @@ image_types:
- *edge_commit_pkgset
vmdk: &vmdk
name_aliases: ["vsphere"]
filename: "disk.vmdk"
mime_type: "application/x-vmdk"
bootable: true
@ -2262,6 +2271,7 @@ image_types:
ova:
<<: *vmdk
name_aliases: ["vsphere-ova"]
filename: "image.ova"
mime_type: "application/ovf"
payload_pipelines: ["os", "image", "vmdk", "ovf", "archive"]
@ -2271,6 +2281,9 @@ image_types:
image_format: "ova"
gce: &gce
# this image type is set to `gcp` in image-builder-crc
# & `osbuild-composer`, so set the alias here
name_aliases: ["gcp"]
filename: "image.tar.gz"
mime_type: "application/gzip"
image_func: "disk"
@ -2374,6 +2387,9 @@ image_types:
"gce-rhui":
<<: *gce
# we have to reset the aliases otherwise this type
# will inherit the name aliases causing a conflict
name_aliases: []
image_config:
<<: *gce_image_config
rhsm_config:
@ -2397,6 +2413,9 @@ image_types:
oci:
<<: *qcow2
# we have to reset the aliases otherwise this type
# will inherit the name aliases causing a conflict
name_aliases: []
platforms:
- <<: *x86_64_bios_platform
image_format: "qcow2"
@ -2404,6 +2423,9 @@ image_types:
openstack:
<<: *qcow2
# we have to reset the aliases otherwise this type
# will inherit the name aliases causing a conflict
name_aliases: []
default_size: 4_294_967_296 # 4 * datasizes.GibiByte
image_config:
kernel_options:

View file

@ -1070,6 +1070,11 @@
terminal: ["console"]
default_installer_config: &default_installer_config
enabled_anaconda_modules: &install_config_enabled_anaconda_modules
- "org.fedoraproject.Anaconda.Modules.Network"
- "org.fedoraproject.Anaconda.Modules.Payloads"
- "org.fedoraproject.Anaconda.Modules.Runtime"
- "org.fedoraproject.Anaconda.Modules.Storage"
# see commit c6bfb22f54, controls the kickstart location
iso_root_kickstart: true
additional_dracut_modules:
@ -1155,6 +1160,7 @@ image_types:
- "subscription-manager-cockpit"
qcow2: &qcow2
name_aliases: ["guest-image"]
filename: "disk.qcow2"
mime_type: "application/x-qemu-disk"
# note that unlike fedora rhel does not use the environment.KVM
@ -1267,6 +1273,9 @@ image_types:
"vagrant-libvirt": &vagrant_libvirt
<<: *qcow2
# we have to reset the aliases otherwise this type
# will inherit the name aliases causing a conflict
name_aliases: []
filename: "vagrant-libvirt.box"
mime_type: "application/x-tar"
bootable: true
@ -1307,12 +1316,18 @@ image_types:
oci:
<<: *qcow2
# we have to reset the aliases otherwise this type
# will inherit the name aliases causing a conflict
name_aliases: []
platforms:
- <<: *x86_64_bios_platform
image_format: "qcow2"
vhd: &vhd
<<: *qcow2
# we have to reset the aliases otherwise this type
# will inherit the name aliases causing a conflict
name_aliases: []
filename: "disk.vhd"
mime_type: "application/x-vhd"
default_size: 4_294_967_296 # 4 * datasizes.GibiByte
@ -1646,6 +1661,7 @@ image_types:
- "rng-tools"
vmdk: &vmdk
name_aliases: ["vsphere"]
filename: "disk.vmdk"
mime_type: "application/x-vmdk"
bootable: true
@ -1679,6 +1695,7 @@ image_types:
ova:
<<: *vmdk
name_aliases: ["vsphere-ova"]
filename: "image.ova"
mime_type: "application/ovf"
payload_pipelines: ["os", "image", "vmdk", "ovf", "archive"]
@ -1836,6 +1853,7 @@ image_types:
ami:
<<: *ec2
name_aliases: ["aws"]
mime_type: "application/octet-stream"
filename: "image.raw"
payload_pipelines: ["os", "image"]
@ -2057,6 +2075,16 @@ image_types:
platforms:
- *x86_64_installer_platform
- *aarch64_platform
platforms_override:
conditions:
"RHEL 9.7+ adds FIPS menu":
when:
version_greater_or_equal: "9.7"
override:
- <<: *x86_64_installer_platform
fips_menu: true
- <<: *aarch64_platform
fips_menu: true
installer_config: *default_installer_config
image_config:
locale: "C.UTF-8"
@ -2073,7 +2101,9 @@ image_types:
- *anaconda_pkgset
gce:
name_aliases: ["gce-rhui"]
# this image type is set to `gcp` in image-builder-crc
# & `osbuild-composer`, so set the alias here
name_aliases: ["gce-rhui", "gcp"]
filename: "image.tar.gz"
mime_type: "application/gzip"
image_func: "disk"
@ -2338,6 +2368,9 @@ image_types:
openstack:
<<: *qcow2
# we have to reset the aliases otherwise this type
# will inherit the name aliases causing a conflict
name_aliases: []
default_size: 4_294_967_296 # 4 * datasizes.GibiByte
platforms:
- <<: *x86_64_bios_platform
@ -2925,6 +2958,7 @@ image_types:
- "redhat-release"
- "tpm2-tools"
- "WALinuxAgent"
- "yum-utils"
- exclude:
- "dracut-config-rescue"
- "iwl*"

View file

@ -643,30 +643,29 @@ func (a *AWS) RunInstanceEC2(imageID, secGroupID, userData, instanceType string)
return reservation, nil
}
func (a *AWS) TerminateInstanceEC2(instanceID string) (*ec2.TerminateInstancesOutput, error) {
// We need to terminate the instance now and wait until the termination is done.
// Otherwise, it wouldn't be possible to delete the image.
// TerminateInstancesEC2 terminates the specified EC2 instances and waits for them to be terminated if timeout is greater than 0.
func (a *AWS) TerminateInstancesEC2(instanceIDs []string, timeout time.Duration) (*ec2.TerminateInstancesOutput, error) {
res, err := a.ec2.TerminateInstances(
context.TODO(),
&ec2.TerminateInstancesInput{
InstanceIds: []string{
instanceID,
},
InstanceIds: slices.Clone(instanceIDs),
})
if err != nil {
return nil, err
}
instanceWaiter := newTerminateInstancesWaiterEC2(a.ec2)
err = instanceWaiter.Wait(
context.TODO(),
&ec2.DescribeInstancesInput{
InstanceIds: []string{instanceID},
},
time.Hour,
)
if err != nil {
return nil, err
if timeout > 0 {
instanceWaiter := newTerminateInstancesWaiterEC2(a.ec2)
err = instanceWaiter.Wait(
context.TODO(),
&ec2.DescribeInstancesInput{
InstanceIds: slices.Clone(instanceIDs),
},
timeout,
)
if err != nil {
return nil, err
}
}
return res, nil
@ -681,30 +680,56 @@ func (a *AWS) GetInstanceAddress(instanceID string) (string, error) {
return *reservation.Instances[0].PublicIpAddress, nil
}
// DeleteEC2Image deletes the specified image and its associated snapshot
func (a *AWS) DeleteEC2Image(imageID, snapshotID string) error {
var retErr error
// DeleteEC2Image deletes the specified image and all of its associated snapshots
func (a *AWS) DeleteEC2Image(imageID string) error {
img, err := a.ec2.DescribeImages(
context.TODO(),
&ec2.DescribeImagesInput{
ImageIds: []string{imageID},
},
)
if err != nil {
return err
}
if len(img.Images) == 0 {
return fmt.Errorf("image %s not found", imageID)
}
var snapshotIDs []string
for _, bdm := range img.Images[0].BlockDeviceMappings {
if bdm.Ebs != nil && bdm.Ebs.SnapshotId != nil {
snapshotIDs = append(snapshotIDs, *bdm.Ebs.SnapshotId)
}
}
var retErr error
// firstly, deregister the image
_, err := a.ec2.DeregisterImage(
_, err = a.ec2.DeregisterImage(
context.TODO(),
&ec2.DeregisterImageInput{
ImageId: &imageID,
})
if err != nil {
return err
retErr = fmt.Errorf("failed to deregister image %s: %w", imageID, err)
}
// now it's possible to delete the snapshot
_, err = a.ec2.DeleteSnapshot(
context.TODO(),
&ec2.DeleteSnapshotInput{
SnapshotId: &snapshotID,
})
// now it's possible to delete snapshots
for _, snapshotID := range snapshotIDs {
_, err = a.ec2.DeleteSnapshot(
context.TODO(),
&ec2.DeleteSnapshotInput{
SnapshotId: &snapshotID,
})
if err != nil {
return err
if err != nil {
if retErr != nil {
retErr = fmt.Errorf("%w; failed to delete snapshot %s: %v", retErr, snapshotID, err)
continue
}
retErr = fmt.Errorf("failed to delete snapshot %s: %w", snapshotID, err)
}
}
return retErr

View file

@ -32,30 +32,6 @@ type PartitionTable struct {
StartOffset uint64 `json:"start_offset,omitempty" yaml:"start_offset,omitempty"`
}
// TODO: PartitioningMode is a copy of
// pkg/disk/partition.PartitioningMode - drop once
// https://github.com/osbuild/blueprint/pull/26 is merged
type PartitioningMode string
const (
// AutoLVMPartitioningMode creates a LVM layout if the filesystem
// contains a mountpoint that's not defined in the base partition table
// of the specified image type. In the other case, a raw layout is used.
AutoLVMPartitioningMode PartitioningMode = "auto-lvm"
// LVMPartitioningMode always creates an LVM layout.
LVMPartitioningMode PartitioningMode = "lvm"
// RawPartitioningMode always creates a raw layout.
RawPartitioningMode PartitioningMode = "raw"
// BtrfsPartitioningMode creates a btrfs layout.
BtrfsPartitioningMode PartitioningMode = "btrfs"
// DefaultPartitioningMode is AutoLVMPartitioningMode and is the empty state
DefaultPartitioningMode PartitioningMode = ""
)
// DefaultBootPartitionSize is the default size of the /boot partition if it
// needs to be auto-created. This happens if the custom partitioning don't
// specify one, but the image requires one to boot (/ is on btrfs, or an LV).

View file

@ -79,6 +79,9 @@ type ImageType interface {
// Returns the name of the image type.
Name() string
// Returns the aliases for the image type.
Aliases() []string
// Returns the parent architecture
Arch() Arch

View file

@ -580,10 +580,10 @@ func imageInstallerImage(workload workload.Workload,
return nil, err
}
if instCust != nil && instCust.Modules != nil {
img.AdditionalAnacondaModules = append(img.AdditionalAnacondaModules, instCust.Modules.Enable...)
img.EnabledAnacondaModules = append(img.EnabledAnacondaModules, instCust.Modules.Enable...)
img.DisabledAnacondaModules = append(img.DisabledAnacondaModules, instCust.Modules.Disable...)
}
img.AdditionalAnacondaModules = append(img.AdditionalAnacondaModules, anaconda.ModuleUsers)
img.EnabledAnacondaModules = append(img.EnabledAnacondaModules, anaconda.ModuleUsers)
img.Platform = t.platform
img.Workload = workload
@ -596,6 +596,7 @@ func imageInstallerImage(workload workload.Workload,
}
if installerConfig != nil {
img.EnabledAnacondaModules = append(img.EnabledAnacondaModules, installerConfig.EnabledAnacondaModules...)
img.AdditionalDracutModules = append(img.AdditionalDracutModules, installerConfig.AdditionalDracutModules...)
img.AdditionalDrivers = append(img.AdditionalDrivers, installerConfig.AdditionalDrivers...)
if installerConfig.SquashfsRootfs != nil && *installerConfig.SquashfsRootfs {
@ -797,7 +798,7 @@ func iotInstallerImage(workload workload.Workload,
return nil, err
}
if instCust != nil && instCust.Modules != nil {
img.AdditionalAnacondaModules = append(img.AdditionalAnacondaModules, instCust.Modules.Enable...)
img.EnabledAnacondaModules = append(img.EnabledAnacondaModules, instCust.Modules.Enable...)
img.DisabledAnacondaModules = append(img.DisabledAnacondaModules, instCust.Modules.Disable...)
}
@ -809,14 +810,14 @@ func iotInstallerImage(workload workload.Workload,
if installerConfig != nil {
img.AdditionalDracutModules = append(img.AdditionalDracutModules, installerConfig.AdditionalDracutModules...)
img.AdditionalDrivers = append(img.AdditionalDrivers, installerConfig.AdditionalDrivers...)
img.AdditionalAnacondaModules = append(img.AdditionalAnacondaModules, installerConfig.AdditionalAnacondaModules...)
img.EnabledAnacondaModules = append(img.EnabledAnacondaModules, installerConfig.EnabledAnacondaModules...)
if installerConfig.SquashfsRootfs != nil && *installerConfig.SquashfsRootfs {
img.RootfsType = manifest.SquashfsRootfs
}
}
if len(img.Kickstart.Users)+len(img.Kickstart.Groups) > 0 {
// only enable the users module if needed
img.AdditionalAnacondaModules = append(img.AdditionalAnacondaModules, anaconda.ModuleUsers)
img.EnabledAnacondaModules = append(img.EnabledAnacondaModules, anaconda.ModuleUsers)
}
img.Product = d.Product()

View file

@ -79,6 +79,10 @@ func (t *imageType) Name() string {
return t.ImageTypeYAML.Name()
}
func (t *imageType) Aliases() []string {
return t.ImageTypeYAML.NameAliases
}
func (t *imageType) Arch() distro.Arch {
return t.arch
}

View file

@ -3,10 +3,11 @@ package distro
// InstallerConfig represents a configuration for the installer
// part of an Installer image type.
type InstallerConfig struct {
EnabledAnacondaModules []string `yaml:"enabled_anaconda_modules"`
// Additional dracut modules and drivers to enable
AdditionalDracutModules []string `yaml:"additional_dracut_modules"`
AdditionalDrivers []string `yaml:"additional_drivers"`
AdditionalAnacondaModules []string `yaml:"additional_anaconda_modules"`
AdditionalDracutModules []string `yaml:"additional_dracut_modules"`
AdditionalDrivers []string `yaml:"additional_drivers"`
// XXX: this is really here only for compatibility/because of drift in the "imageInstallerImage"
// between fedora/rhel

View file

@ -45,6 +45,7 @@ type TestArch struct {
type TestImageType struct {
architecture *TestArch
name string
aliases []string
}
const (
@ -178,6 +179,10 @@ func (t *TestImageType) Name() string {
return t.name
}
func (t *TestImageType) Aliases() []string {
return t.aliases
}
func (t *TestImageType) Arch() distro.Arch {
return t.architecture
}
@ -341,10 +346,16 @@ func newTestDistro(releasever string) *TestDistro {
it3 := TestImageType{
name: TestImageTypeAmi,
aliases: []string{
"aws",
},
}
it4 := TestImageType{
name: TestImageTypeVhd,
aliases: []string{
"azure",
},
}
it5 := TestImageType{
@ -361,14 +372,23 @@ func newTestDistro(releasever string) *TestDistro {
it8 := TestImageType{
name: TestImageTypeQcow2,
aliases: []string{
"guest-image",
},
}
it9 := TestImageType{
name: TestImageTypeVmdk,
aliases: []string{
"vsphere",
},
}
it10 := TestImageType{
name: TestImageTypeGce,
aliases: []string{
"gcp",
},
}
it11 := TestImageType{

View file

@ -40,8 +40,8 @@ type AnacondaContainerInstaller struct {
Filename string
AdditionalAnacondaModules []string
DisabledAnacondaModules []string
EnabledAnacondaModules []string
DisabledAnacondaModules []string
AdditionalDracutModules []string
AdditionalDrivers []string
@ -99,11 +99,11 @@ func (img *AnacondaContainerInstaller) InstantiateManifest(m *manifest.Manifest,
anacondaPipeline.Variant = img.Variant
anacondaPipeline.Biosdevname = (img.Platform.GetArch() == arch.ARCH_X86_64)
anacondaPipeline.Checkpoint()
anacondaPipeline.AdditionalAnacondaModules = img.AdditionalAnacondaModules
anacondaPipeline.EnabledAnacondaModules = img.EnabledAnacondaModules
anacondaPipeline.DisabledAnacondaModules = img.DisabledAnacondaModules
if img.FIPS {
anacondaPipeline.AdditionalAnacondaModules = append(
anacondaPipeline.AdditionalAnacondaModules,
anacondaPipeline.EnabledAnacondaModules = append(
anacondaPipeline.EnabledAnacondaModules,
anaconda.ModuleSecurity,
)
}

View file

@ -43,8 +43,8 @@ type AnacondaOSTreeInstaller struct {
Filename string
AdditionalAnacondaModules []string
DisabledAnacondaModules []string
EnabledAnacondaModules []string
DisabledAnacondaModules []string
AdditionalDracutModules []string
AdditionalDrivers []string
@ -99,10 +99,10 @@ func (img *AnacondaOSTreeInstaller) InstantiateManifest(m *manifest.Manifest,
anacondaPipeline.UseLegacyAnacondaConfig = img.UseLegacyAnacondaConfig
anacondaPipeline.AdditionalDracutModules = img.AdditionalDracutModules
anacondaPipeline.AdditionalAnacondaModules = img.AdditionalAnacondaModules
anacondaPipeline.EnabledAnacondaModules = img.EnabledAnacondaModules
if img.FIPS {
anacondaPipeline.AdditionalAnacondaModules = append(
anacondaPipeline.AdditionalAnacondaModules,
anacondaPipeline.EnabledAnacondaModules = append(
anacondaPipeline.EnabledAnacondaModules,
anaconda.ModuleSecurity,
)
}

View file

@ -69,9 +69,9 @@ type AnacondaTarInstaller struct {
Filename string
AdditionalKernelOpts []string
AdditionalAnacondaModules []string
DisabledAnacondaModules []string
AdditionalKernelOpts []string
EnabledAnacondaModules []string
DisabledAnacondaModules []string
AdditionalDracutModules []string
AdditionalDrivers []string
@ -136,10 +136,10 @@ func (img *AnacondaTarInstaller) InstantiateManifest(m *manifest.Manifest,
anacondaPipeline.Biosdevname = (img.Platform.GetArch() == arch.ARCH_X86_64)
anacondaPipeline.UseLegacyAnacondaConfig = img.UseLegacyAnacondaConfig
anacondaPipeline.AdditionalAnacondaModules = img.AdditionalAnacondaModules
anacondaPipeline.EnabledAnacondaModules = img.EnabledAnacondaModules
if img.OSCustomizations.FIPS {
anacondaPipeline.AdditionalAnacondaModules = append(
anacondaPipeline.AdditionalAnacondaModules,
anacondaPipeline.EnabledAnacondaModules = append(
anacondaPipeline.EnabledAnacondaModules,
anaconda.ModuleSecurity,
)
}

View file

@ -66,7 +66,7 @@ type AnacondaInstaller struct {
InteractiveDefaultsKickstart *kickstart.Options
// Additional anaconda modules to enable
AdditionalAnacondaModules []string
EnabledAnacondaModules []string
// Anaconda modules to explicitly disable
DisabledAnacondaModules []string
@ -307,9 +307,9 @@ func (p *AnacondaInstaller) payloadStages() []*osbuild.Stage {
var anacondaStageOptions *osbuild.AnacondaStageOptions
if p.UseLegacyAnacondaConfig {
anacondaStageOptions = osbuild.NewAnacondaStageOptionsLegacy(p.AdditionalAnacondaModules, p.DisabledAnacondaModules)
anacondaStageOptions = osbuild.NewAnacondaStageOptionsLegacy(p.EnabledAnacondaModules, p.DisabledAnacondaModules)
} else {
anacondaStageOptions = osbuild.NewAnacondaStageOptions(p.AdditionalAnacondaModules, p.DisabledAnacondaModules)
anacondaStageOptions = osbuild.NewAnacondaStageOptions(p.EnabledAnacondaModules, p.DisabledAnacondaModules)
}
stages = append(stages, osbuild.NewAnacondaStage(anacondaStageOptions))

View file

@ -435,6 +435,7 @@ func (p *AnacondaInstallerISOTree) serialize() osbuild.Pipeline {
Dir: "/images/pxeboot",
Opts: kernelOpts,
},
FIPS: p.anacondaPipeline.platform.GetFIPSMenu(),
}
stage := osbuild.NewISOLinuxStage(options, p.anacondaPipeline.Name())
@ -450,6 +451,7 @@ func (p *AnacondaInstallerISOTree) serialize() osbuild.Pipeline {
Opts: kernelOpts,
},
ISOLabel: p.isoLabel,
FIPS: p.anacondaPipeline.platform.GetFIPSMenu(),
}
stage := osbuild.NewGrub2ISOLegacyStage(options)

View file

@ -55,6 +55,7 @@ func (p *EFIBootTree) serialize() osbuild.Pipeline {
ISOLabel: p.ISOLabel,
Architectures: architectures,
Vendor: p.UEFIVendor,
FIPS: p.Platform.GetFIPSMenu(),
}
grub2Stage := osbuild.NewGrubISOStage(grubOptions)
pipeline.AddStage(grub2Stage)

View file

@ -20,9 +20,6 @@ type Pipeline interface {
// Checkpoint this pipeline when osbuild is called.
Checkpoint()
// Export this tree of this pipeline as an artifact when osbuild is called.
Export() *artifact.Artifact
// BuildPipeline returns a reference to the pipeline that creates the build
// root for this pipeline. For build pipelines, it should return nil.
BuildPipeline() Build
@ -74,6 +71,14 @@ type Pipeline interface {
fileRefs() []string
}
// ExportingPipeline is a pipeline that can export an artifact
type ExportingPipeline interface {
Pipeline
// Export this tree of this pipeline as an artifact when osbuild is called.
Export() *artifact.Artifact
}
// A Base represents the core functionality shared between each of the pipeline
// implementations, and the Base struct must be embedded in each of them.
type Base struct {
@ -99,10 +104,6 @@ func (p Base) getCheckpoint() bool {
return p.checkpoint
}
func (p *Base) Export() *artifact.Artifact {
panic("can't export pipeline directly from pipeline.Base")
}
func (p Base) getExport() bool {
return p.export
}
@ -204,7 +205,7 @@ type TreePipeline interface {
// FilePipeline is any pipeline that produces a single file (typically an image file).
type FilePipeline interface {
Pipeline
ExportingPipeline
Filename() string
SetFilename(fname string)
}

View file

@ -10,7 +10,7 @@ type VMDK struct {
Base
filename string
imgPipeline Pipeline
imgPipeline FilePipeline
}
func (p VMDK) Filename() string {

View file

@ -2,8 +2,6 @@ package osbuild
import (
"slices"
"github.com/osbuild/images/pkg/customizations/anaconda"
)
type AnacondaStageOptions struct {
@ -39,28 +37,17 @@ func NewAnacondaStage(options *AnacondaStageOptions) *Stage {
}
}
func defaultModuleStates() map[string]bool {
return map[string]bool{
anaconda.ModuleLocalization: false,
anaconda.ModuleNetwork: true,
anaconda.ModulePayloads: true,
anaconda.ModuleRuntime: true,
anaconda.ModuleSecurity: false,
anaconda.ModuleServices: false,
anaconda.ModuleStorage: true,
anaconda.ModuleSubscription: false,
anaconda.ModuleTimezone: false,
anaconda.ModuleUsers: false,
}
}
func moduleStates(enable, disable []string) map[string]bool {
states := map[string]bool{}
func setModuleStates(states map[string]bool, enable, disable []string) {
for _, modname := range enable {
states[modname] = true
}
for _, modname := range disable {
states[modname] = false
}
return states
}
func filterEnabledModules(moduleStates map[string]bool) []string {
@ -76,8 +63,7 @@ func filterEnabledModules(moduleStates map[string]bool) []string {
}
func NewAnacondaStageOptionsLegacy(enableModules, disableModules []string) *AnacondaStageOptions {
states := defaultModuleStates()
setModuleStates(states, enableModules, disableModules)
states := moduleStates(enableModules, disableModules)
return &AnacondaStageOptions{
KickstartModules: filterEnabledModules(states),
@ -85,8 +71,7 @@ func NewAnacondaStageOptionsLegacy(enableModules, disableModules []string) *Anac
}
func NewAnacondaStageOptions(enableModules, disableModules []string) *AnacondaStageOptions {
states := defaultModuleStates()
setModuleStates(states, enableModules, disableModules)
states := moduleStates(enableModules, disableModules)
return &AnacondaStageOptions{
ActivatableModules: filterEnabledModules(states),

View file

@ -10,6 +10,8 @@ type Grub2ISOLegacyStageOptions struct {
Kernel ISOKernel `json:"kernel"`
ISOLabel string `json:"isolabel"`
FIPS bool `json:"fips,omitempty"`
}
func (Grub2ISOLegacyStageOptions) isStageOptions() {}

View file

@ -14,6 +14,8 @@ type GrubISOStageOptions struct {
Architectures []string `json:"architectures,omitempty"`
Vendor string `json:"vendor,omitempty"`
FIPS bool `json:"fips,omitempty"`
}
func (GrubISOStageOptions) isStageOptions() {}

View file

@ -3,6 +3,7 @@ package osbuild
type ISOLinuxStageOptions struct {
Product ISOLinuxProduct `json:"product"`
Kernel ISOLinuxKernel `json:"kernel"`
FIPS bool `json:"fips,omitempty"`
}
func (ISOLinuxStageOptions) isStageOptions() {}

View file

@ -136,12 +136,14 @@ type Platform interface {
GetBuildPackages() []string
GetBootFiles() [][2]string
GetBootloader() Bootloader
GetFIPSMenu() bool
}
type BasePlatform struct {
ImageFormat ImageFormat
QCOW2Compat string
FirmwarePackages []string
FIPSMenu bool // Add FIPS entry to iso bootloader menu
}
func (p BasePlatform) GetImageFormat() ImageFormat {
@ -179,3 +181,8 @@ func (p BasePlatform) GetBootFiles() [][2]string {
func (p BasePlatform) GetBootloader() Bootloader {
return BOOTLOADER_NONE
}
// GetFIPSMenu is used to add the FIPS entry to the iso bootloader menu
func (p BasePlatform) GetFIPSMenu() bool {
return p.FIPSMenu
}

View file

@ -22,6 +22,7 @@ type PlatformConf struct {
BootFiles [][2]string `yaml:"boot_files"`
Bootloader Bootloader `yaml:"bootloader"`
FIPSMenu bool `yaml:"fips_menu"` // Add FIPS entry to iso bootloader menu
}
// ensure PlatformConf implements the Platform interface
@ -66,3 +67,8 @@ func (pc *PlatformConf) GetBootFiles() [][2]string {
func (pc *PlatformConf) GetBootloader() Bootloader {
return pc.Bootloader
}
// GetFIPSMenu is used to add the FIPS entry to the iso bootloader menu
func (pc *PlatformConf) GetFIPSMenu() bool {
return pc.FIPSMenu
}