Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions cmd/image-factory/cmd/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ type Options struct { //nolint:govet

// SecureBoot settings.
SecureBoot SecureBootOptions

// Path to YAML file with extension name aliases.
ExtensionNameAlias string
}

// SecureBootOptions configures SecureBoot.
Expand Down Expand Up @@ -165,4 +168,6 @@ var DefaultOptions = Options{
CacheS3Bucket: "image-factory",

MetricsListenAddr: ":2122",

ExtensionNameAlias: "/etc/image-factory/aliases.yaml",
}
2 changes: 2 additions & 0 deletions cmd/image-factory/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ func initFlags() cmd.Options {
flag.StringVar(&opts.SecureBoot.AzureCertificateName, "secureboot-azure-certificate-name", cmd.DefaultOptions.SecureBoot.AzureCertificateName, "Secure Boot Azure Key Vault certificate name (use Azure PKI)") //nolint:lll
flag.StringVar(&opts.SecureBoot.AzureKeyName, "secureboot-azure-key-name", cmd.DefaultOptions.SecureBoot.AzureKeyName, "Secure Boot Azure Key Vault PCR key name (use Azure PKI)")

flag.StringVar(&opts.ExtensionNameAlias, "extension-name-alias", cmd.DefaultOptions.ExtensionNameAlias, "Path to YAML file with extension name aliases")

opts.LogLevel = zap.LevelFlag("log-level", zap.InfoLevel, "set the logging level")

flag.Parse()
Expand Down
7 changes: 7 additions & 0 deletions cmd/image-factory/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"golang.org/x/sys/unix"

"github.com/siderolabs/image-factory/cmd/image-factory/cmd"
"github.com/siderolabs/image-factory/internal/config"
)

func main() {
Expand Down Expand Up @@ -48,6 +49,12 @@ func run() error {
func runWithContext(ctx context.Context) error {
opts := initFlags()

if opts.ExtensionNameAlias != "" {
if err := config.LoadAliases(opts.ExtensionNameAlias); err != nil {
log.Fatalf("failed to load extension aliases: %v", err)
}
}

cfg := zap.NewProductionConfig()
cfg.Level = zap.NewAtomicLevelAt(*opts.LogLevel)

Expand Down
51 changes: 51 additions & 0 deletions internal/config/alias.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

package config

import (
"fmt"
"os"

"gopkg.in/yaml.v3"
)

type aliasConfig struct {
ExtensionNameAlias []struct {
Name string `yaml:"name"`
Alias string `yaml:"alias"`
} `yaml:"extensionNameAlias"`
}

var aliasMap map[string]string

// Loads aliases from aliases.yaml.
func LoadAliases(path string) error {
data, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("failed to read alias config: %w", err)
}

var cfg aliasConfig
if err := yaml.Unmarshal(data, &cfg); err != nil {
return fmt.Errorf("failed to unmarshal alias config: %w", err)
}

aliasMap = make(map[string]string)
for _, item := range cfg.ExtensionNameAlias {
aliasMap[item.Name] = item.Alias
}

return nil
}

// GetAlias returns alias if exists.
func GetAlias(name string) (string, bool) {
if aliasMap == nil {
return "", false
}
alias, ok := aliasMap[name]
return alias, ok
}

11 changes: 10 additions & 1 deletion internal/profile/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/siderolabs/gen/xerrors"
"github.com/siderolabs/gen/xslices"
"github.com/siderolabs/go-pointer"
"github.com/siderolabs/image-factory/internal/config"
"github.com/siderolabs/talos/pkg/imager/profile"
"github.com/siderolabs/talos/pkg/machinery/config/merge"
"github.com/siderolabs/talos/pkg/machinery/constants"
Expand Down Expand Up @@ -393,7 +394,15 @@ func EnhanceFromSchematic(
}

if value.IsZero(extensionRef) {
return prof, xerrors.NewTaggedf[InvalidErrorTag]("official extension %q is not available for Talos version %s", extensionName, versionTag)
// try YAML-based aliases
if aliasedName, ok := config.GetAlias(extensionName); ok {
extensionRef = findExtension(availableExtensions, aliasedName)
} else {
// fallback to default aliases if no YAML config was loaded
if aliasedName, ok := extensionNameAlias(extensionName); ok {
extensionRef = findExtension(availableExtensions, aliasedName)
}
}
}

imagePath, err := artifactProducer.GetExtensionImage(ctx, artifacts.Arch(prof.Arch), extensionRef)
Expand Down