diff --git a/api/resource/definitions/block/block.proto b/api/resource/definitions/block/block.proto
index 69a3ae6e6f..7c380ee228 100755
--- a/api/resource/definitions/block/block.proto
+++ b/api/resource/definitions/block/block.proto
@@ -78,6 +78,7 @@ message DiskSpec {
string pretty_size = 15;
repeated string secondary_disks = 16;
string uuid = 17;
+ repeated string symlinks = 18;
}
// EncryptionKey is the spec for volume encryption key.
@@ -133,6 +134,11 @@ message ProvisioningSpec {
FilesystemSpec filesystem_spec = 4;
}
+// SymlinkSpec is the spec for Symlinks resource.
+message SymlinkSpec {
+ repeated string paths = 1;
+}
+
// SystemDiskSpec is the spec for SystemDisks resource.
message SystemDiskSpec {
string disk_id = 1;
diff --git a/internal/app/machined/pkg/controllers/block/devices.go b/internal/app/machined/pkg/controllers/block/devices.go
index 44aac4becc..e7f8add823 100644
--- a/internal/app/machined/pkg/controllers/block/devices.go
+++ b/internal/app/machined/pkg/controllers/block/devices.go
@@ -15,6 +15,7 @@ import (
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state"
"go.uber.org/zap"
+ "golang.org/x/sys/unix"
"github.com/siderolabs/talos/internal/app/machined/pkg/controllers/block/internal/inotify"
"github.com/siderolabs/talos/internal/app/machined/pkg/controllers/block/internal/kobject"
@@ -217,7 +218,7 @@ func (ctrl *DevicesController) processEvent(ctx context.Context, r controller.Ru
return fmt.Errorf("failed to modify device %q: %w", id, err)
}
- if err := inotifyWatcher.Add(devPath); err != nil {
+ if err := inotifyWatcher.Add(devPath, unix.IN_CLOSE_WRITE); err != nil {
return fmt.Errorf("failed to add inotify watch for %q: %w", devPath, err)
}
case kobject.ActionRemove:
diff --git a/internal/app/machined/pkg/controllers/block/disks.go b/internal/app/machined/pkg/controllers/block/disks.go
index 1147856745..c7b90cbf54 100644
--- a/internal/app/machined/pkg/controllers/block/disks.go
+++ b/internal/app/machined/pkg/controllers/block/disks.go
@@ -11,6 +11,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/safe"
+ "github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/gen/xslices"
blkdev "github.com/siderolabs/go-blockdevice/v2/block"
"go.uber.org/zap"
@@ -34,6 +35,11 @@ func (ctrl *DisksController) Inputs() []controller.Input {
Type: block.DeviceType,
Kind: controller.InputWeak,
},
+ {
+ Namespace: block.NamespaceName,
+ Type: block.SymlinkType,
+ Kind: controller.InputWeak,
+ },
}
}
@@ -82,8 +88,13 @@ func (ctrl *DisksController) Run(ctx context.Context, r controller.Runtime, logg
continue
}
+ // always update symlinks, but skip if the disk hasn't been created yet
+ if err = ctrl.updateSymlinks(ctx, r, device); err != nil {
+ return err
+ }
+
if lastObserved, ok := lastObservedGenerations[device.Metadata().ID()]; ok && device.TypedSpec().Generation == lastObserved {
- // ignore disks which have some generation as before (don't query them once again)
+ // ignore disks which have same generation as before (don't query them once again)
touchedDisks[device.Metadata().ID()] = struct{}{}
continue
@@ -115,6 +126,33 @@ func (ctrl *DisksController) Run(ctx context.Context, r controller.Runtime, logg
}
}
+func (ctrl *DisksController) updateSymlinks(ctx context.Context, r controller.Runtime, device *block.Device) error {
+ symlinks, err := safe.ReaderGetByID[*block.Symlink](ctx, r, device.Metadata().ID())
+ if err != nil {
+ if state.IsNotFoundError(err) {
+ return nil
+ }
+
+ return err
+ }
+
+ _, err = safe.ReaderGetByID[*block.Disk](ctx, r, device.Metadata().ID())
+ if err != nil {
+ if state.IsNotFoundError(err) {
+ // don't create disk entries even if we have symlinks, let analyze handle it
+ return nil
+ }
+
+ return err
+ }
+
+ return safe.WriterModify(ctx, r, block.NewDisk(block.NamespaceName, device.Metadata().ID()), func(d *block.Disk) error {
+ d.TypedSpec().Symlinks = symlinks.TypedSpec().Paths
+
+ return nil
+ })
+}
+
//nolint:gocyclo
func (ctrl *DisksController) analyzeBlockDevice(
ctx context.Context, r controller.Runtime, logger *zap.Logger, device *block.Device, touchedDisks map[string]struct{}, allBlockdevices safe.List[*block.Device],
@@ -172,6 +210,11 @@ func (ctrl *DisksController) analyzeBlockDevice(
return devID
})
+ symlinks, err := safe.ReaderGetByID[*block.Symlink](ctx, r, device.Metadata().ID())
+ if err != nil && !state.IsNotFoundError(err) {
+ return err
+ }
+
touchedDisks[device.Metadata().ID()] = struct{}{}
return safe.WriterModify(ctx, r, block.NewDisk(block.NamespaceName, device.Metadata().ID()), func(d *block.Disk) error {
@@ -195,6 +238,12 @@ func (ctrl *DisksController) analyzeBlockDevice(
d.TypedSpec().SecondaryDisks = secondaryDisks
+ if symlinks != nil {
+ d.TypedSpec().Symlinks = symlinks.TypedSpec().Paths
+ } else {
+ d.TypedSpec().Symlinks = nil
+ }
+
return nil
})
}
diff --git a/internal/app/machined/pkg/controllers/block/internal/inotify/inotify.go b/internal/app/machined/pkg/controllers/block/internal/inotify/inotify.go
index d02d605b78..d7346e3160 100644
--- a/internal/app/machined/pkg/controllers/block/internal/inotify/inotify.go
+++ b/internal/app/machined/pkg/controllers/block/internal/inotify/inotify.go
@@ -210,7 +210,7 @@ func (w *Watcher) Run() (<-chan string, <-chan error) {
}
// Send the events that are not ignored on the events channel
- if mask&unix.IN_IGNORED == 0 && mask&unix.IN_CLOSE_WRITE != 0 {
+ if mask&unix.IN_IGNORED == 0 && mask&^uint32(unix.IN_DELETE_SELF) != 0 {
eventCh <- name
}
@@ -224,8 +224,8 @@ func (w *Watcher) Run() (<-chan string, <-chan error) {
}
// Add a watch to the inotify watcher.
-func (w *Watcher) Add(name string) error {
- var flags uint32 = unix.IN_CLOSE_WRITE | unix.IN_DELETE_SELF
+func (w *Watcher) Add(name string, flags uint32) error {
+ flags |= unix.IN_DELETE_SELF
return w.watches.updatePath(name, func(existing *watch) (*watch, error) {
if existing != nil {
diff --git a/internal/app/machined/pkg/controllers/block/internal/inotify/inotify_test.go b/internal/app/machined/pkg/controllers/block/internal/inotify/inotify_test.go
index ca57c2d9b9..2965460865 100644
--- a/internal/app/machined/pkg/controllers/block/internal/inotify/inotify_test.go
+++ b/internal/app/machined/pkg/controllers/block/internal/inotify/inotify_test.go
@@ -11,12 +11,37 @@ import (
"time"
"github.com/stretchr/testify/require"
+ "golang.org/x/sys/unix"
"github.com/siderolabs/talos/internal/app/machined/pkg/controllers/block/internal/inotify"
)
-//nolint:gocyclo
-func TestWatcher(t *testing.T) {
+func assertEvent(t *testing.T, watchCh <-chan string, errCh <-chan error, expected string) {
+ t.Helper()
+
+ select {
+ case path := <-watchCh:
+ require.Equal(t, expected, path)
+ case err := <-errCh:
+ require.FailNow(t, "unexpected error", "%s", err)
+ case <-time.After(time.Second):
+ require.FailNow(t, "timeout")
+ }
+}
+
+func assertNoEvent(t *testing.T, watchCh <-chan string, errCh <-chan error) {
+ t.Helper()
+
+ select {
+ case path := <-watchCh:
+ require.FailNow(t, "unexpected path", "%s", path)
+ case err := <-errCh:
+ require.FailNow(t, "unexpected error", "%s", err)
+ case <-time.After(100 * time.Millisecond):
+ }
+}
+
+func TestWatcherCloseWrite(t *testing.T) {
watcher, err := inotify.NewWatcher()
require.NoError(t, err)
@@ -25,19 +50,13 @@ func TestWatcher(t *testing.T) {
require.NoError(t, os.WriteFile(filepath.Join(d, "file1"), []byte("test1"), 0o644))
require.NoError(t, os.WriteFile(filepath.Join(d, "file2"), []byte("test2"), 0o644))
- require.NoError(t, watcher.Add(filepath.Join(d, "file1")))
+ require.NoError(t, watcher.Add(filepath.Join(d, "file1"), unix.IN_CLOSE_WRITE))
watchCh, errCh := watcher.Run()
- require.NoError(t, watcher.Add(filepath.Join(d, "file2")))
+ require.NoError(t, watcher.Add(filepath.Join(d, "file2"), unix.IN_CLOSE_WRITE))
- select {
- case path := <-watchCh:
- require.FailNow(t, "unexpected path", "%s", path)
- case err = <-errCh:
- require.FailNow(t, "unexpected error", "%s", err)
- case <-time.After(100 * time.Millisecond):
- }
+ assertNoEvent(t, watchCh, errCh)
// open file1 for writing, should get inotify event
f1, err := os.OpenFile(filepath.Join(d, "file1"), os.O_WRONLY, 0)
@@ -45,14 +64,7 @@ func TestWatcher(t *testing.T) {
require.NoError(t, f1.Close())
- select {
- case path := <-watchCh:
- require.Equal(t, filepath.Join(d, "file1"), path)
- case err = <-errCh:
- require.FailNow(t, "unexpected error", "%s", err)
- case <-time.After(time.Second):
- require.FailNow(t, "timeout")
- }
+ assertEvent(t, watchCh, errCh, filepath.Join(d, "file1"))
// open file2 for reading, should not get inotify event
f2, err := os.OpenFile(filepath.Join(d, "file2"), os.O_RDONLY, 0)
@@ -60,26 +72,57 @@ func TestWatcher(t *testing.T) {
require.NoError(t, f2.Close())
- select {
- case path := <-watchCh:
- require.FailNow(t, "unexpected path", "%s", path)
- case err = <-errCh:
- require.FailNow(t, "unexpected error", "%s", err)
- case <-time.After(100 * time.Millisecond):
- }
+ assertNoEvent(t, watchCh, errCh)
// remove file2
require.NoError(t, os.Remove(filepath.Join(d, "file2")))
- select {
- case path := <-watchCh:
- require.FailNow(t, "unexpected path", "%s", path)
- case err = <-errCh:
- require.FailNow(t, "unexpected error", "%s", err)
- case <-time.After(100 * time.Millisecond):
- }
+ assertNoEvent(t, watchCh, errCh)
require.NoError(t, watcher.Remove(filepath.Join(d, "file2")))
require.NoError(t, watcher.Close())
}
+
+func TestWatcherDirectory(t *testing.T) {
+ watcher, err := inotify.NewWatcher()
+ require.NoError(t, err)
+
+ d := t.TempDir()
+
+ require.NoError(t, os.Mkdir(filepath.Join(d, "dir1"), 0o755))
+
+ require.NoError(t, os.Symlink("a1", filepath.Join(d, "dir1", "link1")))
+ require.NoError(t, os.Symlink("a2", filepath.Join(d, "dir1", "link2")))
+
+ require.NoError(t, watcher.Add(d, unix.IN_CREATE|unix.IN_DELETE|unix.IN_MOVE))
+ require.NoError(t, watcher.Add(filepath.Join(d, "dir1"), unix.IN_CREATE|unix.IN_DELETE|unix.IN_MOVE))
+
+ watchCh, errCh := watcher.Run()
+
+ assertNoEvent(t, watchCh, errCh)
+
+ require.NoError(t, os.Remove(filepath.Join(d, "dir1", "link1")))
+
+ assertEvent(t, watchCh, errCh, filepath.Join(d, "dir1", "link1"))
+
+ require.NoError(t, os.Mkdir(filepath.Join(d, "dir2"), 0o755))
+
+ assertEvent(t, watchCh, errCh, filepath.Join(d, "dir2"))
+
+ require.NoError(t, os.Symlink("a3", filepath.Join(d, "dir1", "#.link3")))
+
+ assertEvent(t, watchCh, errCh, filepath.Join(d, "dir1", "#.link3"))
+
+ require.NoError(t, os.Rename(filepath.Join(d, "dir1", "#.link3"), filepath.Join(d, "dir1", "link3")))
+
+ assertEvent(t, watchCh, errCh, filepath.Join(d, "dir1", "#.link3"))
+ assertEvent(t, watchCh, errCh, filepath.Join(d, "dir1", "link3"))
+
+ // no more events
+ assertNoEvent(t, watchCh, errCh)
+
+ require.NoError(t, watcher.Remove(d))
+
+ require.NoError(t, watcher.Close())
+}
diff --git a/internal/app/machined/pkg/controllers/block/symlinks.go b/internal/app/machined/pkg/controllers/block/symlinks.go
new file mode 100644
index 0000000000..161dd806e1
--- /dev/null
+++ b/internal/app/machined/pkg/controllers/block/symlinks.go
@@ -0,0 +1,239 @@
+// 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 block
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io/fs"
+ "os"
+ "path/filepath"
+ "slices"
+ "strings"
+
+ "github.com/cosi-project/runtime/pkg/controller"
+ "github.com/cosi-project/runtime/pkg/safe"
+ "github.com/cosi-project/runtime/pkg/state"
+ "github.com/siderolabs/gen/optional"
+ "go.uber.org/zap"
+ "golang.org/x/sys/unix"
+
+ "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/block/internal/inotify"
+ "github.com/siderolabs/talos/pkg/machinery/resources/block"
+ "github.com/siderolabs/talos/pkg/machinery/resources/v1alpha1"
+)
+
+// SymlinksController provides a view of symlinks created by udevd to the blockdevices.
+type SymlinksController struct{}
+
+// Name implements controller.Controller interface.
+func (ctrl *SymlinksController) Name() string {
+ return "block.SymlinksController"
+}
+
+// Inputs implements controller.Controller interface.
+func (ctrl *SymlinksController) Inputs() []controller.Input {
+ return []controller.Input{
+ {
+ Namespace: v1alpha1.NamespaceName,
+ Type: v1alpha1.ServiceType,
+ ID: optional.Some("udevd"),
+ Kind: controller.InputWeak,
+ },
+ }
+}
+
+// Outputs implements controller.Controller interface.
+func (ctrl *SymlinksController) Outputs() []controller.Output {
+ return []controller.Output{
+ {
+ Type: block.SymlinkType,
+ Kind: controller.OutputExclusive,
+ },
+ }
+}
+
+const (
+ baseDevDiskPath = "/dev/disk"
+ tempSymlinkPrefix = ".#"
+)
+
+// Run implements controller.Controller interface.
+//
+//nolint:gocyclo,cyclop
+func (ctrl *SymlinksController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error {
+ // wait for udevd to be healthy & running
+ for {
+ select {
+ case <-ctx.Done():
+ return nil
+ case <-r.EventCh():
+ }
+
+ udevdService, err := safe.ReaderGetByID[*v1alpha1.Service](ctx, r, "udevd")
+ if err != nil {
+ if state.IsNotFoundError(err) {
+ continue
+ }
+
+ return fmt.Errorf("failed to get udevd service: %w", err)
+ }
+
+ if udevdService.TypedSpec().Healthy && udevdService.TypedSpec().Running {
+ break
+ }
+ }
+
+ // start the inotify watcher
+ inotifyWatcher, err := inotify.NewWatcher()
+ if err != nil {
+ return fmt.Errorf("failed to create inotify watcher: %w", err)
+ }
+
+ defer inotifyWatcher.Close() //nolint:errcheck
+
+ inotifyCh, inotifyErrCh := inotifyWatcher.Run()
+
+ // build initial list of symlinks
+ //
+ // map of path -> destination
+ detectedSymlinks := map[string]string{}
+
+ // get list of subpaths under /dev/disk
+ if err = ctrl.handleDir(logger, inotifyWatcher, detectedSymlinks, baseDevDiskPath); err != nil {
+ return err
+ }
+
+ if err = ctrl.updateOutputs(ctx, r, detectedSymlinks); err != nil {
+ return err
+ }
+
+ // now wait for inotify events
+ for {
+ select {
+ case <-ctx.Done():
+ return nil
+ case updatedPath := <-inotifyCh:
+ logger.Debug("inotify event", zap.String("path", updatedPath))
+
+ st, err := os.Stat(updatedPath)
+ if err != nil {
+ if errors.Is(err, fs.ErrNotExist) {
+ delete(detectedSymlinks, updatedPath)
+ } else {
+ return fmt.Errorf("failed to stat %q: %w", updatedPath, err)
+ }
+ } else {
+ if st.IsDir() {
+ if err = ctrl.handleDir(logger, inotifyWatcher, detectedSymlinks, updatedPath); err != nil {
+ return err
+ }
+ } else {
+ dest, err := os.Readlink(updatedPath)
+ if err != nil {
+ if errors.Is(err, fs.ErrNotExist) || errors.Is(err, unix.EINVAL) {
+ delete(detectedSymlinks, updatedPath)
+ } else {
+ return fmt.Errorf("failed to readlink %q: %w", updatedPath, err)
+ }
+ } else if !strings.HasPrefix(filepath.Base(updatedPath), tempSymlinkPrefix) {
+ detectedSymlinks[updatedPath] = dest
+ }
+ }
+ }
+ case watchErr := <-inotifyErrCh:
+ return fmt.Errorf("inotify watcher failed: %w", watchErr)
+ }
+
+ if err = ctrl.updateOutputs(ctx, r, detectedSymlinks); err != nil {
+ return err
+ }
+ }
+}
+
+func (ctrl *SymlinksController) updateOutputs(ctx context.Context, r controller.Runtime, detectedSymlinks map[string]string) error {
+ r.StartTrackingOutputs()
+
+ deviceToSymlinks := map[string][]string{}
+
+ for path, dest := range detectedSymlinks {
+ devicePath := filepath.Base(dest)
+
+ deviceToSymlinks[devicePath] = append(deviceToSymlinks[devicePath], path)
+ }
+
+ for devicePath := range deviceToSymlinks {
+ slices.Sort(deviceToSymlinks[devicePath])
+ }
+
+ for devicePath, symlinks := range deviceToSymlinks {
+ if err := safe.WriterModify(ctx, r, block.NewSymlink(block.NamespaceName, devicePath), func(symlink *block.Symlink) error {
+ symlink.TypedSpec().Paths = symlinks
+
+ return nil
+ }); err != nil {
+ return fmt.Errorf("failed to update symlink %q: %w", devicePath, err)
+ }
+ }
+
+ return safe.CleanupOutputs[*block.Symlink](ctx, r)
+}
+
+//nolint:gocyclo
+func (ctrl *SymlinksController) handleDir(logger *zap.Logger, inotifyWatcher *inotify.Watcher, detectedSymlinks map[string]string, path string) error {
+ if err := inotifyWatcher.Add(path, unix.IN_CREATE|unix.IN_DELETE|unix.IN_MOVE); err != nil {
+ logger.Debug("failed to add inotify watch", zap.String("path", path), zap.Error(err))
+
+ if !errors.Is(err, fs.ErrNotExist) {
+ return fmt.Errorf("failed to add inotify watch for %q: %w", path, err)
+ }
+ }
+
+ logger.Debug("processing directory", zap.String("path", path))
+
+ entries, err := os.ReadDir(path)
+ if err != nil {
+ if errors.Is(err, fs.ErrNotExist) {
+ return nil
+ }
+
+ return fmt.Errorf("failed to read directory %q: %w", path, err)
+ }
+
+ for _, entry := range entries {
+ fullPath := filepath.Join(path, entry.Name())
+
+ st, err := os.Stat(fullPath)
+ if err != nil {
+ if errors.Is(err, fs.ErrNotExist) {
+ continue
+ }
+
+ return fmt.Errorf("failed to stat %q: %w", fullPath, err)
+ }
+
+ if st.IsDir() {
+ if err = ctrl.handleDir(logger, inotifyWatcher, detectedSymlinks, fullPath); err != nil {
+ return err
+ }
+ } else {
+ dest, err := os.Readlink(fullPath)
+ if err != nil {
+ if errors.Is(err, fs.ErrNotExist) || errors.Is(err, unix.EINVAL) {
+ continue
+ }
+
+ return fmt.Errorf("failed to readlink %q: %w", fullPath, err)
+ }
+
+ if !strings.HasPrefix(entry.Name(), tempSymlinkPrefix) {
+ detectedSymlinks[fullPath] = dest
+ }
+ }
+ }
+
+ return nil
+}
diff --git a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go
index 4aa22de03a..08ebbaa092 100644
--- a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go
+++ b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go
@@ -97,6 +97,7 @@ func (ctrl *Controller) Run(ctx context.Context, drainer *runtime.Drainer) error
&block.LVMActivationController{
V1Alpha1Mode: ctrl.v1alpha1Runtime.State().Platform().Mode(),
},
+ &block.SymlinksController{},
&block.SystemDiskController{},
&block.UserDiskConfigController{},
&block.VolumeConfigController{
diff --git a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_state.go b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_state.go
index 0771842fe7..78b15b826e 100644
--- a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_state.go
+++ b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_state.go
@@ -100,6 +100,7 @@ func NewState() (*State, error) {
&block.DiscoveryRefreshRequest{},
&block.DiscoveryRefreshStatus{},
&block.Disk{},
+ &block.Symlink{},
&block.SystemDisk{},
&block.UserDiskConfigStatus{},
&block.VolumeConfig{},
diff --git a/internal/integration/api/volumes.go b/internal/integration/api/volumes.go
index e5e29f0f47..c32b6faaaf 100644
--- a/internal/integration/api/volumes.go
+++ b/internal/integration/api/volumes.go
@@ -9,13 +9,19 @@ package api
import (
"context"
"fmt"
+ "path/filepath"
+ "slices"
"strings"
"testing"
"time"
+ "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
+ "github.com/cosi-project/runtime/pkg/state"
+ "github.com/google/uuid"
"github.com/siderolabs/talos/internal/integration/base"
+ "github.com/siderolabs/talos/pkg/machinery/api/storage"
"github.com/siderolabs/talos/pkg/machinery/client"
"github.com/siderolabs/talos/pkg/machinery/config/machine"
"github.com/siderolabs/talos/pkg/machinery/resources/block"
@@ -155,6 +161,7 @@ func (suite *VolumesSuite) TestDisks() {
suite.Assert().NotEmpty(disk.TypedSpec().Size, "disk: %s", disk.Metadata().ID())
}
+ suite.Assert().NotEmpty(disk.TypedSpec().Symlinks, "disk: %s", disk.Metadata().ID())
suite.Assert().NotEmpty(disk.TypedSpec().IOSize, "disk: %s", disk.Metadata().ID())
suite.Assert().NotEmpty(disk.TypedSpec().SectorSize, "disk: %s", disk.Metadata().ID())
@@ -305,6 +312,91 @@ func (suite *VolumesSuite) lvmVolumeExists(node string) bool {
return lvmVolumeCount >= 6
}
+// TestSymlinks that Talos can update disk symlinks on the fly.
+func (suite *VolumesSuite) TestSymlinks() {
+ if testing.Short() {
+ suite.T().Skip("skipping test in short mode.")
+ }
+
+ if suite.Cluster == nil || suite.Cluster.Provisioner() != base.ProvisionerQEMU {
+ suite.T().Skip("skipping test for non-qemu provisioner")
+ }
+
+ node := suite.RandomDiscoveredNodeInternalIP(machine.TypeWorker)
+
+ k8sNode, err := suite.GetK8sNodeByInternalIP(suite.ctx, node)
+ suite.Require().NoError(err)
+
+ nodeName := k8sNode.Name
+
+ userDisks := suite.UserDisks(suite.ctx, node)
+
+ if len(userDisks) < 1 {
+ suite.T().Skipf("skipping test, not enough user disks available on node %s/%s: %q", node, nodeName, userDisks)
+ }
+
+ userDisk := userDisks[0]
+ userDiskName := filepath.Base(userDisk)
+
+ suite.T().Logf("performing a symlink test %s on %s/%s", userDisk, node, nodeName)
+
+ podDef, err := suite.NewPrivilegedPod("xfs-format")
+ suite.Require().NoError(err)
+
+ podDef = podDef.WithNodeName(nodeName)
+
+ suite.Require().NoError(podDef.Create(suite.ctx, 5*time.Minute))
+
+ defer podDef.Delete(suite.ctx) //nolint:errcheck
+
+ fsUUID := uuid.New().String()
+
+ _, _, err = podDef.Exec(
+ suite.ctx,
+ fmt.Sprintf("nsenter --mount=/proc/1/ns/mnt -- mkfs.xfs -m uuid=%s %s", fsUUID, userDisk),
+ )
+ suite.Require().NoError(err)
+
+ expectedSymlink := "/dev/disk/by-uuid/" + fsUUID
+
+ // Talos should report a symlink to the disk via FS UUID
+ _, err = suite.Client.COSI.WatchFor(client.WithNode(suite.ctx, node), block.NewDisk(block.NamespaceName, userDiskName).Metadata(),
+ state.WithCondition(func(r resource.Resource) (bool, error) {
+ disk, ok := r.(*block.Disk)
+ if !ok {
+ return false, fmt.Errorf("unexpected resource type: %T", r)
+ }
+
+ return slices.Index(disk.TypedSpec().Symlinks, expectedSymlink) != -1, nil
+ }),
+ )
+ suite.Require().NoError(err)
+
+ suite.T().Logf("wiping user disk %s on %s/%s", userDisk, node, nodeName)
+
+ suite.Require().NoError(suite.Client.BlockDeviceWipe(client.WithNode(suite.ctx, node), &storage.BlockDeviceWipeRequest{
+ Devices: []*storage.BlockDeviceWipeDescriptor{
+ {
+ Device: userDiskName,
+ Method: storage.BlockDeviceWipeDescriptor_FAST,
+ },
+ },
+ }))
+
+ // Talos should remove a symlink to the disk
+ _, err = suite.Client.COSI.WatchFor(client.WithNode(suite.ctx, node), block.NewDisk(block.NamespaceName, userDiskName).Metadata(),
+ state.WithCondition(func(r resource.Resource) (bool, error) {
+ disk, ok := r.(*block.Disk)
+ if !ok {
+ return false, fmt.Errorf("unexpected resource type: %T", r)
+ }
+
+ return slices.Index(disk.TypedSpec().Symlinks, expectedSymlink) == -1, nil
+ }),
+ )
+ suite.Require().NoError(err)
+}
+
func init() {
allSuites = append(allSuites, new(VolumesSuite))
}
diff --git a/pkg/machinery/api/resource/definitions/block/block.pb.go b/pkg/machinery/api/resource/definitions/block/block.pb.go
index 99fb399a1d..71180bfde1 100644
--- a/pkg/machinery/api/resource/definitions/block/block.pb.go
+++ b/pkg/machinery/api/resource/definitions/block/block.pb.go
@@ -477,6 +477,7 @@ type DiskSpec struct {
PrettySize string `protobuf:"bytes,15,opt,name=pretty_size,json=prettySize,proto3" json:"pretty_size,omitempty"`
SecondaryDisks []string `protobuf:"bytes,16,rep,name=secondary_disks,json=secondaryDisks,proto3" json:"secondary_disks,omitempty"`
Uuid string `protobuf:"bytes,17,opt,name=uuid,proto3" json:"uuid,omitempty"`
+ Symlinks []string `protobuf:"bytes,18,rep,name=symlinks,proto3" json:"symlinks,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -630,6 +631,13 @@ func (x *DiskSpec) GetUuid() string {
return ""
}
+func (x *DiskSpec) GetSymlinks() []string {
+ if x != nil {
+ return x.Symlinks
+ }
+ return nil
+}
+
// EncryptionKey is the spec for volume encryption key.
type EncryptionKey struct {
state protoimpl.MessageState `protogen:"open.v1"`
@@ -1089,6 +1097,51 @@ func (x *ProvisioningSpec) GetFilesystemSpec() *FilesystemSpec {
return nil
}
+// SymlinkSpec is the spec for Symlinks resource.
+type SymlinkSpec struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ Paths []string `protobuf:"bytes,1,rep,name=paths,proto3" json:"paths,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *SymlinkSpec) Reset() {
+ *x = SymlinkSpec{}
+ mi := &file_resource_definitions_block_block_proto_msgTypes[13]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *SymlinkSpec) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SymlinkSpec) ProtoMessage() {}
+
+func (x *SymlinkSpec) ProtoReflect() protoreflect.Message {
+ mi := &file_resource_definitions_block_block_proto_msgTypes[13]
+ 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 SymlinkSpec.ProtoReflect.Descriptor instead.
+func (*SymlinkSpec) Descriptor() ([]byte, []int) {
+ return file_resource_definitions_block_block_proto_rawDescGZIP(), []int{13}
+}
+
+func (x *SymlinkSpec) GetPaths() []string {
+ if x != nil {
+ return x.Paths
+ }
+ return nil
+}
+
// SystemDiskSpec is the spec for SystemDisks resource.
type SystemDiskSpec struct {
state protoimpl.MessageState `protogen:"open.v1"`
@@ -1100,7 +1153,7 @@ type SystemDiskSpec struct {
func (x *SystemDiskSpec) Reset() {
*x = SystemDiskSpec{}
- mi := &file_resource_definitions_block_block_proto_msgTypes[13]
+ mi := &file_resource_definitions_block_block_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1112,7 +1165,7 @@ func (x *SystemDiskSpec) String() string {
func (*SystemDiskSpec) ProtoMessage() {}
func (x *SystemDiskSpec) ProtoReflect() protoreflect.Message {
- mi := &file_resource_definitions_block_block_proto_msgTypes[13]
+ mi := &file_resource_definitions_block_block_proto_msgTypes[14]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1125,7 +1178,7 @@ func (x *SystemDiskSpec) ProtoReflect() protoreflect.Message {
// Deprecated: Use SystemDiskSpec.ProtoReflect.Descriptor instead.
func (*SystemDiskSpec) Descriptor() ([]byte, []int) {
- return file_resource_definitions_block_block_proto_rawDescGZIP(), []int{13}
+ return file_resource_definitions_block_block_proto_rawDescGZIP(), []int{14}
}
func (x *SystemDiskSpec) GetDiskId() string {
@@ -1152,7 +1205,7 @@ type UserDiskConfigStatusSpec struct {
func (x *UserDiskConfigStatusSpec) Reset() {
*x = UserDiskConfigStatusSpec{}
- mi := &file_resource_definitions_block_block_proto_msgTypes[14]
+ mi := &file_resource_definitions_block_block_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1164,7 +1217,7 @@ func (x *UserDiskConfigStatusSpec) String() string {
func (*UserDiskConfigStatusSpec) ProtoMessage() {}
func (x *UserDiskConfigStatusSpec) ProtoReflect() protoreflect.Message {
- mi := &file_resource_definitions_block_block_proto_msgTypes[14]
+ mi := &file_resource_definitions_block_block_proto_msgTypes[15]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1177,7 +1230,7 @@ func (x *UserDiskConfigStatusSpec) ProtoReflect() protoreflect.Message {
// Deprecated: Use UserDiskConfigStatusSpec.ProtoReflect.Descriptor instead.
func (*UserDiskConfigStatusSpec) Descriptor() ([]byte, []int) {
- return file_resource_definitions_block_block_proto_rawDescGZIP(), []int{14}
+ return file_resource_definitions_block_block_proto_rawDescGZIP(), []int{15}
}
func (x *UserDiskConfigStatusSpec) GetReady() bool {
@@ -1202,7 +1255,7 @@ type VolumeConfigSpec struct {
func (x *VolumeConfigSpec) Reset() {
*x = VolumeConfigSpec{}
- mi := &file_resource_definitions_block_block_proto_msgTypes[15]
+ mi := &file_resource_definitions_block_block_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1214,7 +1267,7 @@ func (x *VolumeConfigSpec) String() string {
func (*VolumeConfigSpec) ProtoMessage() {}
func (x *VolumeConfigSpec) ProtoReflect() protoreflect.Message {
- mi := &file_resource_definitions_block_block_proto_msgTypes[15]
+ mi := &file_resource_definitions_block_block_proto_msgTypes[16]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1227,7 +1280,7 @@ func (x *VolumeConfigSpec) ProtoReflect() protoreflect.Message {
// Deprecated: Use VolumeConfigSpec.ProtoReflect.Descriptor instead.
func (*VolumeConfigSpec) Descriptor() ([]byte, []int) {
- return file_resource_definitions_block_block_proto_rawDescGZIP(), []int{15}
+ return file_resource_definitions_block_block_proto_rawDescGZIP(), []int{16}
}
func (x *VolumeConfigSpec) GetParentId() string {
@@ -1295,7 +1348,7 @@ type VolumeStatusSpec struct {
func (x *VolumeStatusSpec) Reset() {
*x = VolumeStatusSpec{}
- mi := &file_resource_definitions_block_block_proto_msgTypes[16]
+ mi := &file_resource_definitions_block_block_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1307,7 +1360,7 @@ func (x *VolumeStatusSpec) String() string {
func (*VolumeStatusSpec) ProtoMessage() {}
func (x *VolumeStatusSpec) ProtoReflect() protoreflect.Message {
- mi := &file_resource_definitions_block_block_proto_msgTypes[16]
+ mi := &file_resource_definitions_block_block_proto_msgTypes[17]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1320,7 +1373,7 @@ func (x *VolumeStatusSpec) ProtoReflect() protoreflect.Message {
// Deprecated: Use VolumeStatusSpec.ProtoReflect.Descriptor instead.
func (*VolumeStatusSpec) Descriptor() ([]byte, []int) {
- return file_resource_definitions_block_block_proto_rawDescGZIP(), []int{16}
+ return file_resource_definitions_block_block_proto_rawDescGZIP(), []int{17}
}
func (x *VolumeStatusSpec) GetPhase() enums.BlockVolumePhase {
@@ -1501,7 +1554,7 @@ var file_resource_definitions_block_block_proto_rawDesc = []byte{
0x72, 0x12, 0x3b, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x78,
0x70, 0x72, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63,
- 0x6b, 0x65, 0x64, 0x45, 0x78, 0x70, 0x72, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x22, 0xd9,
+ 0x6b, 0x65, 0x64, 0x45, 0x78, 0x70, 0x72, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x22, 0xf5,
0x03, 0x0a, 0x08, 0x44, 0x69, 0x73, 0x6b, 0x53, 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x73,
0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12,
0x17, 0x0a, 0x07, 0x69, 0x6f, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04,
@@ -1531,176 +1584,181 @@ var file_resource_definitions_block_block_proto_rawDesc = []byte{
0x0f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x64, 0x69, 0x73, 0x6b, 0x73,
0x18, 0x10, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72,
0x79, 0x44, 0x69, 0x73, 0x6b, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x11,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0x92, 0x02, 0x0a, 0x0d, 0x45,
- 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04,
- 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x6c, 0x6f, 0x74,
- 0x12, 0x4c, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x38,
- 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, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f,
- 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2b,
- 0x0a, 0x11, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72,
- 0x61, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x73, 0x74, 0x61, 0x74, 0x69,
- 0x63, 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6b,
- 0x6d, 0x73, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x0b, 0x6b, 0x6d, 0x73, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x4f,
- 0x0a, 0x25, 0x74, 0x70, 0x6d, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x73, 0x65, 0x63, 0x75,
- 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x6f, 0x6e,
- 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x74,
- 0x70, 0x6d, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x62, 0x6f, 0x6f,
- 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x22,
- 0xa5, 0x02, 0x0a, 0x0e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x70,
- 0x65, 0x63, 0x12, 0x59, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3d, 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, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x45, 0x6e, 0x63,
- 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54,
- 0x79, 0x70, 0x65, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x43, 0x0a,
- 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 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, 0x4b, 0x65, 0x79, 0x52, 0x04, 0x6b, 0x65,
- 0x79, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x06, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65,
- 0x79, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6b, 0x65,
- 0x79, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x73,
- 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
- 0x53, 0x69, 0x7a, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x65, 0x72, 0x66, 0x5f, 0x6f, 0x70, 0x74,
- 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x66,
- 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x71, 0x0a, 0x0e, 0x46, 0x69, 0x6c, 0x65, 0x73,
- 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, 0x70, 0x65, 0x63, 0x12, 0x49, 0x0a, 0x04, 0x74, 0x79, 0x70,
- 0x65, 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, 0x42, 0x6c, 0x6f, 0x63, 0x6b,
- 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04,
- 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x4a, 0x0a, 0x0b, 0x4c, 0x6f,
- 0x63, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x12, 0x3b, 0x0a, 0x05, 0x6d, 0x61, 0x74,
- 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
- 0x68, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x45, 0x78, 0x70, 0x72, 0x52,
- 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x22, 0x51, 0x0a, 0x09, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x53,
- 0x70, 0x65, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x61,
- 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74,
- 0x50, 0x61, 0x74, 0x68, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x5f,
- 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x65, 0x6c,
- 0x69, 0x6e, 0x75, 0x78, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x8c, 0x01, 0x0a, 0x0d, 0x50, 0x61,
- 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x19, 0x0a, 0x08, 0x6d,
- 0x69, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d,
- 0x69, 0x6e, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x69,
- 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x53, 0x69, 0x7a,
- 0x65, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x72, 0x6f, 0x77, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52,
- 0x04, 0x67, 0x72, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x04,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x74,
- 0x79, 0x70, 0x65, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
- 0x74, 0x79, 0x70, 0x65, 0x55, 0x75, 0x69, 0x64, 0x22, 0xae, 0x02, 0x0a, 0x10, 0x50, 0x72, 0x6f,
- 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x53, 0x70, 0x65, 0x63, 0x12, 0x53, 0x0a,
- 0x0d, 0x64, 0x69, 0x73, 0x6b, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01,
- 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, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x44, 0x69, 0x73, 0x6b, 0x53, 0x65, 0x6c, 0x65,
- 0x63, 0x74, 0x6f, 0x72, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x6b, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74,
- 0x6f, 0x72, 0x12, 0x56, 0x0a, 0x0e, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f,
- 0x73, 0x70, 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x61, 0x6c,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x79,
+ 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x12, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x79,
+ 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x22, 0x92, 0x02, 0x0a, 0x0d, 0x45, 0x6e, 0x63, 0x72, 0x79,
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6c, 0x6f, 0x74,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x12, 0x4c, 0x0a, 0x04,
+ 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x38, 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, 0x50, 0x61,
- 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0d, 0x70, 0x61, 0x72,
- 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61,
- 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x77, 0x61, 0x76, 0x65, 0x12, 0x59,
- 0x0a, 0x0f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x73, 0x70, 0x65,
- 0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e,
+ 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x42, 0x6c,
+ 0x6f, 0x63, 0x6b, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79,
+ 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x73, 0x74,
+ 0x61, 0x74, 0x69, 0x63, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x18,
+ 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x50, 0x61, 0x73,
+ 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6b, 0x6d, 0x73, 0x5f, 0x65,
+ 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6b,
+ 0x6d, 0x73, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x4f, 0x0a, 0x25, 0x74, 0x70,
+ 0x6d, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x62, 0x6f,
+ 0x6f, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x72,
+ 0x6f, 0x6c, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x74, 0x70, 0x6d, 0x43, 0x68,
+ 0x65, 0x63, 0x6b, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x53, 0x74, 0x61,
+ 0x74, 0x75, 0x73, 0x4f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x22, 0xa5, 0x02, 0x0a, 0x0e,
+ 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x59,
+ 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
+ 0x32, 0x3d, 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, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x52,
+ 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x43, 0x0a, 0x04, 0x6b, 0x65, 0x79,
+ 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 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, 0x46, 0x69, 0x6c, 0x65, 0x73,
- 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x73,
- 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, 0x70, 0x65, 0x63, 0x22, 0x44, 0x0a, 0x0e, 0x53, 0x79, 0x73,
- 0x74, 0x65, 0x6d, 0x44, 0x69, 0x73, 0x6b, 0x53, 0x70, 0x65, 0x63, 0x12, 0x17, 0x0a, 0x07, 0x64,
- 0x69, 0x73, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69,
- 0x73, 0x6b, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x65, 0x76, 0x5f, 0x70, 0x61, 0x74, 0x68,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x76, 0x50, 0x61, 0x74, 0x68, 0x22,
- 0x30, 0x0a, 0x18, 0x55, 0x73, 0x65, 0x72, 0x44, 0x69, 0x73, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x72,
- 0x65, 0x61, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x72, 0x65, 0x61, 0x64,
- 0x79, 0x22, 0xac, 0x03, 0x0a, 0x10, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66,
- 0x69, 0x67, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74,
- 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e,
- 0x74, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x0e, 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, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65,
- 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x56, 0x0a, 0x0c, 0x70, 0x72,
- 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
- 0x32, 0x32, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
+ 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79,
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x12, 0x16,
+ 0x0a, 0x06, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
+ 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x69,
+ 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x53, 0x69, 0x7a,
+ 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18,
+ 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x69, 0x7a, 0x65,
+ 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x65, 0x72, 0x66, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+ 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x66, 0x4f, 0x70, 0x74, 0x69,
+ 0x6f, 0x6e, 0x73, 0x22, 0x71, 0x0a, 0x0e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65,
+ 0x6d, 0x53, 0x70, 0x65, 0x63, 0x12, 0x49, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 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, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65,
+ 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
+ 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x4a, 0x0a, 0x0b, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x6f,
+ 0x72, 0x53, 0x70, 0x65, 0x63, 0x12, 0x3b, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70,
+ 0x69, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
+ 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x45, 0x78, 0x70, 0x72, 0x52, 0x05, 0x6d, 0x61, 0x74,
+ 0x63, 0x68, 0x22, 0x51, 0x0a, 0x09, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12,
+ 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x61, 0x74, 0x68,
+ 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x5f, 0x6c, 0x61, 0x62, 0x65,
+ 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x75, 0x78,
+ 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x8c, 0x01, 0x0a, 0x0d, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74,
+ 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x69, 0x6e, 0x5f, 0x73,
+ 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x69, 0x6e, 0x53, 0x69,
+ 0x7a, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a,
+ 0x04, 0x67, 0x72, 0x6f, 0x77, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x67, 0x72, 0x6f,
+ 0x77, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f,
+ 0x75, 0x75, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65,
+ 0x55, 0x75, 0x69, 0x64, 0x22, 0xae, 0x02, 0x0a, 0x10, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69,
+ 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x53, 0x70, 0x65, 0x63, 0x12, 0x53, 0x0a, 0x0d, 0x64, 0x69, 0x73,
+ 0x6b, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 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, 0x62, 0x6c,
- 0x6f, 0x63, 0x6b, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67,
- 0x53, 0x70, 0x65, 0x63, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69,
- 0x6e, 0x67, 0x12, 0x47, 0x0a, 0x07, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x04, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f,
+ 0x6f, 0x63, 0x6b, 0x2e, 0x44, 0x69, 0x73, 0x6b, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72,
+ 0x52, 0x0c, 0x64, 0x69, 0x73, 0x6b, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x56,
+ 0x0a, 0x0e, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x70, 0x65, 0x63,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 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, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74,
+ 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0d, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69,
+ 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, 0x76, 0x65, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x77, 0x61, 0x76, 0x65, 0x12, 0x59, 0x0a, 0x0f, 0x66, 0x69,
+ 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x18, 0x04, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x30, 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, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x70,
- 0x65, 0x63, 0x52, 0x07, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x41, 0x0a, 0x05, 0x6d,
- 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 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, 0x4d, 0x6f,
- 0x75, 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x50,
- 0x0a, 0x0a, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01,
- 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75,
+ 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65,
+ 0x6d, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65,
+ 0x6d, 0x53, 0x70, 0x65, 0x63, 0x22, 0x23, 0x0a, 0x0b, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b,
+ 0x53, 0x70, 0x65, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x01, 0x20,
+ 0x03, 0x28, 0x09, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x22, 0x44, 0x0a, 0x0e, 0x53, 0x79,
+ 0x73, 0x74, 0x65, 0x6d, 0x44, 0x69, 0x73, 0x6b, 0x53, 0x70, 0x65, 0x63, 0x12, 0x17, 0x0a, 0x07,
+ 0x64, 0x69, 0x73, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64,
+ 0x69, 0x73, 0x6b, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x65, 0x76, 0x5f, 0x70, 0x61, 0x74,
+ 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x76, 0x50, 0x61, 0x74, 0x68,
+ 0x22, 0x30, 0x0a, 0x18, 0x55, 0x73, 0x65, 0x72, 0x44, 0x69, 0x73, 0x6b, 0x43, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x14, 0x0a, 0x05,
+ 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x72, 0x65, 0x61,
+ 0x64, 0x79, 0x22, 0xac, 0x03, 0x0a, 0x10, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x43, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e,
+ 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65,
+ 0x6e, 0x74, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x0e, 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,
- 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, 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,
+ 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x6f, 0x6c, 0x75, 0x6d,
+ 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x56, 0x0a, 0x0c, 0x70,
+ 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x03, 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, 0x62,
+ 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e,
+ 0x67, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
+ 0x69, 0x6e, 0x67, 0x12, 0x47, 0x0a, 0x07, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x04,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 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, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x53,
+ 0x70, 0x65, 0x63, 0x52, 0x07, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x41, 0x0a, 0x05,
+ 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 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, 0x4d,
+ 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12,
+ 0x50, 0x0a, 0x0a, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x30, 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, 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, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f,
+ 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x6f,
+ 0x6c, 0x75, 0x6d, 0x65, 0x50, 0x68, 0x61, 0x73, 0x65, 0x52, 0x05, 0x70, 0x68, 0x61, 0x73, 0x65,
+ 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d,
+ 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
+ 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69,
+ 0x6f, 0x6e, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70,
+ 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x75, 0x69, 0x64, 0x12, 0x58, 0x0a, 0x0e,
+ 0x70, 0x72, 0x65, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x5f, 0x70, 0x68, 0x61, 0x73, 0x65, 0x18, 0x06,
0x20, 0x01, 0x28, 0x0e, 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, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x6f, 0x6c,
- 0x75, 0x6d, 0x65, 0x50, 0x68, 0x61, 0x73, 0x65, 0x52, 0x05, 0x70, 0x68, 0x61, 0x73, 0x65, 0x12,
- 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x65,
- 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
- 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
- 0x75, 0x75, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f,
- 0x6e, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x61,
- 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x75, 0x69, 0x64, 0x12, 0x58, 0x0a, 0x0e, 0x70,
- 0x72, 0x65, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x5f, 0x70, 0x68, 0x61, 0x73, 0x65, 0x18, 0x06, 0x20,
- 0x01, 0x28, 0x0e, 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, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x6f, 0x6c, 0x75,
- 0x6d, 0x65, 0x50, 0x68, 0x61, 0x73, 0x65, 0x52, 0x0c, 0x70, 0x72, 0x65, 0x46, 0x61, 0x69, 0x6c,
- 0x50, 0x68, 0x61, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f,
- 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e,
- 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27,
- 0x0a, 0x0f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65,
- 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69,
- 0x6f, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18,
- 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x55, 0x0a, 0x0a, 0x66,
- 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x0a, 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, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74,
- 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74,
- 0x65, 0x6d, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6c, 0x6f, 0x63, 0x61,
- 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6d, 0x6f, 0x75, 0x6e,
- 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x6e, 0x0a, 0x13, 0x65, 0x6e, 0x63,
- 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
- 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3d, 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, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x45,
- 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
- 0x72, 0x54, 0x79, 0x70, 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, 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,
+ 0x75, 0x6d, 0x65, 0x50, 0x68, 0x61, 0x73, 0x65, 0x52, 0x0c, 0x70, 0x72, 0x65, 0x46, 0x61, 0x69,
+ 0x6c, 0x50, 0x68, 0x61, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74,
+ 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x0e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12,
+ 0x27, 0x0a, 0x0f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64,
+ 0x65, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74,
+ 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65,
+ 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x55, 0x0a, 0x0a,
+ 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x0a, 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, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73,
+ 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73,
+ 0x74, 0x65, 0x6d, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6c, 0x6f, 0x63,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6d, 0x6f, 0x75,
+ 0x6e, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x6e, 0x0a, 0x13, 0x65, 0x6e,
+ 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
+ 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3d, 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, 0x42, 0x6c, 0x6f, 0x63, 0x6b,
+ 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64,
+ 0x65, 0x72, 0x54, 0x79, 0x70, 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, 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 (
@@ -1715,7 +1773,7 @@ func file_resource_definitions_block_block_proto_rawDescGZIP() []byte {
return file_resource_definitions_block_block_proto_rawDescData
}
-var file_resource_definitions_block_block_proto_msgTypes = make([]protoimpl.MessageInfo, 17)
+var file_resource_definitions_block_block_proto_msgTypes = make([]protoimpl.MessageInfo, 18)
var file_resource_definitions_block_block_proto_goTypes = []any{
(*DeviceSpec)(nil), // 0: talos.resource.definitions.block.DeviceSpec
(*DiscoveredVolumeSpec)(nil), // 1: talos.resource.definitions.block.DiscoveredVolumeSpec
@@ -1730,36 +1788,37 @@ var file_resource_definitions_block_block_proto_goTypes = []any{
(*MountSpec)(nil), // 10: talos.resource.definitions.block.MountSpec
(*PartitionSpec)(nil), // 11: talos.resource.definitions.block.PartitionSpec
(*ProvisioningSpec)(nil), // 12: talos.resource.definitions.block.ProvisioningSpec
- (*SystemDiskSpec)(nil), // 13: talos.resource.definitions.block.SystemDiskSpec
- (*UserDiskConfigStatusSpec)(nil), // 14: talos.resource.definitions.block.UserDiskConfigStatusSpec
- (*VolumeConfigSpec)(nil), // 15: talos.resource.definitions.block.VolumeConfigSpec
- (*VolumeStatusSpec)(nil), // 16: talos.resource.definitions.block.VolumeStatusSpec
- (*v1alpha1.CheckedExpr)(nil), // 17: google.api.expr.v1alpha1.CheckedExpr
- (enums.BlockEncryptionKeyType)(0), // 18: talos.resource.definitions.enums.BlockEncryptionKeyType
- (enums.BlockEncryptionProviderType)(0), // 19: talos.resource.definitions.enums.BlockEncryptionProviderType
- (enums.BlockFilesystemType)(0), // 20: talos.resource.definitions.enums.BlockFilesystemType
- (enums.BlockVolumeType)(0), // 21: talos.resource.definitions.enums.BlockVolumeType
- (enums.BlockVolumePhase)(0), // 22: talos.resource.definitions.enums.BlockVolumePhase
+ (*SymlinkSpec)(nil), // 13: talos.resource.definitions.block.SymlinkSpec
+ (*SystemDiskSpec)(nil), // 14: talos.resource.definitions.block.SystemDiskSpec
+ (*UserDiskConfigStatusSpec)(nil), // 15: talos.resource.definitions.block.UserDiskConfigStatusSpec
+ (*VolumeConfigSpec)(nil), // 16: talos.resource.definitions.block.VolumeConfigSpec
+ (*VolumeStatusSpec)(nil), // 17: talos.resource.definitions.block.VolumeStatusSpec
+ (*v1alpha1.CheckedExpr)(nil), // 18: google.api.expr.v1alpha1.CheckedExpr
+ (enums.BlockEncryptionKeyType)(0), // 19: talos.resource.definitions.enums.BlockEncryptionKeyType
+ (enums.BlockEncryptionProviderType)(0), // 20: talos.resource.definitions.enums.BlockEncryptionProviderType
+ (enums.BlockFilesystemType)(0), // 21: talos.resource.definitions.enums.BlockFilesystemType
+ (enums.BlockVolumeType)(0), // 22: talos.resource.definitions.enums.BlockVolumeType
+ (enums.BlockVolumePhase)(0), // 23: talos.resource.definitions.enums.BlockVolumePhase
}
var file_resource_definitions_block_block_proto_depIdxs = []int32{
- 17, // 0: talos.resource.definitions.block.DiskSelector.match:type_name -> google.api.expr.v1alpha1.CheckedExpr
- 18, // 1: talos.resource.definitions.block.EncryptionKey.type:type_name -> talos.resource.definitions.enums.BlockEncryptionKeyType
- 19, // 2: talos.resource.definitions.block.EncryptionSpec.provider:type_name -> talos.resource.definitions.enums.BlockEncryptionProviderType
+ 18, // 0: talos.resource.definitions.block.DiskSelector.match:type_name -> google.api.expr.v1alpha1.CheckedExpr
+ 19, // 1: talos.resource.definitions.block.EncryptionKey.type:type_name -> talos.resource.definitions.enums.BlockEncryptionKeyType
+ 20, // 2: talos.resource.definitions.block.EncryptionSpec.provider:type_name -> talos.resource.definitions.enums.BlockEncryptionProviderType
6, // 3: talos.resource.definitions.block.EncryptionSpec.keys:type_name -> talos.resource.definitions.block.EncryptionKey
- 20, // 4: talos.resource.definitions.block.FilesystemSpec.type:type_name -> talos.resource.definitions.enums.BlockFilesystemType
- 17, // 5: talos.resource.definitions.block.LocatorSpec.match:type_name -> google.api.expr.v1alpha1.CheckedExpr
+ 21, // 4: talos.resource.definitions.block.FilesystemSpec.type:type_name -> talos.resource.definitions.enums.BlockFilesystemType
+ 18, // 5: talos.resource.definitions.block.LocatorSpec.match:type_name -> google.api.expr.v1alpha1.CheckedExpr
4, // 6: talos.resource.definitions.block.ProvisioningSpec.disk_selector:type_name -> talos.resource.definitions.block.DiskSelector
11, // 7: talos.resource.definitions.block.ProvisioningSpec.partition_spec:type_name -> talos.resource.definitions.block.PartitionSpec
8, // 8: talos.resource.definitions.block.ProvisioningSpec.filesystem_spec:type_name -> talos.resource.definitions.block.FilesystemSpec
- 21, // 9: talos.resource.definitions.block.VolumeConfigSpec.type:type_name -> talos.resource.definitions.enums.BlockVolumeType
+ 22, // 9: talos.resource.definitions.block.VolumeConfigSpec.type:type_name -> talos.resource.definitions.enums.BlockVolumeType
12, // 10: talos.resource.definitions.block.VolumeConfigSpec.provisioning:type_name -> talos.resource.definitions.block.ProvisioningSpec
9, // 11: talos.resource.definitions.block.VolumeConfigSpec.locator:type_name -> talos.resource.definitions.block.LocatorSpec
10, // 12: talos.resource.definitions.block.VolumeConfigSpec.mount:type_name -> talos.resource.definitions.block.MountSpec
7, // 13: talos.resource.definitions.block.VolumeConfigSpec.encryption:type_name -> talos.resource.definitions.block.EncryptionSpec
- 22, // 14: talos.resource.definitions.block.VolumeStatusSpec.phase:type_name -> talos.resource.definitions.enums.BlockVolumePhase
- 22, // 15: talos.resource.definitions.block.VolumeStatusSpec.pre_fail_phase:type_name -> talos.resource.definitions.enums.BlockVolumePhase
- 20, // 16: talos.resource.definitions.block.VolumeStatusSpec.filesystem:type_name -> talos.resource.definitions.enums.BlockFilesystemType
- 19, // 17: talos.resource.definitions.block.VolumeStatusSpec.encryption_provider:type_name -> talos.resource.definitions.enums.BlockEncryptionProviderType
+ 23, // 14: talos.resource.definitions.block.VolumeStatusSpec.phase:type_name -> talos.resource.definitions.enums.BlockVolumePhase
+ 23, // 15: talos.resource.definitions.block.VolumeStatusSpec.pre_fail_phase:type_name -> talos.resource.definitions.enums.BlockVolumePhase
+ 21, // 16: talos.resource.definitions.block.VolumeStatusSpec.filesystem:type_name -> talos.resource.definitions.enums.BlockFilesystemType
+ 20, // 17: talos.resource.definitions.block.VolumeStatusSpec.encryption_provider:type_name -> talos.resource.definitions.enums.BlockEncryptionProviderType
18, // [18:18] is the sub-list for method output_type
18, // [18:18] is the sub-list for method input_type
18, // [18:18] is the sub-list for extension type_name
@@ -1778,7 +1837,7 @@ func file_resource_definitions_block_block_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_resource_definitions_block_block_proto_rawDesc,
NumEnums: 0,
- NumMessages: 17,
+ NumMessages: 18,
NumExtensions: 0,
NumServices: 0,
},
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 9e41ab3afe..20880292f2 100644
--- a/pkg/machinery/api/resource/definitions/block/block_vtproto.pb.go
+++ b/pkg/machinery/api/resource/definitions/block/block_vtproto.pb.go
@@ -434,6 +434,17 @@ func (m *DiskSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
i -= len(m.unknownFields)
copy(dAtA[i:], m.unknownFields)
}
+ if len(m.Symlinks) > 0 {
+ for iNdEx := len(m.Symlinks) - 1; iNdEx >= 0; iNdEx-- {
+ i -= len(m.Symlinks[iNdEx])
+ copy(dAtA[i:], m.Symlinks[iNdEx])
+ i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Symlinks[iNdEx])))
+ i--
+ dAtA[i] = 0x1
+ i--
+ dAtA[i] = 0x92
+ }
+ }
if len(m.Uuid) > 0 {
i -= len(m.Uuid)
copy(dAtA[i:], m.Uuid)
@@ -990,6 +1001,48 @@ func (m *ProvisioningSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
+func (m *SymlinkSpec) MarshalVT() (dAtA []byte, err error) {
+ if m == nil {
+ return nil, nil
+ }
+ size := m.SizeVT()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBufferVT(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *SymlinkSpec) MarshalToVT(dAtA []byte) (int, error) {
+ size := m.SizeVT()
+ return m.MarshalToSizedBufferVT(dAtA[:size])
+}
+
+func (m *SymlinkSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
+ if m == nil {
+ return 0, nil
+ }
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.unknownFields != nil {
+ i -= len(m.unknownFields)
+ copy(dAtA[i:], m.unknownFields)
+ }
+ if len(m.Paths) > 0 {
+ for iNdEx := len(m.Paths) - 1; iNdEx >= 0; iNdEx-- {
+ i -= len(m.Paths[iNdEx])
+ copy(dAtA[i:], m.Paths[iNdEx])
+ i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Paths[iNdEx])))
+ i--
+ dAtA[i] = 0xa
+ }
+ }
+ return len(dAtA) - i, nil
+}
+
func (m *SystemDiskSpec) MarshalVT() (dAtA []byte, err error) {
if m == nil {
return nil, nil
@@ -1525,6 +1578,12 @@ func (m *DiskSpec) SizeVT() (n int) {
if l > 0 {
n += 2 + l + protohelpers.SizeOfVarint(uint64(l))
}
+ if len(m.Symlinks) > 0 {
+ for _, s := range m.Symlinks {
+ l = len(s)
+ n += 2 + l + protohelpers.SizeOfVarint(uint64(l))
+ }
+ }
n += len(m.unknownFields)
return n
}
@@ -1698,6 +1757,22 @@ func (m *ProvisioningSpec) SizeVT() (n int) {
return n
}
+func (m *SymlinkSpec) SizeVT() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if len(m.Paths) > 0 {
+ for _, s := range m.Paths {
+ l = len(s)
+ n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
+ }
+ }
+ n += len(m.unknownFields)
+ return n
+}
+
func (m *SystemDiskSpec) SizeVT() (n int) {
if m == nil {
return 0
@@ -3412,6 +3487,38 @@ func (m *DiskSpec) UnmarshalVT(dAtA []byte) error {
}
m.Uuid = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
+ case 18:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Symlinks", 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.Symlinks = append(m.Symlinks, string(dAtA[iNdEx:postIndex]))
+ iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := protohelpers.Skip(dAtA[iNdEx:])
@@ -4478,6 +4585,89 @@ func (m *ProvisioningSpec) UnmarshalVT(dAtA []byte) error {
}
return nil
}
+func (m *SymlinkSpec) UnmarshalVT(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return protohelpers.ErrIntOverflow
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: SymlinkSpec: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: SymlinkSpec: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Paths", 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.Paths = append(m.Paths, string(dAtA[iNdEx:postIndex]))
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := protohelpers.Skip(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return protohelpers.ErrInvalidLength
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
func (m *SystemDiskSpec) UnmarshalVT(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
diff --git a/pkg/machinery/resources/block/block.go b/pkg/machinery/resources/block/block.go
index 6327b8a0cd..6e7fe08b4b 100644
--- a/pkg/machinery/resources/block/block.go
+++ b/pkg/machinery/resources/block/block.go
@@ -17,7 +17,7 @@ import (
"github.com/siderolabs/talos/pkg/machinery/resources/v1alpha1"
)
-//go:generate deep-copy -type DeviceSpec -type DiscoveredVolumeSpec -type DiscoveryRefreshRequestSpec -type DiscoveryRefreshStatusSpec -type DiskSpec -type SystemDiskSpec -type UserDiskConfigStatusSpec -type VolumeConfigSpec -type VolumeLifecycleSpec -type VolumeStatusSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go .
+//go:generate deep-copy -type DeviceSpec -type DiscoveredVolumeSpec -type DiscoveryRefreshRequestSpec -type DiscoveryRefreshStatusSpec -type DiskSpec -type SymlinkSpec -type SystemDiskSpec -type UserDiskConfigStatusSpec -type VolumeConfigSpec -type VolumeLifecycleSpec -type VolumeStatusSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go .
//go:generate enumer -type=VolumeType,VolumePhase,FilesystemType,EncryptionKeyType,EncryptionProviderType -linecomment -text
diff --git a/pkg/machinery/resources/block/block_test.go b/pkg/machinery/resources/block/block_test.go
index ef4c40bda2..8a2e57863a 100644
--- a/pkg/machinery/resources/block/block_test.go
+++ b/pkg/machinery/resources/block/block_test.go
@@ -30,6 +30,7 @@ func TestRegisterResource(t *testing.T) {
&block.DiscoveryRefreshStatus{},
&block.DiscoveredVolume{},
&block.Disk{},
+ &block.Symlink{},
&block.SystemDisk{},
&block.UserDiskConfigStatus{},
&block.VolumeConfig{},
diff --git a/pkg/machinery/resources/block/deep_copy.generated.go b/pkg/machinery/resources/block/deep_copy.generated.go
index a273d89833..7a508b93ee 100644
--- a/pkg/machinery/resources/block/deep_copy.generated.go
+++ b/pkg/machinery/resources/block/deep_copy.generated.go
@@ -2,7 +2,7 @@
// 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 DeviceSpec -type DiscoveredVolumeSpec -type DiscoveryRefreshRequestSpec -type DiscoveryRefreshStatusSpec -type DiskSpec -type SystemDiskSpec -type UserDiskConfigStatusSpec -type VolumeConfigSpec -type VolumeLifecycleSpec -type VolumeStatusSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go ."; DO NOT EDIT.
+// Code generated by "deep-copy -type DeviceSpec -type DiscoveredVolumeSpec -type DiscoveryRefreshRequestSpec -type DiscoveryRefreshStatusSpec -type DiskSpec -type SymlinkSpec -type SystemDiskSpec -type UserDiskConfigStatusSpec -type VolumeConfigSpec -type VolumeLifecycleSpec -type VolumeStatusSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go ."; DO NOT EDIT.
package block
@@ -41,6 +41,20 @@ func (o DiskSpec) DeepCopy() DiskSpec {
cp.SecondaryDisks = make([]string, len(o.SecondaryDisks))
copy(cp.SecondaryDisks, o.SecondaryDisks)
}
+ if o.Symlinks != nil {
+ cp.Symlinks = make([]string, len(o.Symlinks))
+ copy(cp.Symlinks, o.Symlinks)
+ }
+ return cp
+}
+
+// DeepCopy generates a deep copy of SymlinkSpec.
+func (o SymlinkSpec) DeepCopy() SymlinkSpec {
+ var cp SymlinkSpec = o
+ if o.Paths != nil {
+ cp.Paths = make([]string, len(o.Paths))
+ copy(cp.Paths, o.Paths)
+ }
return cp
}
diff --git a/pkg/machinery/resources/block/disk.go b/pkg/machinery/resources/block/disk.go
index 851dfe03c1..093ca49a03 100644
--- a/pkg/machinery/resources/block/disk.go
+++ b/pkg/machinery/resources/block/disk.go
@@ -49,6 +49,8 @@ type DiskSpec struct {
// E.g. if the blockdevice secondary is vda5, the secondary disk will be set as vda.
// This allows to map secondaries between disks ignoring the partitions.
SecondaryDisks []string `yaml:"secondary_disks,omitempty" protobuf:"16"`
+
+ Symlinks []string `yaml:"symlinks,omitempty" protobuf:"18"`
}
// SetSize sets the size of the disk, including the pretty size.
diff --git a/pkg/machinery/resources/block/symlink.go b/pkg/machinery/resources/block/symlink.go
new file mode 100644
index 0000000000..03f6e7a1b6
--- /dev/null
+++ b/pkg/machinery/resources/block/symlink.go
@@ -0,0 +1,60 @@
+// 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 block
+
+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/talos/pkg/machinery/proto"
+)
+
+// SymlinkType is type of Symlink resource.
+const SymlinkType = resource.Type("BlockSymlinks.block.talos.dev")
+
+// Symlink resource holds a list of stable symlinks to the blockdevice.
+type Symlink = typed.Resource[SymlinkSpec, SymlinkExtension]
+
+// SymlinkID is the singleton resource ID.
+const SymlinkID resource.ID = "system-disk"
+
+// SymlinkSpec is the spec for Symlinks resource.
+//
+//gotagsrewrite:gen
+type SymlinkSpec struct {
+ Paths []string `yaml:"paths" protobuf:"1"`
+}
+
+// NewSymlink initializes a BlockSymlink resource.
+func NewSymlink(namespace resource.Namespace, id resource.ID) *Symlink {
+ return typed.NewResource[SymlinkSpec, SymlinkExtension](
+ resource.NewMetadata(namespace, SymlinkType, id, resource.VersionUndefined),
+ SymlinkSpec{},
+ )
+}
+
+// SymlinkExtension is auxiliary resource data for BlockSymlink.
+type SymlinkExtension struct{}
+
+// ResourceDefinition implements meta.ResourceDefinitionProvider interface.
+func (SymlinkExtension) ResourceDefinition() meta.ResourceDefinitionSpec {
+ return meta.ResourceDefinitionSpec{
+ Type: SymlinkType,
+ Aliases: []resource.Type{},
+ DefaultNamespace: NamespaceName,
+ PrintColumns: []meta.PrintColumn{},
+ }
+}
+
+func init() {
+ proto.RegisterDefaultTypes()
+
+ err := protobuf.RegisterDynamic[SymlinkSpec](SymlinkType, &Symlink{})
+ if err != nil {
+ panic(err)
+ }
+}
diff --git a/website/content/v1.10/reference/api.md b/website/content/v1.10/reference/api.md
index b20b4c9fd9..eb1349f3d8 100644
--- a/website/content/v1.10/reference/api.md
+++ b/website/content/v1.10/reference/api.md
@@ -40,6 +40,7 @@ description: Talos gRPC API reference.
- [MountSpec](#talos.resource.definitions.block.MountSpec)
- [PartitionSpec](#talos.resource.definitions.block.PartitionSpec)
- [ProvisioningSpec](#talos.resource.definitions.block.ProvisioningSpec)
+ - [SymlinkSpec](#talos.resource.definitions.block.SymlinkSpec)
- [SystemDiskSpec](#talos.resource.definitions.block.SystemDiskSpec)
- [UserDiskConfigStatusSpec](#talos.resource.definitions.block.UserDiskConfigStatusSpec)
- [VolumeConfigSpec](#talos.resource.definitions.block.VolumeConfigSpec)
@@ -936,6 +937,7 @@ DiskSpec is the spec for Disks status.
| pretty_size | [string](#string) | | |
| secondary_disks | [string](#string) | repeated | |
| uuid | [string](#string) | | |
+| symlinks | [string](#string) | repeated | |
@@ -1065,6 +1067,21 @@ ProvisioningSpec is the spec for volume provisioning.
+
+
+### SymlinkSpec
+SymlinkSpec is the spec for Symlinks resource.
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| paths | [string](#string) | repeated | |
+
+
+
+
+
+
### SystemDiskSpec