mirror of
https://github.com/lingble/talos.git
synced 2025-11-02 05:28:09 +00:00
fix: use imager incoming version for extension validation
Use the version coming from imager to validate extension constraints. Part of : #9694 Signed-off-by: Noel Georgi <git@frezbo.dev>
This commit is contained in:
@@ -16,11 +16,12 @@ import (
|
||||
|
||||
func (i *Installer) installExtensions() error {
|
||||
builder := extensions.Builder{
|
||||
InitramfsPath: fmt.Sprintf(constants.InitramfsAssetPath, i.options.Arch),
|
||||
Arch: i.options.Arch,
|
||||
ExtensionTreePath: constants.SystemExtensionsPath,
|
||||
Printf: log.Printf,
|
||||
Quirks: quirks.New(i.options.Version),
|
||||
InitramfsPath: fmt.Sprintf(constants.InitramfsAssetPath, i.options.Arch),
|
||||
Arch: i.options.Arch,
|
||||
ExtensionTreePath: constants.SystemExtensionsPath,
|
||||
ExtensionValidateContents: true,
|
||||
Printf: log.Printf,
|
||||
Quirks: quirks.New(i.options.Version),
|
||||
}
|
||||
|
||||
return builder.Build()
|
||||
|
||||
@@ -24,6 +24,8 @@ type Builder struct {
|
||||
Arch string
|
||||
// ExtensionTreePath is a path to the extracted extension tree.
|
||||
ExtensionTreePath string
|
||||
// ExtensionValidateContents enables validation of the extension contents.
|
||||
ExtensionValidateContents bool
|
||||
// Printf is used for logging.
|
||||
Printf func(format string, v ...any)
|
||||
// Quirks for the Talos version being used.
|
||||
@@ -95,8 +97,17 @@ func (builder *Builder) Build() error {
|
||||
func (builder *Builder) validateExtensions(extensions []*extensions.Extension) error {
|
||||
builder.Printf("validating system extensions")
|
||||
|
||||
opts := []extinterface.ValidationOption{
|
||||
extinterface.WithValidateConstraints(),
|
||||
extinterface.WithTalosVersion(builder.Quirks.Version()),
|
||||
}
|
||||
|
||||
if builder.ExtensionValidateContents {
|
||||
opts = append(opts, extinterface.WithValidateContents())
|
||||
}
|
||||
|
||||
for _, ext := range extensions {
|
||||
if err := ext.Validate(); err != nil {
|
||||
if err := ext.Validate(opts...); err != nil {
|
||||
return fmt.Errorf("error validating extension %q: %w", ext.Manifest.Metadata.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,11 +8,11 @@ import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/blang/semver/v4"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/siderolabs/talos/pkg/machinery/extensions"
|
||||
"github.com/siderolabs/talos/pkg/machinery/version"
|
||||
)
|
||||
|
||||
func TestLoadValidate(t *testing.T) {
|
||||
@@ -21,25 +21,19 @@ func TestLoadValidate(t *testing.T) {
|
||||
|
||||
assert.Equal(t, "gvisor", ext.Manifest.Metadata.Name)
|
||||
|
||||
// override Talos version to make it predictable
|
||||
oldVersion := version.Tag
|
||||
version.Tag = "v1.0.0"
|
||||
version, err := semver.Parse("1.0.0")
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
version.Tag = oldVersion
|
||||
})
|
||||
|
||||
assert.NoError(t, ext.Validate())
|
||||
assert.NoError(t, ext.Validate(
|
||||
extensions.WithValidateConstraints(),
|
||||
extensions.WithValidateContents(),
|
||||
extensions.WithTalosVersion(version),
|
||||
))
|
||||
}
|
||||
|
||||
func TestValidateFailures(t *testing.T) {
|
||||
// override Talos version to make it predictable
|
||||
oldVersion := version.Tag
|
||||
version.Tag = "v1.0.0"
|
||||
|
||||
t.Cleanup(func() {
|
||||
version.Tag = oldVersion
|
||||
})
|
||||
version, err := semver.Parse("1.0.0")
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
@@ -73,7 +67,12 @@ func TestValidateFailures(t *testing.T) {
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
err = ext.Validate()
|
||||
err = ext.Validate(
|
||||
extensions.WithValidateConstraints(),
|
||||
extensions.WithValidateContents(),
|
||||
extensions.WithTalosVersion(version),
|
||||
)
|
||||
|
||||
assert.EqualError(t, err, tt.validateError)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -16,24 +16,83 @@ import (
|
||||
"github.com/siderolabs/talos/pkg/machinery/version"
|
||||
)
|
||||
|
||||
// Validate the extension: compatibility, contents, etc.
|
||||
func (ext *Extension) Validate() error {
|
||||
if err := ext.validateConstraints(); err != nil {
|
||||
return err
|
||||
}
|
||||
// ValidationOptions are used to configure the validation process.
|
||||
type ValidationOptions struct {
|
||||
// ValidateContstraints enables validation of the extension constraints.
|
||||
ValidateContstraints bool
|
||||
// ValidateContents enables validation of the extension contents.
|
||||
ValidateContents bool
|
||||
|
||||
return ext.validateContents()
|
||||
// TalosVersion is the version of Talos to validate against.
|
||||
TalosVersion *semver.Version
|
||||
}
|
||||
|
||||
func (ext *Extension) validateConstraints() error {
|
||||
constraint := ext.Manifest.Metadata.Compatibility.Talos.Version
|
||||
// WithValidateConstraints enables validation of the extension constraints.
|
||||
func WithValidateConstraints() ValidationOption {
|
||||
return func(o *ValidationOptions) error {
|
||||
o.ValidateContstraints = true
|
||||
|
||||
if constraint != "" {
|
||||
talosVersion, err := semver.ParseTolerant(version.Tag)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithValidateContents enables validation of the extension contents.
|
||||
func WithValidateContents() ValidationOption {
|
||||
return func(o *ValidationOptions) error {
|
||||
o.ValidateContents = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithTalosVersion sets the Talos version to validate against.
|
||||
func WithTalosVersion(version semver.Version) ValidationOption {
|
||||
return func(o *ValidationOptions) error {
|
||||
o.TalosVersion = &version
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ValidationOption is a function that configures the validation options.
|
||||
type ValidationOption func(*ValidationOptions) error
|
||||
|
||||
// Validate the extension: compatibility, contents, etc.
|
||||
func (ext *Extension) Validate(opts ...ValidationOption) error {
|
||||
validationOptions := &ValidationOptions{}
|
||||
|
||||
for _, opt := range opts {
|
||||
if err := opt(validationOptions); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
if validationOptions.TalosVersion == nil {
|
||||
version, err := semver.ParseTolerant(version.Tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
validationOptions.TalosVersion = &version
|
||||
}
|
||||
|
||||
if validationOptions.ValidateContstraints {
|
||||
if err := ext.validateConstraints(*validationOptions.TalosVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if validationOptions.ValidateContents {
|
||||
return ext.validateContents()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ext *Extension) validateConstraints(talosVersion semver.Version) error {
|
||||
constraint := ext.Manifest.Metadata.Compatibility.Talos.Version
|
||||
|
||||
if constraint != "" {
|
||||
versionConstraint, err := semver.ParseRange(trim(constraint))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing Talos version constraint: %w", err)
|
||||
|
||||
@@ -29,6 +29,11 @@ func New(talosVersion string) Quirks {
|
||||
|
||||
var minVersionResetOption = semver.MustParse("1.4.0")
|
||||
|
||||
// Version returns the Talos version.
|
||||
func (q Quirks) Version() semver.Version {
|
||||
return *q.v
|
||||
}
|
||||
|
||||
// SupportsResetGRUBOption returns true if the Talos version supports the reset option in GRUB menu (image and ISO).
|
||||
func (q Quirks) SupportsResetGRUBOption() bool {
|
||||
// if the version doesn't parse, we assume it's latest Talos
|
||||
|
||||
Reference in New Issue
Block a user