chore: split config.Registry into the separate resource

Required for #9614

Closes #9766

Signed-off-by: Dmitriy Matrenichev <dmitry.matrenichev@siderolabs.com>
This commit is contained in:
Dmitriy Matrenichev 2024-11-21 22:45:49 +03:00
parent c735d14928
commit ccc5a8d34c
No known key found for this signature in database
GPG Key ID: 94B473337258BFD5
30 changed files with 2672 additions and 114 deletions

View File

@ -5,6 +5,7 @@ package talos.resource.definitions.cri;
option go_package = "github.com/siderolabs/talos/pkg/machinery/api/resource/definitions/cri";
option java_package = "dev.talos.api.resource.definitions.cri";
import "common/common.proto";
import "google/protobuf/struct.proto";
import "resource/definitions/enums/enums.proto";
@ -14,6 +15,40 @@ message ImageCacheConfigSpec {
repeated string roots = 2;
}
// RegistriesConfigSpec describes status of rendered secrets.
message RegistriesConfigSpec {
map<string, RegistryMirrorConfig> registry_mirrors = 1;
map<string, RegistryConfig> registry_config = 2;
}
// RegistryAuthConfig specifies authentication configuration for a registry.
message RegistryAuthConfig {
string registry_username = 1;
string registry_password = 2;
string registry_auth = 3;
string registry_identity_token = 4;
}
// RegistryConfig specifies auth & TLS config per registry.
message RegistryConfig {
RegistryTLSConfig registry_tls = 1;
RegistryAuthConfig registry_auth = 2;
}
// RegistryMirrorConfig represents mirror configuration for a registry.
message RegistryMirrorConfig {
repeated string mirror_endpoints = 1;
bool mirror_override_path = 2;
bool mirror_skip_fallback = 3;
}
// RegistryTLSConfig specifies TLS config for HTTPS registries.
message RegistryTLSConfig {
common.PEMEncodedCertificateAndKey tls_client_identity = 1;
bytes tlsca = 2;
bool tls_insecure_skip_verify = 3;
}
// SeccompProfileSpec represents the SeccompProfile.
message SeccompProfileSpec {
string name = 1;

View File

@ -396,6 +396,12 @@ func formatTypeName(fieldTypePkg string, fieldType string, declPkg string) (stri
return commoProto, "common.PEMEncodedCertificate"
case typeData{"github.com/siderolabs/talos/pkg/machinery/cel", "Expression"}:
return "google/api/expr/v1alpha1/checked.proto", "google.api.expr.v1alpha1.CheckedExpr"
case typeData{"github.com/siderolabs/talos/pkg/machinery/resources/cri", "RegistryMirrorConfig"}:
// This is a hack, but I (Dmitry) don't have enough patience to figure out why we don't support complex maps
return "resource/definitions/cri/registry.proto", "talos.resource.definitions.cri.RegistryMirrorConfig"
case typeData{"github.com/siderolabs/talos/pkg/machinery/resources/cri", "RegistryConfig"}:
// This is a hack, but I (Dmitry) don't have enough patience to figure out why we don't support complex maps
return "resource/definitions/cri/registry.proto", "talos.resource.definitions.cri.RegistryConfig"
default:
return "", ""
}

View File

@ -19,6 +19,7 @@ import (
"github.com/siderolabs/talos/pkg/machinery/api/common"
"github.com/siderolabs/talos/pkg/machinery/api/machine"
"github.com/siderolabs/talos/pkg/machinery/constants"
"github.com/siderolabs/talos/pkg/machinery/resources/cri"
)
func containerdNamespaceHelper(ctx context.Context, ns common.ContainerdNamespace) (context.Context, error) {
@ -91,7 +92,7 @@ func (s *Server) ImagePull(ctx context.Context, req *machine.ImagePullRequest) (
return nil, err
}
_, err = image.Pull(ctx, s.Controller.Runtime().Config().Machine().Registries(), client, req.Reference, image.WithSkipIfAlreadyPulled())
_, err = image.Pull(ctx, cri.RegistryBuilder(s.Controller.Runtime().State().V1Alpha2().Resources()), client, req.Reference, image.WithSkipIfAlreadyPulled())
if err != nil {
if errdefs.IsNotFound(err) {
return nil, status.Errorf(codes.NotFound, "error pulling image: %s", err)

View File

@ -83,6 +83,7 @@ import (
"github.com/siderolabs/talos/pkg/machinery/meta"
"github.com/siderolabs/talos/pkg/machinery/nethelpers"
"github.com/siderolabs/talos/pkg/machinery/resources/block"
crires "github.com/siderolabs/talos/pkg/machinery/resources/cri"
etcdresource "github.com/siderolabs/talos/pkg/machinery/resources/etcd"
"github.com/siderolabs/talos/pkg/machinery/resources/network"
timeresource "github.com/siderolabs/talos/pkg/machinery/resources/time"
@ -482,7 +483,7 @@ func (s *Server) Upgrade(ctx context.Context, in *machine.UpgradeRequest) (*mach
log.Printf("validating %q", in.GetImage())
if err := install.PullAndValidateInstallerImage(ctx, s.Controller.Runtime().Config().Machine().Registries(), in.GetImage()); err != nil {
if err := install.PullAndValidateInstallerImage(ctx, crires.RegistryBuilder(s.Controller.Runtime().State().V1Alpha2().Resources()), in.GetImage()); err != nil {
return nil, fmt.Errorf("error validating installer image %q: %w", in.GetImage(), err)
}

View File

@ -0,0 +1,118 @@
// 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 cri
import (
"context"
"fmt"
"github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/controller/generic/transform"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/gen/optional"
"go.uber.org/zap"
"github.com/siderolabs/talos/pkg/machinery/constants"
"github.com/siderolabs/talos/pkg/machinery/resources/config"
"github.com/siderolabs/talos/pkg/machinery/resources/cri"
)
// RegistriesConfigController watches v1alpha1.Config, updates registry.RegistriesConfig.
type RegistriesConfigController = transform.Controller[*config.MachineConfig, *cri.RegistriesConfig]
// NewRegistriesConfigController creates new config controller.
//
//nolint:gocyclo
func NewRegistriesConfigController() *RegistriesConfigController {
return transform.NewController(
transform.Settings[*config.MachineConfig, *cri.RegistriesConfig]{
Name: "cri.RegistriesConfigController",
MapMetadataOptionalFunc: func(cfg *config.MachineConfig) optional.Optional[*cri.RegistriesConfig] {
if cfg.Metadata().ID() != config.V1Alpha1ID {
return optional.None[*cri.RegistriesConfig]()
}
return optional.Some(cri.NewRegistriesConfig())
},
TransformFunc: func(ctx context.Context, r controller.Reader, logger *zap.Logger, cfg *config.MachineConfig, res *cri.RegistriesConfig) error {
imageCacheConfig, err := safe.ReaderGetByID[*cri.ImageCacheConfig](ctx, r, cri.ImageCacheConfigID)
if err != nil && !state.IsNotFoundError(err) {
return fmt.Errorf("failed to get image cache config: %w", err)
}
spec := res.TypedSpec()
spec.RegistryConfig = clearInit(spec.RegistryConfig)
spec.RegistryMirrors = clearInit(spec.RegistryMirrors)
if cfg != nil && cfg.Config().Machine() != nil {
// This is breaking our interface abstraction, but we need to get the underlying types for protobuf
// encoding to work correctly.
mr := cfg.Provider().RawV1Alpha1().MachineConfig.MachineRegistries
for k, v := range mr.RegistryConfig {
spec.RegistryConfig[k] = &cri.RegistryConfig{
RegistryTLS: &cri.RegistryTLSConfig{
TLSClientIdentity: v.RegistryTLS.TLSClientIdentity,
TLSCA: v.RegistryTLS.TLSCA,
TLSInsecureSkipVerify: v.RegistryTLS.TLSInsecureSkipVerify,
},
RegistryAuth: &cri.RegistryAuthConfig{
RegistryUsername: v.RegistryAuth.RegistryUsername,
RegistryPassword: v.RegistryAuth.RegistryPassword,
RegistryAuth: v.RegistryAuth.RegistryAuth,
RegistryIdentityToken: v.RegistryAuth.RegistryIdentityToken,
},
}
}
for k, v := range mr.RegistryMirrors {
spec.RegistryMirrors[k] = &cri.RegistryMirrorConfig{
MirrorEndpoints: v.MirrorEndpoints,
MirrorOverridePath: v.MirrorOverridePath,
MirrorSkipFallback: v.MirrorSkipFallback,
}
}
}
if imageCacheConfig != nil && imageCacheConfig.TypedSpec().Status == cri.ImageCacheStatusReady {
// if the '*' was configured, we just use it, otherwise create it so that we can inject the registryd
if _, hasStar := spec.RegistryMirrors["*"]; !hasStar {
spec.RegistryMirrors["*"] = &cri.RegistryMirrorConfig{}
}
// inject the registryd mirror endpoint as the first one for all registries
for registry := range spec.RegistryMirrors {
spec.RegistryMirrors[registry].MirrorEndpoints = append(
[]string{"http://" + constants.RegistrydListenAddress},
spec.RegistryMirrors[registry].MirrorEndpoints...,
)
}
}
return nil
},
},
transform.WithExtraInputs(
controller.Input{
Namespace: cri.NamespaceName,
Type: cri.ImageCacheConfigType,
ID: optional.Some(cri.ImageCacheConfigID),
Kind: controller.InputWeak,
},
),
)
}
func clearInit[M ~map[K]V, K comparable, V any](m M) M {
if m == nil {
return make(M)
}
clear(m)
return m
}

View File

@ -0,0 +1,113 @@
// 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 cri_test
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"github.com/siderolabs/talos/internal/app/machined/pkg/controllers/cri"
"github.com/siderolabs/talos/internal/app/machined/pkg/controllers/ctest"
"github.com/siderolabs/talos/pkg/machinery/config/container"
"github.com/siderolabs/talos/pkg/machinery/config/types/v1alpha1"
"github.com/siderolabs/talos/pkg/machinery/constants"
"github.com/siderolabs/talos/pkg/machinery/resources/config"
crires "github.com/siderolabs/talos/pkg/machinery/resources/cri"
)
type ConfigSuite struct {
ctest.DefaultSuite
}
func (suite *ConfigSuite) TestRegistry() {
cfg := config.NewMachineConfig(container.NewV1Alpha1(&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachineType: "controlplane",
MachineRegistries: v1alpha1.RegistriesConfig{
RegistryMirrors: map[string]*v1alpha1.RegistryMirrorConfig{
"docker.io": {MirrorEndpoints: []string{"https://mirror.io"}},
},
},
},
}))
suite.Require().NoError(suite.State().Create(suite.Ctx(), cfg))
ctest.AssertResource(suite, crires.RegistriesConfigID, func(r *crires.RegistriesConfig, a *assert.Assertions) {
spec := r.TypedSpec()
a.Equal(
map[string]*crires.RegistryMirrorConfig{
"docker.io": {MirrorEndpoints: []string{"https://mirror.io"}},
},
spec.RegistryMirrors,
)
})
ic := crires.NewImageCacheConfig()
ic.TypedSpec().Roots = []string{"/imagecache"}
ic.TypedSpec().Status = crires.ImageCacheStatusReady
suite.Require().NoError(suite.State().Create(suite.Ctx(), ic))
ctest.AssertResource(suite, crires.RegistriesConfigID, func(r *crires.RegistriesConfig, a *assert.Assertions) {
spec := r.TypedSpec()
a.Equal(
map[string]*crires.RegistryMirrorConfig{
"*": {MirrorEndpoints: []string{
"http://" + constants.RegistrydListenAddress,
}},
"docker.io": {MirrorEndpoints: []string{
"http://" + constants.RegistrydListenAddress,
"https://mirror.io",
}},
},
spec.RegistryMirrors,
)
})
}
func (suite *ConfigSuite) TestRegistryNoMachineConfig() {
cfg := config.NewMachineConfig(container.NewV1Alpha1(nil))
suite.Require().NoError(suite.State().Create(suite.Ctx(), cfg))
ic := crires.NewImageCacheConfig()
ic.TypedSpec().Roots = []string{"/imagecache"}
ic.TypedSpec().Status = crires.ImageCacheStatusReady
suite.Require().NoError(suite.State().Create(suite.Ctx(), ic))
ctest.AssertResource(suite, crires.RegistriesConfigID, func(r *crires.RegistriesConfig, a *assert.Assertions) {
spec := r.TypedSpec()
a.Equal(
map[string]*crires.RegistryMirrorConfig{
"*": {MirrorEndpoints: []string{
"http://" + constants.RegistrydListenAddress,
}},
},
spec.RegistryMirrors,
)
})
}
func TestConfigSuite(t *testing.T) {
t.Parallel()
suite.Run(t, &ConfigSuite{
DefaultSuite: ctest.DefaultSuite{
Timeout: 5 * time.Second,
AfterSetup: func(s *ctest.DefaultSuite) {
s.Require().NoError(s.Runtime().RegisterController(cri.NewRegistriesConfigController()))
},
},
})
}

View File

@ -22,7 +22,7 @@ import (
"github.com/siderolabs/talos/internal/pkg/containers/cri/containerd"
"github.com/siderolabs/talos/pkg/machinery/constants"
"github.com/siderolabs/talos/pkg/machinery/resources/config"
"github.com/siderolabs/talos/pkg/machinery/resources/cri"
"github.com/siderolabs/talos/pkg/machinery/resources/files"
)
@ -40,9 +40,9 @@ func (ctrl *CRIRegistryConfigController) Name() string {
func (ctrl *CRIRegistryConfigController) Inputs() []controller.Input {
return []controller.Input{
{
Namespace: config.NamespaceName,
Type: config.MachineConfigType,
ID: optional.Some(config.V1Alpha1ID),
Namespace: cri.NamespaceName,
Type: cri.RegistriesConfigType,
ID: optional.Some(cri.RegistriesConfigID),
Kind: controller.InputWeak,
},
}
@ -88,9 +88,9 @@ func (ctrl *CRIRegistryConfigController) Run(ctx context.Context, r controller.R
case <-r.EventCh():
}
cfg, err := safe.ReaderGetByID[*config.MachineConfig](ctx, r, config.V1Alpha1ID)
cfg, err := safe.ReaderGetByID[*cri.RegistriesConfig](ctx, r, cri.RegistriesConfigID)
if err != nil && !state.IsNotFoundError(err) {
return fmt.Errorf("error getting config: %w", err)
return fmt.Errorf("error getting registries config: %w", err)
}
var (
@ -98,13 +98,13 @@ func (ctrl *CRIRegistryConfigController) Run(ctx context.Context, r controller.R
criHosts *containerd.HostsConfig
)
if cfg != nil && cfg.Config().Machine() != nil {
criRegistryContents, err = containerd.GenerateCRIConfig(cfg.Config().Machine().Registries())
if cfg != nil {
criRegistryContents, err = containerd.GenerateCRIConfig(cfg.TypedSpec())
if err != nil {
return err
}
criHosts, err = containerd.GenerateHosts(cfg.Config().Machine().Registries(), basePath)
criHosts, err = containerd.GenerateHosts(cfg.TypedSpec(), basePath)
if err != nil {
return err
}

View File

@ -70,6 +70,7 @@ import (
"github.com/siderolabs/talos/pkg/machinery/constants"
metamachinery "github.com/siderolabs/talos/pkg/machinery/meta"
blockres "github.com/siderolabs/talos/pkg/machinery/resources/block"
crires "github.com/siderolabs/talos/pkg/machinery/resources/cri"
resourcefiles "github.com/siderolabs/talos/pkg/machinery/resources/files"
"github.com/siderolabs/talos/pkg/machinery/resources/k8s"
resourceruntime "github.com/siderolabs/talos/pkg/machinery/resources/runtime"
@ -1513,6 +1514,7 @@ func Upgrade(_ runtime.Sequence, data any) (runtime.TaskExecutionFunc, string) {
in.GetImage(),
r.Config(),
r.ConfigContainer(),
crires.RegistryBuilder(r.State().V1Alpha2().Resources()),
install.OptionsFromUpgradeRequest(r, in)...,
)
if err != nil {
@ -1687,6 +1689,12 @@ func Install(runtime.Sequence, any) (runtime.TaskExecutionFunc, string) {
installerImage = images.DefaultInstallerImage
}
logger.Printf("waiting for the image cache")
if err = crires.WaitForImageCache(ctx, r.State().V1Alpha2().Resources()); err != nil {
return fmt.Errorf("failed to wait for the image cache: %w", err)
}
var disk string
matchExpr, err := r.Config().Machine().Install().DiskMatchExpression()
@ -1725,6 +1733,7 @@ func Install(runtime.Sequence, any) (runtime.TaskExecutionFunc, string) {
installerImage,
r.Config(),
r.ConfigContainer(),
crires.RegistryBuilder(r.State().V1Alpha2().Resources()),
install.WithForce(true),
install.WithZero(r.Config().Machine().Install().Zero()),
install.WithExtraKernelArgs(r.Config().Machine().Install().ExtraKernelArgs()),
@ -1772,6 +1781,12 @@ func Install(runtime.Sequence, any) (runtime.TaskExecutionFunc, string) {
return fmt.Errorf("error unserializing install options: %w", err)
}
logger.Printf("waiting for the image cache")
if err = crires.WaitForImageCache(ctx, r.State().V1Alpha2().Resources()); err != nil {
return fmt.Errorf("failed to wait for the image cache: %w", err)
}
logger.Printf("performing staged upgrade via %q", r.State().Machine().StagedInstallImageRef())
err = install.RunInstallerContainer(
@ -1779,6 +1794,7 @@ func Install(runtime.Sequence, any) (runtime.TaskExecutionFunc, string) {
r.State().Machine().StagedInstallImageRef(),
r.Config(),
r.ConfigContainer(),
crires.RegistryBuilder(r.State().V1Alpha2().Resources()),
install.WithOptions(options),
)
if err != nil {

View File

@ -278,6 +278,7 @@ func (ctrl *Controller) Run(ctx context.Context, drainer *runtime.Drainer) error
&network.TimeServerMergeController{},
&network.TimeServerSpecController{},
&perf.StatsController{},
cri.NewRegistriesConfigController(),
&runtimecontrollers.CRIImageGCController{},
&runtimecontrollers.DevicesStatusController{
V1Alpha1Mode: ctrl.v1alpha1Runtime.State().Platform().Mode(),

View File

@ -186,6 +186,7 @@ func NewState() (*State, error) {
&network.TimeServerSpec{},
&perf.CPU{},
&perf.Memory{},
&cri.RegistriesConfig{},
&runtime.DevicesStatus{},
&runtime.Diagnostic{},
&runtime.EventSinkConfig{},

View File

@ -50,6 +50,7 @@ import (
"github.com/siderolabs/talos/pkg/machinery/constants"
"github.com/siderolabs/talos/pkg/machinery/meta"
"github.com/siderolabs/talos/pkg/machinery/nethelpers"
"github.com/siderolabs/talos/pkg/machinery/resources/cri"
etcdresource "github.com/siderolabs/talos/pkg/machinery/resources/etcd"
"github.com/siderolabs/talos/pkg/machinery/resources/k8s"
"github.com/siderolabs/talos/pkg/machinery/resources/network"
@ -120,7 +121,7 @@ func (e *Etcd) PreFunc(ctx context.Context, r runtime.Runtime) error {
return fmt.Errorf("failed to get etcd spec: %w", err)
}
img, err := image.Pull(containerdctx, r.Config().Machine().Registries(), client, spec.TypedSpec().Image, image.WithSkipIfAlreadyPulled())
img, err := image.Pull(containerdctx, cri.RegistryBuilder(r.State().V1Alpha2().Resources()), client, spec.TypedSpec().Image, image.WithSkipIfAlreadyPulled())
if err != nil {
return fmt.Errorf("failed to pull image %q: %w", spec.TypedSpec().Image, err)
}

View File

@ -33,6 +33,7 @@ import (
"github.com/siderolabs/talos/pkg/conditions"
"github.com/siderolabs/talos/pkg/machinery/config/machine"
"github.com/siderolabs/talos/pkg/machinery/constants"
"github.com/siderolabs/talos/pkg/machinery/resources/cri"
"github.com/siderolabs/talos/pkg/machinery/resources/k8s"
"github.com/siderolabs/talos/pkg/machinery/resources/network"
timeresource "github.com/siderolabs/talos/pkg/machinery/resources/time"
@ -70,7 +71,7 @@ func (k *Kubelet) PreFunc(ctx context.Context, r runtime.Runtime) error {
// Pull the image and unpack it.
containerdctx := namespaces.WithNamespace(ctx, constants.SystemContainerdNamespace)
img, err := image.Pull(containerdctx, r.Config().Machine().Registries(), client, spec.Image, image.WithSkipIfAlreadyPulled())
img, err := image.Pull(containerdctx, cri.RegistryBuilder(r.State().V1Alpha2().Resources()), client, spec.Image, image.WithSkipIfAlreadyPulled())
if err != nil {
return err
}

View File

@ -7,7 +7,6 @@ package main
import (
"context"
"fmt"
"io/fs"
"os"
"os/signal"
"path/filepath"
@ -38,9 +37,9 @@ func app() error {
return fmt.Errorf("failed to get user home directory: %w", err)
}
it := func(yield func(fs.StatFS) bool) {
it := func(yield func(string) bool) {
for _, root := range []string{"registry-cache-2", "registry-cache"} {
if !yield(os.DirFS(filepath.Join(homeDir, root)).(fs.StatFS)) {
if !yield(filepath.Join(homeDir, root)) {
return
}
}

View File

@ -5,27 +5,33 @@
package registry
import (
"errors"
"io/fs"
"iter"
"os"
"path/filepath"
"github.com/hashicorp/go-multierror"
)
// MultiPathFS is a FS that can be used to combine multiple FSs into one.
// MultiPathFS is a [fs.FS] that reads from multiple paths sequentially until it finds the file.
type MultiPathFS struct {
fsIt iter.Seq[fs.StatFS]
fsIt iter.Seq[string]
}
// NewMultiPathFS creates a new MultiPathFS. It takes an iterator of FSs which can be used multiple times asynchrously.
func NewMultiPathFS(it iter.Seq[fs.StatFS]) *MultiPathFS { return &MultiPathFS{fsIt: it} }
func NewMultiPathFS(it iter.Seq[string]) *MultiPathFS { return &MultiPathFS{fsIt: it} }
// Open opens the named file.
func (m *MultiPathFS) Open(name string) (fs.File, error) {
var multiErr *multierror.Error
for f := range m.fsIt {
r, err := f.Open(name)
for root := range m.fsIt {
abs, err := filepath.Abs(root)
if err != nil {
return nil, err
}
r, err := os.Open(filepath.Join(abs, name))
if err == nil {
return r, nil
}
@ -34,7 +40,7 @@ func (m *MultiPathFS) Open(name string) (fs.File, error) {
}
if multiErr == nil {
return nil, errors.New("roots are empty")
return nil, os.ErrNotExist
}
return nil, multiErr.ErrorOrNil()
@ -44,8 +50,13 @@ func (m *MultiPathFS) Open(name string) (fs.File, error) {
func (m *MultiPathFS) Stat(name string) (fs.FileInfo, error) {
var multiErr *multierror.Error
for f := range m.fsIt {
r, err := f.Stat(name)
for root := range m.fsIt {
abs, err := filepath.Abs(root)
if err != nil {
return nil, err
}
r, err := os.Stat(filepath.Join(abs, name))
if err == nil {
return r, nil
}
@ -54,7 +65,7 @@ func (m *MultiPathFS) Stat(name string) (fs.FileInfo, error) {
}
if multiErr == nil {
return nil, errors.New("roots are empty")
return nil, os.ErrNotExist
}
return nil, multiErr.ErrorOrNil()

View File

@ -22,7 +22,7 @@ func extractParams(req *http.Request) (params, error) {
value := req.PathValue("args")
parts := strings.Split(path.Clean(value), "/")
if len(parts) < 4 {
if len(parts) < 3 {
return params{}, xerrors.NewTaggedf[notFoundTag]("incorrect args value '%s'", value)
}

View File

@ -184,11 +184,11 @@ func (svc *Service) resolveCanonicalRef(p params) (reference.Canonical, error) {
ntSum, err := hashFile(taggedFile, svc.root)
if err != nil {
if !errors.Is(err, os.ErrNotExist) {
return nil, xerrors.NewTaggedf[internalErrorTag]("failed to hash manifest: %w", err)
if errors.Is(err, os.ErrNotExist) {
return nil, xerrors.NewTagged[notFoundTag](err)
}
return nil, xerrors.NewTagged[notFoundTag](err)
return nil, xerrors.NewTaggedf[internalErrorTag]("failed to hash manifest: %w", err)
}
sha256file := filepath.Join("manifests", namedTagged.Name(), "digest", digest.NewDigestFromBytes(digest.SHA256, ntSum).String())

View File

@ -0,0 +1,147 @@
// 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 registry_test
import (
"cmp"
"context"
"errors"
"io"
"net/http"
"strings"
"sync"
"testing"
"time"
"github.com/siderolabs/gen/xiter"
"github.com/siderolabs/gen/xtesting/check"
"github.com/siderolabs/go-pointer"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zaptest"
"github.com/siderolabs/talos/internal/app/machined/pkg/system/services/registry"
"github.com/siderolabs/talos/pkg/machinery/constants"
)
func TestRegistry(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
logger := zaptest.NewLogger(t)
svc := registry.NewService(registry.NewMultiPathFS(xiter.Single("test")), logger)
var wg sync.WaitGroup
wg.Add(1)
ctx, cancel := context.WithCancelCause(context.Background())
defer cancel(nil)
go func() {
defer wg.Done()
cancel(cmp.Or(svc.Run(ctx), errors.New("service exited")))
}()
defer wg.Wait()
time.Sleep(100 * time.Millisecond)
tests := []struct {
name string
path string
method string
body io.Reader
check check.Check
expectedCode int
}{
{
name: "HEAD /v2/",
path: "/v2/",
method: http.MethodHead,
check: check.NoError(),
expectedCode: http.StatusOK,
},
{
name: "GET /v2/",
path: "/v2/",
method: http.MethodGet,
check: check.NoError(),
expectedCode: http.StatusOK,
},
{
name: "HEAD /healthz",
path: "/healthz",
method: http.MethodHead,
check: check.NoError(),
expectedCode: http.StatusOK,
},
{
name: "GET /healthz",
path: "/healthz",
method: http.MethodGet,
check: check.NoError(),
expectedCode: http.StatusOK,
},
{
name: "GET /v2/alpine/manifests/3.20.3",
path: "/v2/alpine/manifests/3.20.3",
method: http.MethodGet,
check: check.NoError(),
expectedCode: http.StatusBadRequest,
},
{
name: "GET /v2/alpine/manifests/3.20.3?ns=docker.io",
path: "/v2/alpine/manifests/3.20.3?ns=docker.io",
method: http.MethodGet,
check: check.NoError(),
expectedCode: http.StatusNotFound,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
req, err := http.NewRequestWithContext(ctx, test.method, "http://"+constants.RegistrydListenAddress+test.path, test.body)
require.NoError(t, err)
resp, err := http.DefaultClient.Do(req)
test.check(t, err)
if resp != nil {
defer resp.Body.Close() //nolint:errcheck
}
require.Equal(t, test.expectedCode, pointer.SafeDeref(resp).StatusCode, "unexpected status code, body is %s", readAll(t, resp))
})
}
cancel(nil)
wg.Wait()
err := ctx.Err()
if err == context.Canceled || err == context.DeadlineExceeded {
err = nil
}
require.NoError(t, err)
}
func readAll(t *testing.T, resp *http.Response) string {
if resp == nil || resp.Body == nil {
return "<no response>"
}
var builder strings.Builder
_, err := io.Copy(&builder, resp.Body)
require.NoError(t, err)
if builder.String() == "" {
return "<empty response>"
}
return builder.String()
}

View File

@ -7,10 +7,10 @@ package services
import (
"context"
"io"
"io/fs"
"os"
"github.com/cosi-project/runtime/pkg/safe"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime"
@ -47,28 +47,33 @@ func (r *registryD) HealthFunc(runtime.Runtime) health.Check {
}
func (r *registryD) Runner(rt runtime.Runtime) (runner.Runner, error) {
it := func(yield func(fs.StatFS) bool) {
imageCacheConfig, err := safe.StateGetByID[*cri.ImageCacheConfig](context.Background(), rt.State().V1Alpha2().Resources(), cri.ImageCacheConfigID)
if err != nil {
// we can't handle it here
return
}
return goroutine.NewRunner(rt, "registryd", func(ctx context.Context, r runtime.Runtime, logOutput io.Writer) error {
logger := logging.ZapLogger(
logging.NewLogDestination(logOutput, zapcore.DebugLevel, logging.WithColoredLevels()),
)
st := r.State().V1Alpha2().Resources()
it := func(yield func(string) bool) {
imageCacheConfig, err := safe.StateGetByID[*cri.ImageCacheConfig](ctx, st, cri.ImageCacheConfigID)
if err != nil {
logger.Error("failed to get image cache config", zap.Error(err))
for _, root := range imageCacheConfig.TypedSpec().Roots {
if !yield(os.DirFS(root).(fs.StatFS)) {
return
}
}
}
return goroutine.NewRunner(rt, "registryd", func(ctx context.Context, r runtime.Runtime, logOutput io.Writer) error {
return registry.NewService(
registry.NewMultiPathFS(it),
logging.ZapLogger(logging.NewLogDestination(
logOutput,
zapcore.DebugLevel,
logging.WithColoredLevels(),
)),
).Run(ctx)
for _, root := range imageCacheConfig.TypedSpec().Roots {
if _, err = os.Stat(root); err != nil {
logger.Error("failed to stat image cache root", zap.String("root", root), zap.Error(err))
continue
}
if !yield(root) {
return
}
}
}
return registry.NewService(registry.NewMultiPathFS(it), logger).Run(ctx)
}, runner.WithLoggingManager(rt.Logging())), nil
}

View File

@ -53,11 +53,14 @@ func WithSkipIfAlreadyPulled() PullOption {
}
}
// RegistriesBuilder is a function that returns registries configuration.
type RegistriesBuilder = func(context.Context) (config.Registries, error)
// Pull is a convenience function that wraps the containerd image pull func with
// retry functionality.
//
//nolint:gocyclo
func Pull(ctx context.Context, reg config.Registries, client *containerd.Client, ref string, opt ...PullOption) (img containerd.Image, err error) {
func Pull(ctx context.Context, registryBuilder RegistriesBuilder, client *containerd.Client, ref string, opt ...PullOption) (img containerd.Image, err error) {
var opts PullOptions
for _, o := range opt {
@ -96,9 +99,14 @@ func Pull(ctx context.Context, reg config.Registries, client *containerd.Client,
ctx = log.WithLogger(ctx, containerdLogger.WithField("image", ref))
resolver := NewResolver(reg)
err = retry.Exponential(PullTimeout, retry.WithUnits(PullRetryInterval), retry.WithErrorLogging(true)).RetryWithContext(ctx, func(ctx context.Context) error {
registriesConfig, err := registryBuilder(ctx)
if err != nil {
return fmt.Errorf("failed to get configured registries: %w", err)
}
resolver := NewResolver(registriesConfig)
if img, err = client.Pull(
ctx,
ref,

View File

@ -48,7 +48,7 @@ func NewPuller(client *containerd.Client) (*Puller, error) {
}
// PullAndMount pulls the system extension images, unpacks them and mounts under well known path (constants.SystemExtensionsPath).
func (puller *Puller) PullAndMount(ctx context.Context, registryConfig config.Registries, extensions []config.Extension) error {
func (puller *Puller) PullAndMount(ctx context.Context, registriesBuilder image.RegistriesBuilder, extensions []config.Extension) error {
snapshotService := puller.client.SnapshotService(defaults.DefaultSnapshotter)
for i, ext := range extensions {
@ -61,7 +61,7 @@ func (puller *Puller) PullAndMount(ctx context.Context, registryConfig config.Re
var extImg containerd.Image
extImg, err := image.Pull(ctx, registryConfig, puller.client, extensionImage, image.WithSkipIfAlreadyPulled())
extImg, err := image.Pull(ctx, registriesBuilder, puller.client, extensionImage, image.WithSkipIfAlreadyPulled())
if err != nil {
return err
}

View File

@ -33,14 +33,19 @@ import (
machineapi "github.com/siderolabs/talos/pkg/machinery/api/machine"
configcore "github.com/siderolabs/talos/pkg/machinery/config"
"github.com/siderolabs/talos/pkg/machinery/config/config"
"github.com/siderolabs/talos/pkg/machinery/config/types/v1alpha1"
"github.com/siderolabs/talos/pkg/machinery/constants"
)
// RunInstallerContainer performs an installation via the installer container.
//
//nolint:gocyclo,cyclop
func RunInstallerContainer(disk, platform, ref string, cfg configcore.Config, cfgContainer configcore.Container, opts ...Option) error {
func RunInstallerContainer(
disk, platform, ref string,
cfg configcore.Config,
cfgContainer configcore.Container,
registryBuilder image.RegistriesBuilder,
opts ...Option,
) error {
const containerID = "upgrade"
options := DefaultInstallOptions()
@ -51,16 +56,10 @@ func RunInstallerContainer(disk, platform, ref string, cfg configcore.Config, cf
}
}
var (
registriesConfig config.Registries
extensionsConfig []config.Extension
)
var extensionsConfig []config.Extension
if cfg != nil && cfg.Machine() != nil {
registriesConfig = cfg.Machine().Registries()
extensionsConfig = cfg.Machine().Install().Extensions()
} else {
registriesConfig = &v1alpha1.RegistriesConfig{}
}
ctx, cancel := context.WithCancel(context.Background())
@ -89,7 +88,7 @@ func RunInstallerContainer(disk, platform, ref string, cfg configcore.Config, cf
if img == nil || err != nil && errdefs.IsNotFound(err) {
log.Printf("pulling %q", ref)
img, err = image.Pull(ctx, registriesConfig, client, ref)
img, err = image.Pull(ctx, registryBuilder, client, ref)
}
if err != nil {
@ -102,7 +101,7 @@ func RunInstallerContainer(disk, platform, ref string, cfg configcore.Config, cf
}
if extensionsConfig != nil {
if err = puller.PullAndMount(ctx, registriesConfig, extensionsConfig); err != nil {
if err = puller.PullAndMount(ctx, registryBuilder, extensionsConfig); err != nil {
return err
}
}

View File

@ -16,14 +16,13 @@ import (
"github.com/containerd/errdefs"
"github.com/siderolabs/talos/internal/pkg/containers/image"
"github.com/siderolabs/talos/pkg/machinery/config/config"
"github.com/siderolabs/talos/pkg/machinery/constants"
)
// PullAndValidateInstallerImage pulls down the installer and validates that it can run.
//
//nolint:gocyclo
func PullAndValidateInstallerImage(ctx context.Context, reg config.Registries, ref string) error {
func PullAndValidateInstallerImage(ctx context.Context, registryBuilder image.RegistriesBuilder, ref string) error {
// Pull down specified installer image early so we can bail if it doesn't exist in the upstream registry
containerdctx := namespaces.WithNamespace(ctx, constants.SystemContainerdNamespace)
@ -36,7 +35,7 @@ func PullAndValidateInstallerImage(ctx context.Context, reg config.Registries, r
defer client.Close() //nolint:errcheck
img, err := image.Pull(containerdctx, reg, client, ref, image.WithSkipIfAlreadyPulled())
img, err := image.Pull(containerdctx, registryBuilder, client, ref, image.WithSkipIfAlreadyPulled())
if err != nil {
return err
}

View File

@ -14,6 +14,7 @@ import (
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
structpb "google.golang.org/protobuf/types/known/structpb"
common "github.com/siderolabs/talos/pkg/machinery/api/common"
enums "github.com/siderolabs/talos/pkg/machinery/api/resource/definitions/enums"
)
@ -78,6 +79,308 @@ func (x *ImageCacheConfigSpec) GetRoots() []string {
return nil
}
// RegistriesConfigSpec describes status of rendered secrets.
type RegistriesConfigSpec struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
RegistryMirrors map[string]*RegistryMirrorConfig `protobuf:"bytes,1,rep,name=registry_mirrors,json=registryMirrors,proto3" json:"registry_mirrors,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
RegistryConfig map[string]*RegistryConfig `protobuf:"bytes,2,rep,name=registry_config,json=registryConfig,proto3" json:"registry_config,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
func (x *RegistriesConfigSpec) Reset() {
*x = RegistriesConfigSpec{}
mi := &file_resource_definitions_cri_cri_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RegistriesConfigSpec) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RegistriesConfigSpec) ProtoMessage() {}
func (x *RegistriesConfigSpec) ProtoReflect() protoreflect.Message {
mi := &file_resource_definitions_cri_cri_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RegistriesConfigSpec.ProtoReflect.Descriptor instead.
func (*RegistriesConfigSpec) Descriptor() ([]byte, []int) {
return file_resource_definitions_cri_cri_proto_rawDescGZIP(), []int{1}
}
func (x *RegistriesConfigSpec) GetRegistryMirrors() map[string]*RegistryMirrorConfig {
if x != nil {
return x.RegistryMirrors
}
return nil
}
func (x *RegistriesConfigSpec) GetRegistryConfig() map[string]*RegistryConfig {
if x != nil {
return x.RegistryConfig
}
return nil
}
// RegistryAuthConfig specifies authentication configuration for a registry.
type RegistryAuthConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
RegistryUsername string `protobuf:"bytes,1,opt,name=registry_username,json=registryUsername,proto3" json:"registry_username,omitempty"`
RegistryPassword string `protobuf:"bytes,2,opt,name=registry_password,json=registryPassword,proto3" json:"registry_password,omitempty"`
RegistryAuth string `protobuf:"bytes,3,opt,name=registry_auth,json=registryAuth,proto3" json:"registry_auth,omitempty"`
RegistryIdentityToken string `protobuf:"bytes,4,opt,name=registry_identity_token,json=registryIdentityToken,proto3" json:"registry_identity_token,omitempty"`
}
func (x *RegistryAuthConfig) Reset() {
*x = RegistryAuthConfig{}
mi := &file_resource_definitions_cri_cri_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RegistryAuthConfig) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RegistryAuthConfig) ProtoMessage() {}
func (x *RegistryAuthConfig) ProtoReflect() protoreflect.Message {
mi := &file_resource_definitions_cri_cri_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RegistryAuthConfig.ProtoReflect.Descriptor instead.
func (*RegistryAuthConfig) Descriptor() ([]byte, []int) {
return file_resource_definitions_cri_cri_proto_rawDescGZIP(), []int{2}
}
func (x *RegistryAuthConfig) GetRegistryUsername() string {
if x != nil {
return x.RegistryUsername
}
return ""
}
func (x *RegistryAuthConfig) GetRegistryPassword() string {
if x != nil {
return x.RegistryPassword
}
return ""
}
func (x *RegistryAuthConfig) GetRegistryAuth() string {
if x != nil {
return x.RegistryAuth
}
return ""
}
func (x *RegistryAuthConfig) GetRegistryIdentityToken() string {
if x != nil {
return x.RegistryIdentityToken
}
return ""
}
// RegistryConfig specifies auth & TLS config per registry.
type RegistryConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
RegistryTls *RegistryTLSConfig `protobuf:"bytes,1,opt,name=registry_tls,json=registryTls,proto3" json:"registry_tls,omitempty"`
RegistryAuth *RegistryAuthConfig `protobuf:"bytes,2,opt,name=registry_auth,json=registryAuth,proto3" json:"registry_auth,omitempty"`
}
func (x *RegistryConfig) Reset() {
*x = RegistryConfig{}
mi := &file_resource_definitions_cri_cri_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RegistryConfig) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RegistryConfig) ProtoMessage() {}
func (x *RegistryConfig) ProtoReflect() protoreflect.Message {
mi := &file_resource_definitions_cri_cri_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RegistryConfig.ProtoReflect.Descriptor instead.
func (*RegistryConfig) Descriptor() ([]byte, []int) {
return file_resource_definitions_cri_cri_proto_rawDescGZIP(), []int{3}
}
func (x *RegistryConfig) GetRegistryTls() *RegistryTLSConfig {
if x != nil {
return x.RegistryTls
}
return nil
}
func (x *RegistryConfig) GetRegistryAuth() *RegistryAuthConfig {
if x != nil {
return x.RegistryAuth
}
return nil
}
// RegistryMirrorConfig represents mirror configuration for a registry.
type RegistryMirrorConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
MirrorEndpoints []string `protobuf:"bytes,1,rep,name=mirror_endpoints,json=mirrorEndpoints,proto3" json:"mirror_endpoints,omitempty"`
MirrorOverridePath bool `protobuf:"varint,2,opt,name=mirror_override_path,json=mirrorOverridePath,proto3" json:"mirror_override_path,omitempty"`
MirrorSkipFallback bool `protobuf:"varint,3,opt,name=mirror_skip_fallback,json=mirrorSkipFallback,proto3" json:"mirror_skip_fallback,omitempty"`
}
func (x *RegistryMirrorConfig) Reset() {
*x = RegistryMirrorConfig{}
mi := &file_resource_definitions_cri_cri_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RegistryMirrorConfig) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RegistryMirrorConfig) ProtoMessage() {}
func (x *RegistryMirrorConfig) ProtoReflect() protoreflect.Message {
mi := &file_resource_definitions_cri_cri_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RegistryMirrorConfig.ProtoReflect.Descriptor instead.
func (*RegistryMirrorConfig) Descriptor() ([]byte, []int) {
return file_resource_definitions_cri_cri_proto_rawDescGZIP(), []int{4}
}
func (x *RegistryMirrorConfig) GetMirrorEndpoints() []string {
if x != nil {
return x.MirrorEndpoints
}
return nil
}
func (x *RegistryMirrorConfig) GetMirrorOverridePath() bool {
if x != nil {
return x.MirrorOverridePath
}
return false
}
func (x *RegistryMirrorConfig) GetMirrorSkipFallback() bool {
if x != nil {
return x.MirrorSkipFallback
}
return false
}
// RegistryTLSConfig specifies TLS config for HTTPS registries.
type RegistryTLSConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
TlsClientIdentity *common.PEMEncodedCertificateAndKey `protobuf:"bytes,1,opt,name=tls_client_identity,json=tlsClientIdentity,proto3" json:"tls_client_identity,omitempty"`
Tlsca []byte `protobuf:"bytes,2,opt,name=tlsca,proto3" json:"tlsca,omitempty"`
TlsInsecureSkipVerify bool `protobuf:"varint,3,opt,name=tls_insecure_skip_verify,json=tlsInsecureSkipVerify,proto3" json:"tls_insecure_skip_verify,omitempty"`
}
func (x *RegistryTLSConfig) Reset() {
*x = RegistryTLSConfig{}
mi := &file_resource_definitions_cri_cri_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RegistryTLSConfig) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RegistryTLSConfig) ProtoMessage() {}
func (x *RegistryTLSConfig) ProtoReflect() protoreflect.Message {
mi := &file_resource_definitions_cri_cri_proto_msgTypes[5]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RegistryTLSConfig.ProtoReflect.Descriptor instead.
func (*RegistryTLSConfig) Descriptor() ([]byte, []int) {
return file_resource_definitions_cri_cri_proto_rawDescGZIP(), []int{5}
}
func (x *RegistryTLSConfig) GetTlsClientIdentity() *common.PEMEncodedCertificateAndKey {
if x != nil {
return x.TlsClientIdentity
}
return nil
}
func (x *RegistryTLSConfig) GetTlsca() []byte {
if x != nil {
return x.Tlsca
}
return nil
}
func (x *RegistryTLSConfig) GetTlsInsecureSkipVerify() bool {
if x != nil {
return x.TlsInsecureSkipVerify
}
return false
}
// SeccompProfileSpec represents the SeccompProfile.
type SeccompProfileSpec struct {
state protoimpl.MessageState
@ -90,7 +393,7 @@ type SeccompProfileSpec struct {
func (x *SeccompProfileSpec) Reset() {
*x = SeccompProfileSpec{}
mi := &file_resource_definitions_cri_cri_proto_msgTypes[1]
mi := &file_resource_definitions_cri_cri_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -102,7 +405,7 @@ func (x *SeccompProfileSpec) String() string {
func (*SeccompProfileSpec) ProtoMessage() {}
func (x *SeccompProfileSpec) ProtoReflect() protoreflect.Message {
mi := &file_resource_definitions_cri_cri_proto_msgTypes[1]
mi := &file_resource_definitions_cri_cri_proto_msgTypes[6]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -115,7 +418,7 @@ func (x *SeccompProfileSpec) ProtoReflect() protoreflect.Message {
// Deprecated: Use SeccompProfileSpec.ProtoReflect.Descriptor instead.
func (*SeccompProfileSpec) Descriptor() ([]byte, []int) {
return file_resource_definitions_cri_cri_proto_rawDescGZIP(), []int{1}
return file_resource_definitions_cri_cri_proto_rawDescGZIP(), []int{6}
}
func (x *SeccompProfileSpec) GetName() string {
@ -139,32 +442,111 @@ var file_resource_definitions_cri_cri_proto_rawDesc = []byte{
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x63, 0x72, 0x69, 0x2f, 0x63, 0x72, 0x69, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x2e, 0x63, 0x72, 0x69, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x1a, 0x26, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x64, 0x65, 0x66,
0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2f, 0x65,
0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x7b, 0x0a, 0x14, 0x49, 0x6d,
0x61, 0x67, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x70,
0x65, 0x63, 0x12, 0x4d, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0e, 0x32, 0x35, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75,
0x2e, 0x63, 0x72, 0x69, 0x1a, 0x13, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d,
0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63,
0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x26, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x65, 0x6e,
0x75, 0x6d, 0x73, 0x2f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
0x7b, 0x0a, 0x14, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x43, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x53, 0x70, 0x65, 0x63, 0x12, 0x4d, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x35, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e,
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x43, 0x72, 0x69, 0x49, 0x6d,
0x61, 0x67, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06,
0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x18,
0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x22, 0xec, 0x03, 0x0a,
0x14, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x69, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x53, 0x70, 0x65, 0x63, 0x12, 0x74, 0x0a, 0x10, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72,
0x79, 0x5f, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x49, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x63, 0x72, 0x69,
0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x69, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x53, 0x70, 0x65, 0x63, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x4d, 0x69,
0x72, 0x72, 0x6f, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x72, 0x65, 0x67, 0x69,
0x73, 0x74, 0x72, 0x79, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x71, 0x0a, 0x0f, 0x72,
0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x48, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e,
0x73, 0x2e, 0x63, 0x72, 0x69, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x69, 0x65, 0x73,
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x70, 0x65, 0x63, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73,
0x74, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e,
0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x78,
0x0a, 0x14, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72,
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x4a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e,
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x63, 0x72, 0x69, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72,
0x79, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x71, 0x0a, 0x13, 0x52, 0x65, 0x67, 0x69,
0x73, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
0x79, 0x12, 0x44, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x2e, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x63, 0x72,
0x69, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xcb, 0x01, 0x0a, 0x12,
0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x41, 0x75, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x12, 0x2b, 0x0a, 0x11, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x5f, 0x75,
0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x72,
0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12,
0x2b, 0x0a, 0x11, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x5f, 0x70, 0x61, 0x73, 0x73,
0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x65, 0x67, 0x69,
0x73, 0x74, 0x72, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x23, 0x0a, 0x0d,
0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x18, 0x03, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x41, 0x75, 0x74,
0x68, 0x12, 0x36, 0x0a, 0x17, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x5f, 0x69, 0x64,
0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01,
0x28, 0x09, 0x52, 0x15, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x49, 0x64, 0x65, 0x6e,
0x74, 0x69, 0x74, 0x79, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xbf, 0x01, 0x0a, 0x0e, 0x52, 0x65,
0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x54, 0x0a, 0x0c,
0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x5f, 0x74, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e,
0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x43, 0x72, 0x69, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x43, 0x61,
0x63, 0x68, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
0x73, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09,
0x52, 0x05, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x22, 0x57, 0x0a, 0x12, 0x53, 0x65, 0x63, 0x63, 0x6f,
0x6d, 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a,
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
0x65, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x42, 0x70, 0x0a, 0x26, 0x64, 0x65, 0x76, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x63, 0x72, 0x69, 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68,
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69, 0x64, 0x65, 0x72, 0x6f, 0x6c, 0x61, 0x62,
0x73, 0x2f, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6d, 0x61, 0x63, 0x68,
0x69, 0x6e, 0x65, 0x72, 0x79, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x63,
0x72, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x63, 0x72, 0x69, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x54, 0x4c, 0x53, 0x43,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0b, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x54,
0x6c, 0x73, 0x12, 0x57, 0x0a, 0x0d, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x5f, 0x61,
0x75, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x74, 0x61, 0x6c, 0x6f,
0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x63, 0x72, 0x69, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73,
0x74, 0x72, 0x79, 0x41, 0x75, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0c, 0x72,
0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x41, 0x75, 0x74, 0x68, 0x22, 0xa5, 0x01, 0x0a, 0x14,
0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f,
0x6e, 0x66, 0x69, 0x67, 0x12, 0x29, 0x0a, 0x10, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x65,
0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f,
0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12,
0x30, 0x0a, 0x14, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69,
0x64, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x6d,
0x69, 0x72, 0x72, 0x6f, 0x72, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x50, 0x61, 0x74,
0x68, 0x12, 0x30, 0x0a, 0x14, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x73, 0x6b, 0x69, 0x70,
0x5f, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52,
0x12, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x6b, 0x69, 0x70, 0x46, 0x61, 0x6c, 0x6c, 0x62,
0x61, 0x63, 0x6b, 0x22, 0xb7, 0x01, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79,
0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x53, 0x0a, 0x13, 0x74, 0x6c, 0x73,
0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
0x50, 0x45, 0x4d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
0x69, 0x63, 0x61, 0x74, 0x65, 0x41, 0x6e, 0x64, 0x4b, 0x65, 0x79, 0x52, 0x11, 0x74, 0x6c, 0x73,
0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x14,
0x0a, 0x05, 0x74, 0x6c, 0x73, 0x63, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74,
0x6c, 0x73, 0x63, 0x61, 0x12, 0x37, 0x0a, 0x18, 0x74, 0x6c, 0x73, 0x5f, 0x69, 0x6e, 0x73, 0x65,
0x63, 0x75, 0x72, 0x65, 0x5f, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79,
0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x74, 0x6c, 0x73, 0x49, 0x6e, 0x73, 0x65, 0x63,
0x75, 0x72, 0x65, 0x53, 0x6b, 0x69, 0x70, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x22, 0x57, 0x0a,
0x12, 0x53, 0x65, 0x63, 0x63, 0x6f, 0x6d, 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53,
0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52,
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x70, 0x0a, 0x26, 0x64, 0x65, 0x76, 0x2e, 0x74, 0x61,
0x6c, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x63, 0x72, 0x69,
0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69, 0x64,
0x65, 0x72, 0x6f, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2f, 0x70, 0x6b,
0x67, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x72, 0x79, 0x2f, 0x61, 0x70, 0x69, 0x2f,
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x63, 0x72, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -179,21 +561,36 @@ func file_resource_definitions_cri_cri_proto_rawDescGZIP() []byte {
return file_resource_definitions_cri_cri_proto_rawDescData
}
var file_resource_definitions_cri_cri_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_resource_definitions_cri_cri_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_resource_definitions_cri_cri_proto_goTypes = []any{
(*ImageCacheConfigSpec)(nil), // 0: talos.resource.definitions.cri.ImageCacheConfigSpec
(*SeccompProfileSpec)(nil), // 1: talos.resource.definitions.cri.SeccompProfileSpec
(enums.CriImageCacheStatus)(0), // 2: talos.resource.definitions.enums.CriImageCacheStatus
(*structpb.Struct)(nil), // 3: google.protobuf.Struct
(*ImageCacheConfigSpec)(nil), // 0: talos.resource.definitions.cri.ImageCacheConfigSpec
(*RegistriesConfigSpec)(nil), // 1: talos.resource.definitions.cri.RegistriesConfigSpec
(*RegistryAuthConfig)(nil), // 2: talos.resource.definitions.cri.RegistryAuthConfig
(*RegistryConfig)(nil), // 3: talos.resource.definitions.cri.RegistryConfig
(*RegistryMirrorConfig)(nil), // 4: talos.resource.definitions.cri.RegistryMirrorConfig
(*RegistryTLSConfig)(nil), // 5: talos.resource.definitions.cri.RegistryTLSConfig
(*SeccompProfileSpec)(nil), // 6: talos.resource.definitions.cri.SeccompProfileSpec
nil, // 7: talos.resource.definitions.cri.RegistriesConfigSpec.RegistryMirrorsEntry
nil, // 8: talos.resource.definitions.cri.RegistriesConfigSpec.RegistryConfigEntry
(enums.CriImageCacheStatus)(0), // 9: talos.resource.definitions.enums.CriImageCacheStatus
(*common.PEMEncodedCertificateAndKey)(nil), // 10: common.PEMEncodedCertificateAndKey
(*structpb.Struct)(nil), // 11: google.protobuf.Struct
}
var file_resource_definitions_cri_cri_proto_depIdxs = []int32{
2, // 0: talos.resource.definitions.cri.ImageCacheConfigSpec.status:type_name -> talos.resource.definitions.enums.CriImageCacheStatus
3, // 1: talos.resource.definitions.cri.SeccompProfileSpec.value:type_name -> google.protobuf.Struct
2, // [2:2] is the sub-list for method output_type
2, // [2:2] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
9, // 0: talos.resource.definitions.cri.ImageCacheConfigSpec.status:type_name -> talos.resource.definitions.enums.CriImageCacheStatus
7, // 1: talos.resource.definitions.cri.RegistriesConfigSpec.registry_mirrors:type_name -> talos.resource.definitions.cri.RegistriesConfigSpec.RegistryMirrorsEntry
8, // 2: talos.resource.definitions.cri.RegistriesConfigSpec.registry_config:type_name -> talos.resource.definitions.cri.RegistriesConfigSpec.RegistryConfigEntry
5, // 3: talos.resource.definitions.cri.RegistryConfig.registry_tls:type_name -> talos.resource.definitions.cri.RegistryTLSConfig
2, // 4: talos.resource.definitions.cri.RegistryConfig.registry_auth:type_name -> talos.resource.definitions.cri.RegistryAuthConfig
10, // 5: talos.resource.definitions.cri.RegistryTLSConfig.tls_client_identity:type_name -> common.PEMEncodedCertificateAndKey
11, // 6: talos.resource.definitions.cri.SeccompProfileSpec.value:type_name -> google.protobuf.Struct
4, // 7: talos.resource.definitions.cri.RegistriesConfigSpec.RegistryMirrorsEntry.value:type_name -> talos.resource.definitions.cri.RegistryMirrorConfig
3, // 8: talos.resource.definitions.cri.RegistriesConfigSpec.RegistryConfigEntry.value:type_name -> talos.resource.definitions.cri.RegistryConfig
9, // [9:9] is the sub-list for method output_type
9, // [9:9] is the sub-list for method input_type
9, // [9:9] is the sub-list for extension type_name
9, // [9:9] is the sub-list for extension extendee
0, // [0:9] is the sub-list for field type_name
}
func init() { file_resource_definitions_cri_cri_proto_init() }
@ -207,7 +604,7 @@ func file_resource_definitions_cri_cri_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_resource_definitions_cri_cri_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumMessages: 9,
NumExtensions: 0,
NumServices: 0,
},

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@ import (
"github.com/google/cel-go/common/ast"
"github.com/google/cel-go/common/operators"
"github.com/google/cel-go/common/types"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/siderolabs/crypto/x509"
"github.com/siderolabs/gen/xslices"
"github.com/siderolabs/go-blockdevice/v2/encryption"

View File

@ -5,11 +5,51 @@
// Package cri contains resources related to the Container Runtime Interface (CRI).
package cri
import "github.com/cosi-project/runtime/pkg/resource"
import (
"context"
"fmt"
//go:generate deep-copy -type ImageCacheConfigSpec -type SeccompProfileSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go .
"github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/talos/pkg/machinery/config/config"
)
//go:generate deep-copy -type RegistriesConfigSpec -type ImageCacheConfigSpec -type SeccompProfileSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go .
//go:generate enumer -type=ImageCacheStatus -linecomment -text
// NamespaceName contains resources related to stats.
const NamespaceName resource.Namespace = "cri"
// RegistryBuilder implements image.RegistriesBuilder.
func RegistryBuilder(st state.State) func(ctx context.Context) (config.Registries, error) {
return func(ctx context.Context) (config.Registries, error) {
regs, err := safe.StateWatchFor[*RegistriesConfig](ctx, st, NewRegistriesConfig().Metadata(), state.WithEventTypes(state.Created, state.Updated))
if err != nil {
return nil, err
}
return regs.TypedSpec(), nil
}
}
// WaitForImageCache waits for the image cache config to be either disabled or ready.
func WaitForImageCache(ctx context.Context, st state.State) error {
_, err := st.WatchFor(ctx, NewImageCacheConfig().Metadata(),
state.WithEventTypes(state.Created, state.Updated),
state.WithCondition(func(r resource.Resource) (bool, error) {
imageCacheConfig, ok := r.(*ImageCacheConfig)
if !ok {
return false, fmt.Errorf("unexpected resource type: %T", r)
}
s := imageCacheConfig.TypedSpec().Status
return s == ImageCacheStatusDisabled || s == ImageCacheStatusReady, nil
}),
)
return err
}

View File

@ -27,6 +27,7 @@ func TestRegisterResource(t *testing.T) {
for _, resource := range []meta.ResourceWithRD{
&cri.ImageCacheConfig{},
&cri.SeccompProfile{},
&cri.RegistriesConfig{},
} {
assert.NoError(t, resourceRegistry.Register(ctx, resource))
}

View File

@ -2,10 +2,66 @@
// 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/.
// Code generated by "deep-copy -type ImageCacheConfigSpec -type SeccompProfileSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go ."; DO NOT EDIT.
// Code generated by "deep-copy -type RegistriesConfigSpec -type ImageCacheConfigSpec -type SeccompProfileSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go ."; DO NOT EDIT.
package cri
// DeepCopy generates a deep copy of RegistriesConfigSpec.
func (o RegistriesConfigSpec) DeepCopy() RegistriesConfigSpec {
var cp RegistriesConfigSpec = o
if o.RegistryMirrors != nil {
cp.RegistryMirrors = make(map[string]*RegistryMirrorConfig, len(o.RegistryMirrors))
for k2, v2 := range o.RegistryMirrors {
var cp_RegistryMirrors_v2 *RegistryMirrorConfig
if v2 != nil {
cp_RegistryMirrors_v2 = new(RegistryMirrorConfig)
*cp_RegistryMirrors_v2 = *v2
if v2.MirrorEndpoints != nil {
cp_RegistryMirrors_v2.MirrorEndpoints = make([]string, len(v2.MirrorEndpoints))
copy(cp_RegistryMirrors_v2.MirrorEndpoints, v2.MirrorEndpoints)
}
if v2.MirrorOverridePath != nil {
cp_RegistryMirrors_v2.MirrorOverridePath = new(bool)
*cp_RegistryMirrors_v2.MirrorOverridePath = *v2.MirrorOverridePath
}
if v2.MirrorSkipFallback != nil {
cp_RegistryMirrors_v2.MirrorSkipFallback = new(bool)
*cp_RegistryMirrors_v2.MirrorSkipFallback = *v2.MirrorSkipFallback
}
}
cp.RegistryMirrors[k2] = cp_RegistryMirrors_v2
}
}
if o.RegistryConfig != nil {
cp.RegistryConfig = make(map[string]*RegistryConfig, len(o.RegistryConfig))
for k2, v2 := range o.RegistryConfig {
var cp_RegistryConfig_v2 *RegistryConfig
if v2 != nil {
cp_RegistryConfig_v2 = new(RegistryConfig)
*cp_RegistryConfig_v2 = *v2
if v2.RegistryTLS != nil {
cp_RegistryConfig_v2.RegistryTLS = new(RegistryTLSConfig)
*cp_RegistryConfig_v2.RegistryTLS = *v2.RegistryTLS
if v2.RegistryTLS.TLSClientIdentity != nil {
cp_RegistryConfig_v2.RegistryTLS.TLSClientIdentity = v2.RegistryTLS.TLSClientIdentity.DeepCopy()
}
cp_RegistryConfig_v2.RegistryTLS.TLSCA = v2.RegistryTLS.TLSCA.DeepCopy()
if v2.RegistryTLS.TLSInsecureSkipVerify != nil {
cp_RegistryConfig_v2.RegistryTLS.TLSInsecureSkipVerify = new(bool)
*cp_RegistryConfig_v2.RegistryTLS.TLSInsecureSkipVerify = *v2.RegistryTLS.TLSInsecureSkipVerify
}
}
if v2.RegistryAuth != nil {
cp_RegistryConfig_v2.RegistryAuth = new(RegistryAuthConfig)
*cp_RegistryConfig_v2.RegistryAuth = *v2.RegistryAuth
}
}
cp.RegistryConfig[k2] = cp_RegistryConfig_v2
}
}
return cp
}
// DeepCopy generates a deep copy of ImageCacheConfigSpec.
func (o ImageCacheConfigSpec) DeepCopy() ImageCacheConfigSpec {
var cp ImageCacheConfigSpec = o

View File

@ -0,0 +1,140 @@
// 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 cri
import (
"github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/resource/meta"
"github.com/cosi-project/runtime/pkg/resource/protobuf"
"github.com/cosi-project/runtime/pkg/resource/typed"
"github.com/siderolabs/crypto/x509"
config2 "github.com/siderolabs/talos/pkg/machinery/config/config"
"github.com/siderolabs/talos/pkg/machinery/config/types/v1alpha1"
"github.com/siderolabs/talos/pkg/machinery/proto"
)
// RegistriesConfigType is type of RegistriesConfig resource.
const RegistriesConfigType = resource.Type("RegistryConfigs.cri.talos.dev")
// RegistriesConfigID is the singleton resource ID.
const RegistriesConfigID resource.ID = "registries"
// RegistriesConfig resource holds info about container registries.
type RegistriesConfig = typed.Resource[RegistriesConfigSpec, RegistriesConfigExtension]
// RegistriesConfigSpec describes status of rendered secrets.
//
//gotagsrewrite:gen
type RegistriesConfigSpec struct {
RegistryMirrors map[string]*RegistryMirrorConfig `yaml:"mirrors,omitempty" protobuf:"1"`
RegistryConfig map[string]*RegistryConfig `yaml:"config,omitempty" protobuf:"2"`
}
// Mirrors implements the Registries interface.
func (r RegistriesConfigSpec) Mirrors() map[string]config2.RegistryMirrorConfig {
mirrors := make(map[string]config2.RegistryMirrorConfig, len(r.RegistryMirrors))
for k, v := range r.RegistryMirrors {
mirrors[k] = (*v1alpha1.RegistryMirrorConfig)(v)
}
return mirrors
}
// Config implements the Registries interface.
func (r RegistriesConfigSpec) Config() map[string]config2.RegistryConfig {
registries := make(map[string]config2.RegistryConfig, len(r.RegistryConfig))
for k, v := range r.RegistryConfig {
registries[k] = v
}
return registries
}
// RegistryMirrorConfig represents mirror configuration for a registry.
//
//gotagsrewrite:gen
type RegistryMirrorConfig struct {
MirrorEndpoints []string `yaml:"endpoints" protobuf:"1"`
MirrorOverridePath *bool `yaml:"overridePath,omitempty" protobuf:"2"`
MirrorSkipFallback *bool `yaml:"skipFallback,omitempty" protobuf:"3"`
}
// RegistryConfig specifies auth & TLS config per registry.
//
//gotagsrewrite:gen
type RegistryConfig struct {
RegistryTLS *RegistryTLSConfig `yaml:"tls,omitempty" protobuf:"1"`
RegistryAuth *RegistryAuthConfig `yaml:"auth,omitempty" protobuf:"2"`
}
// TLS implements the Registries interface.
func (c *RegistryConfig) TLS() config2.RegistryTLSConfig {
if c.RegistryTLS == nil {
return nil
}
return (*v1alpha1.RegistryTLSConfig)(c.RegistryTLS)
}
// Auth implements the Registries interface.
func (c *RegistryConfig) Auth() config2.RegistryAuthConfig {
if c.RegistryAuth == nil {
return nil
}
return (*v1alpha1.RegistryAuthConfig)(c.RegistryAuth)
}
// RegistryAuthConfig specifies authentication configuration for a registry.
//
//gotagsrewrite:gen
type RegistryAuthConfig struct {
RegistryUsername string `yaml:"username,omitempty" protobuf:"1"`
RegistryPassword string `yaml:"password,omitempty" protobuf:"2"`
RegistryAuth string `yaml:"auth,omitempty" protobuf:"3"`
RegistryIdentityToken string `yaml:"identityToken,omitempty" protobuf:"4"`
}
// RegistryTLSConfig specifies TLS config for HTTPS registries.
//
//gotagsrewrite:gen
type RegistryTLSConfig struct {
TLSClientIdentity *x509.PEMEncodedCertificateAndKey `yaml:"clientIdentity,omitempty" protobuf:"1"`
TLSCA v1alpha1.Base64Bytes `yaml:"ca,omitempty" protobuf:"2"`
TLSInsecureSkipVerify *bool `yaml:"insecureSkipVerify,omitempty" protobuf:"3"`
}
// NewRegistriesConfig initializes a RegistriesConfig resource.
func NewRegistriesConfig() *RegistriesConfig {
return typed.NewResource[RegistriesConfigSpec, RegistriesConfigExtension](
resource.NewMetadata(NamespaceName, RegistriesConfigType, RegistriesConfigID, resource.VersionUndefined),
RegistriesConfigSpec{},
)
}
// RegistriesConfigExtension provides auxiliary methods for RegistriesConfig.
type RegistriesConfigExtension struct{}
// ResourceDefinition implements [typed.Extension] interface.
func (RegistriesConfigExtension) ResourceDefinition() meta.ResourceDefinitionSpec {
return meta.ResourceDefinitionSpec{
Type: RegistriesConfigType,
Aliases: []resource.Type{},
DefaultNamespace: NamespaceName,
PrintColumns: []meta.PrintColumn{},
}
}
func init() {
proto.RegisterDefaultTypes()
err := protobuf.RegisterDynamic[RegistriesConfigSpec](RegistriesConfigType, &RegistriesConfig{})
if err != nil {
panic(err)
}
}

View File

@ -56,6 +56,13 @@ description: Talos gRPC API reference.
- [resource/definitions/cri/cri.proto](#resource/definitions/cri/cri.proto)
- [ImageCacheConfigSpec](#talos.resource.definitions.cri.ImageCacheConfigSpec)
- [RegistriesConfigSpec](#talos.resource.definitions.cri.RegistriesConfigSpec)
- [RegistriesConfigSpec.RegistryConfigEntry](#talos.resource.definitions.cri.RegistriesConfigSpec.RegistryConfigEntry)
- [RegistriesConfigSpec.RegistryMirrorsEntry](#talos.resource.definitions.cri.RegistriesConfigSpec.RegistryMirrorsEntry)
- [RegistryAuthConfig](#talos.resource.definitions.cri.RegistryAuthConfig)
- [RegistryConfig](#talos.resource.definitions.cri.RegistryConfig)
- [RegistryMirrorConfig](#talos.resource.definitions.cri.RegistryMirrorConfig)
- [RegistryTLSConfig](#talos.resource.definitions.cri.RegistryTLSConfig)
- [SeccompProfileSpec](#talos.resource.definitions.cri.SeccompProfileSpec)
- [resource/definitions/enums/enums.proto](#resource/definitions/enums/enums.proto)
@ -1306,6 +1313,122 @@ ImageCacheConfigSpec represents the ImageCacheConfig.
<a name="talos.resource.definitions.cri.RegistriesConfigSpec"></a>
### RegistriesConfigSpec
RegistriesConfigSpec describes status of rendered secrets.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| registry_mirrors | [RegistriesConfigSpec.RegistryMirrorsEntry](#talos.resource.definitions.cri.RegistriesConfigSpec.RegistryMirrorsEntry) | repeated | |
| registry_config | [RegistriesConfigSpec.RegistryConfigEntry](#talos.resource.definitions.cri.RegistriesConfigSpec.RegistryConfigEntry) | repeated | |
<a name="talos.resource.definitions.cri.RegistriesConfigSpec.RegistryConfigEntry"></a>
### RegistriesConfigSpec.RegistryConfigEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [string](#string) | | |
| value | [RegistryConfig](#talos.resource.definitions.cri.RegistryConfig) | | |
<a name="talos.resource.definitions.cri.RegistriesConfigSpec.RegistryMirrorsEntry"></a>
### RegistriesConfigSpec.RegistryMirrorsEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [string](#string) | | |
| value | [RegistryMirrorConfig](#talos.resource.definitions.cri.RegistryMirrorConfig) | | |
<a name="talos.resource.definitions.cri.RegistryAuthConfig"></a>
### RegistryAuthConfig
RegistryAuthConfig specifies authentication configuration for a registry.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| registry_username | [string](#string) | | |
| registry_password | [string](#string) | | |
| registry_auth | [string](#string) | | |
| registry_identity_token | [string](#string) | | |
<a name="talos.resource.definitions.cri.RegistryConfig"></a>
### RegistryConfig
RegistryConfig specifies auth & TLS config per registry.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| registry_tls | [RegistryTLSConfig](#talos.resource.definitions.cri.RegistryTLSConfig) | | |
| registry_auth | [RegistryAuthConfig](#talos.resource.definitions.cri.RegistryAuthConfig) | | |
<a name="talos.resource.definitions.cri.RegistryMirrorConfig"></a>
### RegistryMirrorConfig
RegistryMirrorConfig represents mirror configuration for a registry.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| mirror_endpoints | [string](#string) | repeated | |
| mirror_override_path | [bool](#bool) | | |
| mirror_skip_fallback | [bool](#bool) | | |
<a name="talos.resource.definitions.cri.RegistryTLSConfig"></a>
### RegistryTLSConfig
RegistryTLSConfig specifies TLS config for HTTPS registries.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| tls_client_identity | [common.PEMEncodedCertificateAndKey](#common.PEMEncodedCertificateAndKey) | | |
| tlsca | [bytes](#bytes) | | |
| tls_insecure_skip_verify | [bool](#bool) | | |
<a name="talos.resource.definitions.cri.SeccompProfileSpec"></a>
### SeccompProfileSpec