pkg/utils: Support OSes that don't have the concept of a release

Operating system distributions like Arch Linux that follow a
rolling-release model don't have the concept of a release.  The latest
snapshot is the only available release.

A subsequent commit will add built-in support for Arch Linux.  Hence,
the code can no longer assume that every distribution will have a
matching release.

Note that just because an operating system distribution may not have the
concept of a release, it doesn't mean that it will accept an invalid
'release' option.

https://github.com/containers/toolbox/pull/1311
This commit is contained in:
Debarshi Ray 2023-06-07 16:33:55 +02:00
parent 774ce8bd07
commit ed76734eb6

View file

@ -46,11 +46,20 @@ type ParseReleaseFunc func(string) (string, error)
type Distro struct {
ContainerNamePrefix string
ImageBasename string
ReleaseRequired bool
GetDefaultRelease GetDefaultReleaseFunc
GetFullyQualifiedImage GetFullyQualifiedImageFunc
ParseRelease ParseReleaseFunc
}
type OptionValueSource int
const (
optionValueDefault OptionValueSource = iota
optionValueConfigFile
optionValueCLI
)
const (
containerNamePrefixFallback = "fedora-toolbox"
distroFallback = "fedora"
@ -102,6 +111,7 @@ var (
"fedora": {
"fedora-toolbox",
"fedora-toolbox",
true,
getDefaultReleaseFedora,
getFullyQualifiedImageFedora,
parseReleaseFedora,
@ -109,6 +119,7 @@ var (
"rhel": {
"rhel-toolbox",
"toolbox",
true,
getDefaultReleaseRHEL,
getFullyQualifiedImageRHEL,
parseReleaseRHEL,
@ -116,6 +127,7 @@ var (
"ubuntu": {
"ubuntu-toolbox",
"ubuntu-toolbox",
true,
getDefaultReleaseUbuntu,
getFullyQualifiedImageUbuntu,
parseReleaseUbuntu,
@ -820,29 +832,59 @@ func ResolveContainerAndImageNames(container, distroCLI, imageCLI, releaseCLI st
logrus.Debugf("Image (CLI): '%s'", imageCLI)
logrus.Debugf("Release (CLI): '%s'", releaseCLI)
distro, image, release := distroCLI, imageCLI, releaseCLI
distro, distroSource := distroCLI, optionValueCLI
image, release := imageCLI, releaseCLI
if distroCLI == "" {
distro = distroDefault
distro, distroSource = distroDefault, optionValueDefault
if viper.IsSet("general.distro") {
distro = viper.GetString("general.distro")
distro, distroSource = viper.GetString("general.distro"), optionValueConfigFile
}
}
if _, supportedDistro := supportedDistros[distro]; !supportedDistro {
distroObj, supportedDistro := supportedDistros[distro]
if !supportedDistro {
return "", "", "", &DistroError{distro, ErrDistroUnsupported}
}
if distro != distroDefault && releaseCLI == "" && !viper.IsSet("general.release") {
return "", "", "", &DistroError{distro, ErrDistroWithoutRelease}
}
if distro == distroDefault {
if releaseCLI == "" {
release = releaseDefault
if viper.IsSet("general.release") {
release = viper.GetString("general.release")
}
}
} else {
if distroObj.ReleaseRequired {
if releaseCLI == "" && !viper.IsSet("general.release") {
return "", "", "", &DistroError{distro, ErrDistroWithoutRelease}
}
if releaseCLI == "" {
release = viper.GetString("general.release")
}
if release == "" {
panicMsg := fmt.Sprintf("cannot find release for non-default distribution %s", distro)
panic(panicMsg)
}
} else {
switch distroSource {
case optionValueCLI:
// 'release' already set to 'releaseCLI'
case optionValueConfigFile:
if releaseCLI == "" {
if viper.IsSet("general.release") {
release = viper.GetString("general.release")
}
}
case optionValueDefault:
panic("distro must be non-default")
default:
panic("cannot handle new OptionValueSource")
}
}
}
release, err := parseRelease(distro, release)
if err != nil {