From fc3b31575c3939028c26022a49c89597d30f78b9 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 28 Nov 2024 19:12:57 +0400 Subject: [PATCH] fix: multiple issues with opening encrypted volumes Fixes #9820 This only affects volumes with multiple key slots configured. Make sync issues non-fatal, so that if some keys fail to sync, proceed with normal boot, but record an error in the `VolumeStatus` resource. When opening, correctly try all key slots. Signed-off-by: Andrey Smirnov --- api/resource/definitions/block/block.proto | 1 + .../block/internal/volumes/close.go | 11 +--- .../block/internal/volumes/encrypt.go | 14 +---- .../block/internal/volumes/volumes.go | 3 +- .../pkg/controllers/block/volume_manager.go | 21 ++++--- internal/integration/api/apply-config.go | 26 +++++++++ internal/pkg/encryption/encryption.go | 58 +++++++++++-------- .../resource/definitions/block/block.pb.go | 57 ++++++++++-------- .../definitions/block/block_vtproto.pb.go | 47 +++++++++++++++ .../resources/block/deep_copy.generated.go | 4 ++ .../resources/block/volume_status.go | 3 +- website/content/v1.9/reference/api.md | 1 + 12 files changed, 169 insertions(+), 77 deletions(-) diff --git a/api/resource/definitions/block/block.proto b/api/resource/definitions/block/block.proto index ce045efe93..f7f84a258a 100755 --- a/api/resource/definitions/block/block.proto +++ b/api/resource/definitions/block/block.proto @@ -168,5 +168,6 @@ message VolumeStatusSpec { string mount_location = 11; talos.resource.definitions.enums.BlockEncryptionProviderType encryption_provider = 12; string pretty_size = 13; + repeated string encryption_failed_syncs = 14; } diff --git a/internal/app/machined/pkg/controllers/block/internal/volumes/close.go b/internal/app/machined/pkg/controllers/block/internal/volumes/close.go index fb65f6bbe0..ad1bc2a5e3 100644 --- a/internal/app/machined/pkg/controllers/block/internal/volumes/close.go +++ b/internal/app/machined/pkg/controllers/block/internal/volumes/close.go @@ -14,19 +14,10 @@ import ( "github.com/siderolabs/talos/internal/pkg/encryption" "github.com/siderolabs/talos/pkg/machinery/resources/block" - "github.com/siderolabs/talos/pkg/machinery/resources/hardware" ) // Close the encrypted volumes. func Close(ctx context.Context, logger *zap.Logger, volumeContext ManagerContext) error { - getSystemInformation := func(ctx context.Context) (*hardware.SystemInformation, error) { - if volumeContext.SystemInformation != nil { - return volumeContext.SystemInformation, nil - } - - return nil, fmt.Errorf("system information not available") - } - switch volumeContext.Cfg.TypedSpec().Encryption.Provider { case block.EncryptionProviderNone: // nothing to do @@ -36,7 +27,7 @@ func Close(ctx context.Context, logger *zap.Logger, volumeContext ManagerContext case block.EncryptionProviderLUKS2: encryptionConfig := volumeContext.Cfg.TypedSpec().Encryption - handler, err := encryption.NewHandler(encryptionConfig, volumeContext.Cfg.Metadata().ID(), getSystemInformation) + handler, err := encryption.NewHandler(encryptionConfig, volumeContext.Cfg.Metadata().ID(), volumeContext.GetSystemInformation) if err != nil { return fmt.Errorf("failed to create encryption handler: %w", err) } diff --git a/internal/app/machined/pkg/controllers/block/internal/volumes/encrypt.go b/internal/app/machined/pkg/controllers/block/internal/volumes/encrypt.go index 6e85bfc17c..537b0a4c57 100644 --- a/internal/app/machined/pkg/controllers/block/internal/volumes/encrypt.go +++ b/internal/app/machined/pkg/controllers/block/internal/volumes/encrypt.go @@ -17,19 +17,10 @@ import ( "github.com/siderolabs/talos/internal/pkg/encryption" "github.com/siderolabs/talos/pkg/machinery/resources/block" - "github.com/siderolabs/talos/pkg/machinery/resources/hardware" ) // HandleEncryption makes sure the encryption for the volumes is handled appropriately. func HandleEncryption(ctx context.Context, logger *zap.Logger, volumeContext ManagerContext) error { - getSystemInformation := func(ctx context.Context) (*hardware.SystemInformation, error) { - if volumeContext.SystemInformation != nil { - return volumeContext.SystemInformation, nil - } - - return nil, fmt.Errorf("system information not available") - } - switch volumeContext.Cfg.TypedSpec().Encryption.Provider { case block.EncryptionProviderNone: // nothing to do @@ -41,7 +32,7 @@ func HandleEncryption(ctx context.Context, logger *zap.Logger, volumeContext Man case block.EncryptionProviderLUKS2: encryptionConfig := volumeContext.Cfg.TypedSpec().Encryption - handler, err := encryption.NewHandler(encryptionConfig, volumeContext.Cfg.Metadata().ID(), getSystemInformation) + handler, err := encryption.NewHandler(encryptionConfig, volumeContext.Cfg.Metadata().ID(), volumeContext.GetSystemInformation) if err != nil { return fmt.Errorf("failed to create encryption handler: %w", err) } @@ -102,7 +93,7 @@ func HandleEncryptionWithHandler(ctx context.Context, logger *zap.Logger, volume encryptedName := filepath.Base(volumeContext.Status.Location) + "-encrypted" - encryptedPath, err := handler.Open(ctx, logger, volumeContext.Status.Location, encryptedName) + encryptedPath, failedSyncs, err := handler.Open(ctx, logger, volumeContext.Status.Location, encryptedName) if err != nil { return xerrors.NewTaggedf[Retryable]("error opening encrypted volume: %w", err) } @@ -115,6 +106,7 @@ func HandleEncryptionWithHandler(ctx context.Context, logger *zap.Logger, volume volumeContext.Status.Phase = block.VolumePhasePrepared volumeContext.Status.MountLocation = encryptedPath volumeContext.Status.EncryptionProvider = volumeContext.Cfg.TypedSpec().Encryption.Provider + volumeContext.Status.EncryptionFailedSyncs = failedSyncs return nil } diff --git a/internal/app/machined/pkg/controllers/block/internal/volumes/volumes.go b/internal/app/machined/pkg/controllers/block/internal/volumes/volumes.go index 305f84e3db..9dcca75003 100644 --- a/internal/app/machined/pkg/controllers/block/internal/volumes/volumes.go +++ b/internal/app/machined/pkg/controllers/block/internal/volumes/volumes.go @@ -7,6 +7,7 @@ package volumes import ( "cmp" + "context" "github.com/siderolabs/gen/optional" @@ -67,6 +68,6 @@ type ManagerContext struct { DevicesReady bool PreviousWaveProvisioned bool - SystemInformation *hardware.SystemInformation + GetSystemInformation func(context.Context) (*hardware.SystemInformation, error) Lifecycle *block.VolumeLifecycle } diff --git a/internal/app/machined/pkg/controllers/block/volume_manager.go b/internal/app/machined/pkg/controllers/block/volume_manager.go index 96297e5b0b..ebb910aeb2 100644 --- a/internal/app/machined/pkg/controllers/block/volume_manager.go +++ b/internal/app/machined/pkg/controllers/block/volume_manager.go @@ -6,6 +6,7 @@ package block import ( "context" + "errors" "fmt" "math" "slices" @@ -181,11 +182,6 @@ func (ctrl *VolumeManagerController) Run(ctx context.Context, r controller.Runti return fmt.Errorf("error fetching system disk: %w", err) } - systemInfo, err := safe.ReaderGetByID[*hardware.SystemInformation](ctx, r, hardware.SystemInformationID) - if err != nil && !state.IsNotFoundError(err) { - return fmt.Errorf("error fetching system information: %w", err) - } - volumeLifecycle, err := safe.ReaderGetByID[*block.VolumeLifecycle](ctx, r, block.VolumeLifecycleID) if err != nil && !state.IsNotFoundError(err) { return fmt.Errorf("error fetching volume lifecycle: %w", err) @@ -318,8 +314,19 @@ func (ctrl *VolumeManagerController) Run(ctx context.Context, r controller.Runti Disks: diskSpecs, DevicesReady: devicesReady, PreviousWaveProvisioned: vc.TypedSpec().Provisioning.Wave <= fullyProvisionedWave, - SystemInformation: systemInfo, - Lifecycle: volumeLifecycle, + GetSystemInformation: func(ctx context.Context) (*hardware.SystemInformation, error) { + systemInfo, err := safe.ReaderGetByID[*hardware.SystemInformation](ctx, r, hardware.SystemInformationID) + if err != nil && !state.IsNotFoundError(err) { + return nil, fmt.Errorf("error fetching system information: %w", err) + } + + if systemInfo == nil { + return nil, errors.New("system information not available") + } + + return systemInfo, nil + }, + Lifecycle: volumeLifecycle, }, ); err != nil { volumeStatus.PreFailPhase = volumeStatus.Phase diff --git a/internal/integration/api/apply-config.go b/internal/integration/api/apply-config.go index dc60aa5e3b..69ed6a6b80 100644 --- a/internal/integration/api/apply-config.go +++ b/internal/integration/api/apply-config.go @@ -8,16 +8,20 @@ package api import ( "context" + "encoding/json" "net/url" "os" "slices" "testing" "time" + "github.com/cosi-project/runtime/pkg/resource/rtestutils" "github.com/cosi-project/runtime/pkg/safe" "github.com/siderolabs/gen/ensure" "github.com/siderolabs/go-pointer" "github.com/siderolabs/go-retry/retry" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" "google.golang.org/protobuf/types/known/durationpb" @@ -30,6 +34,7 @@ import ( "github.com/siderolabs/talos/pkg/machinery/config/types/runtime" "github.com/siderolabs/talos/pkg/machinery/config/types/v1alpha1" "github.com/siderolabs/talos/pkg/machinery/constants" + "github.com/siderolabs/talos/pkg/machinery/resources/block" mc "github.com/siderolabs/talos/pkg/machinery/resources/config" ) @@ -243,6 +248,8 @@ func (suite *ApplyConfigSuite) TestApplyConfigRotateEncryptionSecrets() { suite.WaitForBootDone(suite.ctx) + suite.T().Logf("testing encryption key rotation on node %s", node) + existing := cfg.EncryptionKeys[0] slot := existing.Slot() + 1 @@ -290,6 +297,10 @@ func (suite *ApplyConfigSuite) TestApplyConfigRotateEncryptionSecrets() { for _, keys := range keySets { data := suite.PatchV1Alpha1Config(provider, func(cfg *v1alpha1.Config) { + suite.T().Logf("changing encryption keys to %s", + toJSONString(suite.T(), keys), + ) + cfg.MachineConfig.MachineSystemDiskEncryption.EphemeralPartition.EncryptionKeys = keys }) @@ -348,9 +359,24 @@ func (suite *ApplyConfigSuite) TestApplyConfigRotateEncryptionSecrets() { } suite.WaitForBootDone(suite.ctx) + + // verify that encryption key sync has no failures + rtestutils.AssertAll(nodeCtx, suite.T(), suite.Client.COSI, func(vs *block.VolumeStatus, asrt *assert.Assertions) { + suite.Assert().Contains([]block.VolumePhase{block.VolumePhaseReady, block.VolumePhaseMissing}, vs.TypedSpec().Phase) + suite.Assert().Empty(vs.TypedSpec().EncryptionFailedSyncs) + }) } } +func toJSONString(t *testing.T, v any) string { + t.Helper() + + out, err := json.Marshal(v) + require.NoError(t, err) + + return string(out) +} + // TestApplyNoReboot verifies the apply config API fails if NoReboot mode is requested on a field that can not be applied immediately. func (suite *ApplyConfigSuite) TestApplyNoReboot() { nodes := suite.DiscoverNodeInternalIPsByType(suite.ctx, machine.TypeWorker) diff --git a/internal/pkg/encryption/encryption.go b/internal/pkg/encryption/encryption.go index e83d596465..b6de67625a 100644 --- a/internal/pkg/encryption/encryption.go +++ b/internal/pkg/encryption/encryption.go @@ -88,10 +88,10 @@ type Handler struct { } // Open encrypted partition. -func (h *Handler) Open(ctx context.Context, logger *zap.Logger, devicePath, encryptedName string) (string, error) { +func (h *Handler) Open(ctx context.Context, logger *zap.Logger, devicePath, encryptedName string) (string, []string, error) { isOpen, path, err := h.encryptionProvider.IsOpen(ctx, devicePath, encryptedName) if err != nil { - return "", err + return "", nil, err } var usedKey *encryption.Key @@ -108,15 +108,16 @@ func (h *Handler) Open(ctx context.Context, logger *zap.Logger, devicePath, encr return nil, nil, err } + // try to open with the key, if it fails, tryHandlers will try the next handler + path, err = h.encryptionProvider.Open(ctx, devicePath, encryptedName, slotKey) + if err != nil { + return nil, nil, err + } + return slotKey, slotToken, nil }) if err != nil { - return "", err - } - - path, err = h.encryptionProvider.Open(ctx, devicePath, encryptedName, key) - if err != nil { - return "", err + return "", nil, err } logger.Info("opened encrypted device", zap.Int("slot", handler.Slot()), zap.String("type", fmt.Sprintf("%T", handler))) @@ -124,11 +125,12 @@ func (h *Handler) Open(ctx context.Context, logger *zap.Logger, devicePath, encr usedKey = key } - if err := h.syncKeys(ctx, logger, devicePath, usedKey); err != nil { - return "", err + failedSyncs, err := h.syncKeys(ctx, logger, devicePath, usedKey) + if err != nil { + return "", nil, err } - return path, nil + return path, failedSyncs, nil } // Close encrypted partition. @@ -177,12 +179,14 @@ func (h *Handler) FormatAndEncrypt(ctx context.Context, logger *zap.Logger, path } //nolint:gocyclo -func (h *Handler) syncKeys(ctx context.Context, logger *zap.Logger, path string, k *encryption.Key) error { +func (h *Handler) syncKeys(ctx context.Context, logger *zap.Logger, path string, k *encryption.Key) ([]string, error) { keyslots, err := h.encryptionProvider.ReadKeyslots(path) if err != nil { - return err + return nil, err } + var failedSyncs []string + visited := map[string]bool{} for _, handler := range h.keyHandlers { @@ -196,17 +200,21 @@ func (h *Handler) syncKeys(ctx context.Context, logger *zap.Logger, path string, // keyslot exists if _, ok := keyslots.Keyslots[slot]; ok { if err = h.updateKey(ctx, path, k, handler); err != nil { - return fmt.Errorf("error updating key slot %s %T: %w", slot, handler, err) - } + logger.Error("failed to update key", zap.Int("slot", handler.Slot()), zap.String("handler", fmt.Sprintf("%T", handler)), zap.Error(err)) - logger.Info("updated encryption key", zap.Int("slot", handler.Slot())) + failedSyncs = append(failedSyncs, fmt.Sprintf("error updating key slot %s %T: %s", slot, handler, err)) + } else { + logger.Info("updated encryption key", zap.Int("slot", handler.Slot())) + } } else { // keyslot does not exist so just add the key if err = h.addKey(ctx, path, k, handler); err != nil { - return fmt.Errorf("error adding key slot %s %T: %w", slot, handler, err) - } + logger.Error("failed to add key", zap.Int("slot", handler.Slot()), zap.String("handler", fmt.Sprintf("%T", handler)), zap.Error(err)) - logger.Info("added encryption key", zap.Int("slot", handler.Slot())) + failedSyncs = append(failedSyncs, fmt.Sprintf("error adding key slot %s %T: %s", slot, handler, err)) + } else { + logger.Info("added encryption key", zap.Int("slot", handler.Slot())) + } } } @@ -215,18 +223,20 @@ func (h *Handler) syncKeys(ctx context.Context, logger *zap.Logger, path string, if !visited[slot] { s, err := strconv.ParseInt(slot, 10, 64) if err != nil { - return err + return nil, err } if err = h.encryptionProvider.RemoveKey(ctx, path, int(s), k); err != nil { - return fmt.Errorf("error removing key slot %s: %w", slot, err) - } + logger.Error("failed to remove key", zap.Int("slot", int(s)), zap.Error(err)) - logger.Info("removed encryption key", zap.Int("slot", k.Slot)) + failedSyncs = append(failedSyncs, fmt.Sprintf("error removing key slot %s: %s", slot, err)) + } else { + logger.Info("removed encryption key", zap.Int("slot", k.Slot)) + } } } - return nil + return failedSyncs, nil } func (h *Handler) updateKey(ctx context.Context, path string, existingKey *encryption.Key, handler keys.Handler) error { diff --git a/pkg/machinery/api/resource/definitions/block/block.pb.go b/pkg/machinery/api/resource/definitions/block/block.pb.go index ae6952ec3f..79413e3169 100644 --- a/pkg/machinery/api/resource/definitions/block/block.pb.go +++ b/pkg/machinery/api/resource/definitions/block/block.pb.go @@ -1286,19 +1286,20 @@ type VolumeStatusSpec struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Phase enums.BlockVolumePhase `protobuf:"varint,1,opt,name=phase,proto3,enum=talos.resource.definitions.enums.BlockVolumePhase" json:"phase,omitempty"` - Location string `protobuf:"bytes,2,opt,name=location,proto3" json:"location,omitempty"` - ErrorMessage string `protobuf:"bytes,3,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` - Uuid string `protobuf:"bytes,4,opt,name=uuid,proto3" json:"uuid,omitempty"` - PartitionUuid string `protobuf:"bytes,5,opt,name=partition_uuid,json=partitionUuid,proto3" json:"partition_uuid,omitempty"` - PreFailPhase enums.BlockVolumePhase `protobuf:"varint,6,opt,name=pre_fail_phase,json=preFailPhase,proto3,enum=talos.resource.definitions.enums.BlockVolumePhase" json:"pre_fail_phase,omitempty"` - ParentLocation string `protobuf:"bytes,7,opt,name=parent_location,json=parentLocation,proto3" json:"parent_location,omitempty"` - PartitionIndex int64 `protobuf:"varint,8,opt,name=partition_index,json=partitionIndex,proto3" json:"partition_index,omitempty"` - Size uint64 `protobuf:"varint,9,opt,name=size,proto3" json:"size,omitempty"` - Filesystem enums.BlockFilesystemType `protobuf:"varint,10,opt,name=filesystem,proto3,enum=talos.resource.definitions.enums.BlockFilesystemType" json:"filesystem,omitempty"` - MountLocation string `protobuf:"bytes,11,opt,name=mount_location,json=mountLocation,proto3" json:"mount_location,omitempty"` - EncryptionProvider enums.BlockEncryptionProviderType `protobuf:"varint,12,opt,name=encryption_provider,json=encryptionProvider,proto3,enum=talos.resource.definitions.enums.BlockEncryptionProviderType" json:"encryption_provider,omitempty"` - PrettySize string `protobuf:"bytes,13,opt,name=pretty_size,json=prettySize,proto3" json:"pretty_size,omitempty"` + Phase enums.BlockVolumePhase `protobuf:"varint,1,opt,name=phase,proto3,enum=talos.resource.definitions.enums.BlockVolumePhase" json:"phase,omitempty"` + Location string `protobuf:"bytes,2,opt,name=location,proto3" json:"location,omitempty"` + ErrorMessage string `protobuf:"bytes,3,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` + Uuid string `protobuf:"bytes,4,opt,name=uuid,proto3" json:"uuid,omitempty"` + PartitionUuid string `protobuf:"bytes,5,opt,name=partition_uuid,json=partitionUuid,proto3" json:"partition_uuid,omitempty"` + PreFailPhase enums.BlockVolumePhase `protobuf:"varint,6,opt,name=pre_fail_phase,json=preFailPhase,proto3,enum=talos.resource.definitions.enums.BlockVolumePhase" json:"pre_fail_phase,omitempty"` + ParentLocation string `protobuf:"bytes,7,opt,name=parent_location,json=parentLocation,proto3" json:"parent_location,omitempty"` + PartitionIndex int64 `protobuf:"varint,8,opt,name=partition_index,json=partitionIndex,proto3" json:"partition_index,omitempty"` + Size uint64 `protobuf:"varint,9,opt,name=size,proto3" json:"size,omitempty"` + Filesystem enums.BlockFilesystemType `protobuf:"varint,10,opt,name=filesystem,proto3,enum=talos.resource.definitions.enums.BlockFilesystemType" json:"filesystem,omitempty"` + MountLocation string `protobuf:"bytes,11,opt,name=mount_location,json=mountLocation,proto3" json:"mount_location,omitempty"` + EncryptionProvider enums.BlockEncryptionProviderType `protobuf:"varint,12,opt,name=encryption_provider,json=encryptionProvider,proto3,enum=talos.resource.definitions.enums.BlockEncryptionProviderType" json:"encryption_provider,omitempty"` + PrettySize string `protobuf:"bytes,13,opt,name=pretty_size,json=prettySize,proto3" json:"pretty_size,omitempty"` + EncryptionFailedSyncs []string `protobuf:"bytes,14,rep,name=encryption_failed_syncs,json=encryptionFailedSyncs,proto3" json:"encryption_failed_syncs,omitempty"` } func (x *VolumeStatusSpec) Reset() { @@ -1422,6 +1423,13 @@ func (x *VolumeStatusSpec) GetPrettySize() string { return "" } +func (x *VolumeStatusSpec) GetEncryptionFailedSyncs() []string { + if x != nil { + return x.EncryptionFailedSyncs + } + return nil +} + var File_resource_definitions_block_block_proto protoreflect.FileDescriptor var file_resource_definitions_block_block_proto_rawDesc = []byte{ @@ -1646,7 +1654,7 @@ var file_resource_definitions_block_block_proto_rawDesc = []byte{ 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, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, - 0x52, 0x0a, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xa7, 0x05, 0x0a, + 0x52, 0x0a, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xdf, 0x05, 0x0a, 0x10, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x48, 0x0a, 0x05, 0x70, 0x68, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, @@ -1689,15 +1697,18 @@ var file_resource_definitions_block_block_proto_rawDesc = []byte{ 0x65, 0x52, 0x12, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x74, 0x74, 0x79, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x74, - 0x74, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x74, 0x0a, 0x28, 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, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x5a, 0x48, 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, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x5f, 0x73, 0x79, 0x6e, 0x63, + 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x09, 0x52, 0x15, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x53, 0x79, 0x6e, 0x63, 0x73, 0x42, 0x74, + 0x0a, 0x28, 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, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5a, 0x48, 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, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/pkg/machinery/api/resource/definitions/block/block_vtproto.pb.go b/pkg/machinery/api/resource/definitions/block/block_vtproto.pb.go index 4132d96619..e46089d767 100644 --- a/pkg/machinery/api/resource/definitions/block/block_vtproto.pb.go +++ b/pkg/machinery/api/resource/definitions/block/block_vtproto.pb.go @@ -1186,6 +1186,15 @@ func (m *VolumeStatusSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.EncryptionFailedSyncs) > 0 { + for iNdEx := len(m.EncryptionFailedSyncs) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.EncryptionFailedSyncs[iNdEx]) + copy(dAtA[i:], m.EncryptionFailedSyncs[iNdEx]) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.EncryptionFailedSyncs[iNdEx]))) + i-- + dAtA[i] = 0x72 + } + } if len(m.PrettySize) > 0 { i -= len(m.PrettySize) copy(dAtA[i:], m.PrettySize) @@ -1792,6 +1801,12 @@ func (m *VolumeStatusSpec) SizeVT() (n int) { if l > 0 { n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } + if len(m.EncryptionFailedSyncs) > 0 { + for _, s := range m.EncryptionFailedSyncs { + l = len(s) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } n += len(m.unknownFields) return n } @@ -5217,6 +5232,38 @@ func (m *VolumeStatusSpec) UnmarshalVT(dAtA []byte) error { } m.PrettySize = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EncryptionFailedSyncs", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EncryptionFailedSyncs = append(m.EncryptionFailedSyncs, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) diff --git a/pkg/machinery/resources/block/deep_copy.generated.go b/pkg/machinery/resources/block/deep_copy.generated.go index c62e2ffe63..a273d89833 100644 --- a/pkg/machinery/resources/block/deep_copy.generated.go +++ b/pkg/machinery/resources/block/deep_copy.generated.go @@ -85,5 +85,9 @@ func (o VolumeLifecycleSpec) DeepCopy() VolumeLifecycleSpec { // DeepCopy generates a deep copy of VolumeStatusSpec. func (o VolumeStatusSpec) DeepCopy() VolumeStatusSpec { var cp VolumeStatusSpec = o + if o.EncryptionFailedSyncs != nil { + cp.EncryptionFailedSyncs = make([]string, len(o.EncryptionFailedSyncs)) + copy(cp.EncryptionFailedSyncs, o.EncryptionFailedSyncs) + } return cp } diff --git a/pkg/machinery/resources/block/volume_status.go b/pkg/machinery/resources/block/volume_status.go index 6a62bd3bbf..04bff968db 100644 --- a/pkg/machinery/resources/block/volume_status.go +++ b/pkg/machinery/resources/block/volume_status.go @@ -45,7 +45,8 @@ type VolumeStatusSpec struct { Filesystem FilesystemType `yaml:"filesystem,omitempty" protobuf:"10"` // EncryptionProvider is the provider of the encryption. - EncryptionProvider EncryptionProviderType `yaml:"encryptionProvider,omitempty" protobuf:"12"` + EncryptionProvider EncryptionProviderType `yaml:"encryptionProvider,omitempty" protobuf:"12"` + EncryptionFailedSyncs []string `yaml:"encryptionFailedSyncs,omitempty" protobuf:"14"` ErrorMessage string `yaml:"errorMessage,omitempty" protobuf:"3"` } diff --git a/website/content/v1.9/reference/api.md b/website/content/v1.9/reference/api.md index 43680593ef..19f310a705 100644 --- a/website/content/v1.9/reference/api.md +++ b/website/content/v1.9/reference/api.md @@ -1131,6 +1131,7 @@ VolumeStatusSpec is the spec for VolumeStatus resource. | mount_location | [string](#string) | | | | encryption_provider | [talos.resource.definitions.enums.BlockEncryptionProviderType](#talos.resource.definitions.enums.BlockEncryptionProviderType) | | | | pretty_size | [string](#string) | | | +| encryption_failed_syncs | [string](#string) | repeated | |