Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
54 changes: 54 additions & 0 deletions toolkit/tools/imagecreator/distribution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

package main

import (
"fmt"
"strings"

"github.com/microsoft/azure-linux-image-tools/toolkit/tools/imagecustomizerapi"
)

// distribution represents a supported Linux distribution and version combination
type distribution struct {
name string
version string
}

// GetDistribution validates and returns a distribution from the CLI args
func (c *ImageCreatorCmd) getDistribution() (*distribution, error) {
dist := &distribution{
name: c.Distro,
version: c.DistroVersion,
}
if err := dist.validate(); err != nil {
return nil, err
}
return dist, nil
}

// Validate ensures the distribution and version combination is supported
func (d *distribution) validate() error {
// Get supported versions for this distribution

supportedDistros := imagecustomizerapi.GetSupportedDistros()
validVersions, exists := supportedDistros[d.name]
if !exists {
distros := make([]string, 0, len(supportedDistros))
for d := range supportedDistros {
distros = append(distros, d)
}
return fmt.Errorf("unsupported distribution %q. Supported distributions are: %s",
d.name, strings.Join(distros, ", "))
}

// Validate version
for _, v := range validVersions {
if v == d.version {
return nil
}
}
return fmt.Errorf("unsupported version %q for distribution %q. Supported versions: %s",
d.version, d.name, strings.Join(validVersions, ", "))
}
11 changes: 8 additions & 3 deletions toolkit/tools/imagecreator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type ImageCreatorCmd struct {
OutputImageFile string `name:"output-image-file" help:"Path to write the customized image to."`
OutputImageFormat string `name:"output-image-format" placeholder:"(vhd|vhd-fixed|vhdx|qcow2|raw)" help:"Format of output image." enum:"${imageformat}" default:""`
Distro string `name:"distro" help:"Target distribution for the image." enum:"azurelinux,fedora" default:"azurelinux"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we ever expect a config file to be usable by more than 1 distro and/or version? If not, then it would probably make sense to remove the distro and distro-version and add equivalent fields into the config file instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the same config file would work for fedora and azurelinux

DistroVersion string `name:"distro-version" help:"Target distribution version (e.g., 3.0 for Azure Linux, 42 for Fedora)." default:""`
DistroVersion string `name:"distro-version" help:"Target distribution version (e.g., 3.0 for Azure Linux, 42 for Fedora)." default:"3.0"`
exekong.LogFlags
PackageSnapshotTime string `name:"package-snapshot-time" help:"Only packages published before this snapshot time will be available during customization. Supports 'YYYY-MM-DD' or full RFC3339 timestamp (e.g., 2024-05-20T23:59:59Z)."`
}
Expand All @@ -54,8 +54,13 @@ func main() {

logger.InitBestEffort(ptrutils.PtrTo(cli.LogFlags.AsLoggerFlags()))

err := imagecreatorlib.CreateImageWithConfigFile(ctx, cli.BuildDir, cli.ConfigFile, cli.RpmSources,
cli.ToolsTar, cli.OutputImageFile, cli.OutputImageFormat, cli.Distro, cli.DistroVersion,
dist, err := cli.getDistribution()
if err != nil {
log.Fatalf("invalid distribution arguments: %v", err)
}

err = imagecreatorlib.CreateImageWithConfigFile(ctx, cli.BuildDir, cli.ConfigFile, cli.RpmSources,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API validity checks should be done in imagecreatorlib. This will ensure imagecreatorlib is usable by itself.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The validity check should actually occur in imagecreatorlib, instead of just moving the validation code into imagecreatorlib.

The CLI package should be almost entirely free of any logic.

cli.ToolsTar, cli.OutputImageFile, cli.OutputImageFormat, dist.name, dist.version,
cli.PackageSnapshotTime)
if err != nil {
log.Fatalf("image creation failed:\n%v", err)
Expand Down
17 changes: 17 additions & 0 deletions toolkit/tools/imagecustomizerapi/distribution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

package imagecustomizerapi

const (
DistroNameAzureLinux string = "azurelinux"
DistroNameFedora string = "fedora"
)

func GetSupportedDistros() map[string][]string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image Customizer and Image Creator will likely have different support lists. So, it would be good to give this a name unique to Image Creator.

One option would be to create an imagecreatorapi package.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point. for now, this applies to both tools.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fedora isn't supported in Image Customizer yet. Also, the GetSupportedDistros function is only called by the imagecreatorlib package.

// supportedDistros defines valid distribution and version combinations
return map[string][]string{
DistroNameAzureLinux: {"2.0", "3.0"},
DistroNameFedora: {"42"},
}
}
23 changes: 2 additions & 21 deletions toolkit/tools/pkg/imagecustomizerlib/distrohandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,6 @@ import (
"github.com/microsoft/azure-linux-image-tools/toolkit/tools/internal/targetos"
)

// PackageManagerType represents the type of package manager
type PackageManagerType string

const (
packageManagerTDNF PackageManagerType = "tdnf"
packageManagerDNF PackageManagerType = "dnf"
)

// PackageType represents the type of package format
type PackageType string

// DistroName represents the distribution name
type DistroName string

const (
distroNameAzureLinux DistroName = "azurelinux"
distroNameFedora DistroName = "fedora"
)

// distroHandler represents the interface for distribution-specific configuration
type distroHandler interface {
GetTargetOs() targetos.TargetOs
Expand Down Expand Up @@ -68,9 +49,9 @@ func NewDistroHandlerFromImageConnection(imageConnection *imageconnection.ImageC
// NewDistroHandler creates the appropriate distro handler with version support (legacy)
func NewDistroHandler(distroName string, version string) distroHandler {
switch distroName {
case string(distroNameFedora):
case string(imagecustomizerapi.DistroNameFedora):
return newFedoraDistroHandler(version)
case string(distroNameAzureLinux):
case string(imagecustomizerapi.DistroNameAzureLinux):
return newAzureLinuxDistroHandler(version)
default:
panic("unsupported distro name: " + distroName)
Expand Down
Loading