omni/internal/backend/extensions/extensions.go
Utku Ozdemir 4a82cd0e8f
chore: rewrite renamed extension names on Talos version updates
If an extension is renamed between minor Talos versions, rewrite its name to the newer one on upgrades and to older one on downgrades.

Handle the rename of `xe-guest-utilities` to `xen-guest-agent` happened on `1.6->1.7`, which was previously not handled correctly.

Additionally, closes siderolabs/omni#519.

Signed-off-by: Utku Ozdemir <utku.ozdemir@siderolabs.com>
2024-08-28 13:48:17 +02:00

103 lines
3.3 KiB
Go

// Copyright (c) 2024 Sidero Labs, Inc.
//
// Use of this software is governed by the Business Source License
// included in the LICENSE file.
// Package extensions provides utilities to work with extensions.
package extensions
import (
"github.com/blang/semver"
"github.com/siderolabs/gen/containers"
"github.com/siderolabs/gen/xslices"
)
// OfficialPrefix is the prefix for the official extensions.
const OfficialPrefix = "siderolabs/"
var (
talosV170 = semver.MustParse("1.7.0")
talosV180 = semver.MustParse("1.8.0")
talosV17RenamedExtensions = newBiMap[string, string](map[string]string{
OfficialPrefix + "xe-guest-utilities": OfficialPrefix + "xen-guest-agent",
})
talosV18RenamedExtensions = newBiMap[string, string](map[string]string{
OfficialPrefix + "nvidia-container-toolkit": OfficialPrefix + "nvidia-container-toolkit-lts",
OfficialPrefix + "nvidia-open-gpu-kernel-modules": OfficialPrefix + "nvidia-open-gpu-kernel-modules-lts",
OfficialPrefix + "nonfree-kmod-nvidia": OfficialPrefix + "nonfree-kmod-nvidia-lts",
OfficialPrefix + "nvidia-fabricmanager": OfficialPrefix + "nvidia-fabric-manager-lts",
})
)
// MapNames maps the extension names to their correct final names, taking extensions with the wrong name in their manifests into account.
//
// It does not take renamed extensions into account, MapNamesByVersion should be used for that.
func MapNames(extensions []string) []string {
return xslices.Map(extensions, func(extension string) string {
// extensions with the wrong name in their manifests
switch extension {
case OfficialPrefix + "v4l-uvc":
return OfficialPrefix + "v4l-uvc-drivers"
case OfficialPrefix + "usb-modem":
return OfficialPrefix + "usb-modem-drivers"
case OfficialPrefix + "gasket":
return OfficialPrefix + "gasket-driver"
case OfficialPrefix + "talos-vmtoolsd":
return OfficialPrefix + "vmtoolsd-guest-agent"
default:
return extension
}
})
}
// MapNamesByVersion maps the extension names to their correct final names, taking both the extensions with the wrong name in their manifests and the renamed extensions into account.
//
// It is taken and adapted from here: https://github.com/siderolabs/image-factory/blob/9687413a9a85744c8d8254d6f8604c6a7854c244/internal/profile/profile.go#L267-L289
func MapNamesByVersion(extensions []string, talosVersion semver.Version) []string {
extensions = MapNames(extensions)
gte170 := talosVersion.GTE(talosV170)
gte180 := talosVersion.GTE(talosV180)
return xslices.Map(extensions, func(extension string) string {
return mapSingleNameByVersion(extension, gte170, gte180)
})
}
// mapSingleNameByVersion returns the renamed extension based on the talos version.
func mapSingleNameByVersion(extension string, gte170, gte180 bool) string {
if gte170 {
if name, ok := talosV17RenamedExtensions.Get(extension); ok {
return name
}
} else {
if name, ok := talosV17RenamedExtensions.GetInverse(extension); ok {
return name
}
}
if gte180 {
if name, ok := talosV18RenamedExtensions.Get(extension); ok {
return name
}
} else {
if name, ok := talosV18RenamedExtensions.GetInverse(extension); ok {
return name
}
}
return extension
}
func newBiMap[K, V comparable](m map[K]V) containers.BiMap[K, V] {
bm := containers.BiMap[K, V]{}
for k, v := range m {
bm.Set(k, v)
}
return bm
}