mirror of
https://github.com/siderolabs/talos.git
synced 2025-11-06 11:21:13 +01:00
feat: provide disk detection based on new blockdevices
Uses go-siderolabs/go-blockdevice/v2 for all the hard parts, provides new resource `Disk` which describes all disks in the system. Additional resource `SystemDisk` always point to the system disk (based on the location of `META` partition). The `Disks` API (and `talosctl disks`) provides a view now into the `talosctl get disks` to keep backwards compatibility. QEMU provisioner can now create extra disks of various types: IDE, AHCI, SCSI, NVME, this allows to test detection properly. The new resource will be the foundation for volume provisioning (to pick up the disk to provision the volume on). Example: ``` talosctl -n 172.20.0.5 get disks NODE NAMESPACE TYPE ID VERSION SIZE READ ONLY TRANSPORT ROTATIONAL WWID MODEL SERIAL 172.20.0.5 runtime Disk loop0 1 65568768 true 172.20.0.5 runtime Disk nvme0n1 1 10485760000 false nvme nvme.1b36-6465616462656566-51454d55204e564d65204374726c-00000001 QEMU NVMe Ctrl deadbeef 172.20.0.5 runtime Disk sda 1 10485760000 false virtio true QEMU HARDDISK 172.20.0.5 runtime Disk sdb 1 10485760000 false sata true t10.ATA QEMU HARDDISK QM00013 QEMU HARDDISK 172.20.0.5 runtime Disk sdc 1 10485760000 false sata true t10.ATA QEMU HARDDISK QM00001 QEMU HARDDISK 172.20.0.5 runtime Disk vda 1 12884901888 false virtio true ``` Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
This commit is contained in:
parent
8ee0872683
commit
f07b79f4a8
@ -36,3 +36,24 @@ message DiscoveredVolumeSpec {
|
|||||||
string parent = 16;
|
string parent = 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DiskSpec is the spec for Disks status.
|
||||||
|
message DiskSpec {
|
||||||
|
uint64 size = 1;
|
||||||
|
uint64 io_size = 2;
|
||||||
|
uint64 sector_size = 3;
|
||||||
|
bool readonly = 4;
|
||||||
|
string model = 5;
|
||||||
|
string serial = 6;
|
||||||
|
string modalias = 7;
|
||||||
|
string wwid = 8;
|
||||||
|
string bus_path = 9;
|
||||||
|
string sub_system = 10;
|
||||||
|
string transport = 11;
|
||||||
|
bool rotational = 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SystemDiskSpec is the spec for SystemDisks status.
|
||||||
|
message SystemDiskSpec {
|
||||||
|
string disk_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -137,6 +137,7 @@ var (
|
|||||||
clusterDisks []string
|
clusterDisks []string
|
||||||
extraDisks int
|
extraDisks int
|
||||||
extraDiskSize int
|
extraDiskSize int
|
||||||
|
extraDisksDrivers []string
|
||||||
targetArch string
|
targetArch string
|
||||||
clusterWait bool
|
clusterWait bool
|
||||||
clusterWaitTimeout time.Duration
|
clusterWaitTimeout time.Duration
|
||||||
@ -832,10 +833,17 @@ func create(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// append extra disks
|
// append extra disks
|
||||||
for range extraDisks {
|
for i := range extraDisks {
|
||||||
|
driver := "ide"
|
||||||
|
|
||||||
|
if i < len(extraDisksDrivers) {
|
||||||
|
driver = extraDisksDrivers[i]
|
||||||
|
}
|
||||||
|
|
||||||
disks = append(disks, &provision.Disk{
|
disks = append(disks, &provision.Disk{
|
||||||
Size: uint64(extraDiskSize) * 1024 * 1024,
|
Size: uint64(extraDiskSize) * 1024 * 1024,
|
||||||
SkipPreallocate: !clusterDiskPreallocate,
|
SkipPreallocate: !clusterDiskPreallocate,
|
||||||
|
Driver: driver,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1045,6 +1053,7 @@ func getDisks() ([]*provision.Disk, error) {
|
|||||||
{
|
{
|
||||||
Size: uint64(clusterDiskSize) * 1024 * 1024,
|
Size: uint64(clusterDiskSize) * 1024 * 1024,
|
||||||
SkipPreallocate: !clusterDiskPreallocate,
|
SkipPreallocate: !clusterDiskPreallocate,
|
||||||
|
Driver: "virtio",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1092,6 +1101,7 @@ func getDisks() ([]*provision.Disk, error) {
|
|||||||
Size: diskSize + 2*1024*1024,
|
Size: diskSize + 2*1024*1024,
|
||||||
Partitions: diskPartitions,
|
Partitions: diskPartitions,
|
||||||
SkipPreallocate: !clusterDiskPreallocate,
|
SkipPreallocate: !clusterDiskPreallocate,
|
||||||
|
Driver: "ide",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1143,6 +1153,7 @@ func init() {
|
|||||||
createCmd.Flags().BoolVar(&clusterDiskPreallocate, clusterDiskPreallocateFlag, true, "whether disk space should be preallocated")
|
createCmd.Flags().BoolVar(&clusterDiskPreallocate, clusterDiskPreallocateFlag, true, "whether disk space should be preallocated")
|
||||||
createCmd.Flags().StringSliceVar(&clusterDisks, clusterDisksFlag, []string{}, "list of disks to create for each VM in format: <mount_point1>:<size1>:<mount_point2>:<size2>")
|
createCmd.Flags().StringSliceVar(&clusterDisks, clusterDisksFlag, []string{}, "list of disks to create for each VM in format: <mount_point1>:<size1>:<mount_point2>:<size2>")
|
||||||
createCmd.Flags().IntVar(&extraDisks, "extra-disks", 0, "number of extra disks to create for each worker VM")
|
createCmd.Flags().IntVar(&extraDisks, "extra-disks", 0, "number of extra disks to create for each worker VM")
|
||||||
|
createCmd.Flags().StringSliceVar(&extraDisksDrivers, "extra-disks-drivers", nil, "driver for each extra disk (virtio, ide, ahci, scsi, nvme)")
|
||||||
createCmd.Flags().IntVar(&extraDiskSize, "extra-disks-size", 5*1024, "default limit on disk size in MB (each VM)")
|
createCmd.Flags().IntVar(&extraDiskSize, "extra-disks-size", 5*1024, "default limit on disk size in MB (each VM)")
|
||||||
createCmd.Flags().StringVar(&targetArch, "arch", stdruntime.GOARCH, "cluster architecture")
|
createCmd.Flags().StringVar(&targetArch, "arch", stdruntime.GOARCH, "cluster architecture")
|
||||||
createCmd.Flags().BoolVar(&clusterWait, "wait", true, "wait for the cluster to be ready before returning")
|
createCmd.Flags().BoolVar(&clusterWait, "wait", true, "wait for the cluster to be ready before returning")
|
||||||
|
|||||||
2
go.mod
2
go.mod
@ -128,7 +128,7 @@ require (
|
|||||||
github.com/siderolabs/gen v0.5.0
|
github.com/siderolabs/gen v0.5.0
|
||||||
github.com/siderolabs/go-api-signature v0.3.2
|
github.com/siderolabs/go-api-signature v0.3.2
|
||||||
github.com/siderolabs/go-blockdevice v0.4.7
|
github.com/siderolabs/go-blockdevice v0.4.7
|
||||||
github.com/siderolabs/go-blockdevice/v2 v2.0.0-20240604163945-81b69bf28eaa
|
github.com/siderolabs/go-blockdevice/v2 v2.0.0-20240607145058-1a51f162a09e
|
||||||
github.com/siderolabs/go-circular v0.2.0
|
github.com/siderolabs/go-circular v0.2.0
|
||||||
github.com/siderolabs/go-cmd v0.1.1
|
github.com/siderolabs/go-cmd v0.1.1
|
||||||
github.com/siderolabs/go-copy v0.1.0
|
github.com/siderolabs/go-copy v0.1.0
|
||||||
|
|||||||
4
go.sum
4
go.sum
@ -661,8 +661,8 @@ github.com/siderolabs/go-api-signature v0.3.2 h1:blqrZF1GM7TWgq7mY7CsR+yQ93u6az0
|
|||||||
github.com/siderolabs/go-api-signature v0.3.2/go.mod h1:punhUOaXa7LELYBRCUhfgUGH6ieVz68GrP98apCKXj8=
|
github.com/siderolabs/go-api-signature v0.3.2/go.mod h1:punhUOaXa7LELYBRCUhfgUGH6ieVz68GrP98apCKXj8=
|
||||||
github.com/siderolabs/go-blockdevice v0.4.7 h1:2bk4WpEEflGxjrNwp57ye24Pr+cYgAiAeNMWiQOuWbQ=
|
github.com/siderolabs/go-blockdevice v0.4.7 h1:2bk4WpEEflGxjrNwp57ye24Pr+cYgAiAeNMWiQOuWbQ=
|
||||||
github.com/siderolabs/go-blockdevice v0.4.7/go.mod h1:4PeOuk71pReJj1JQEXDE7kIIQJPVe8a+HZQa+qjxSEA=
|
github.com/siderolabs/go-blockdevice v0.4.7/go.mod h1:4PeOuk71pReJj1JQEXDE7kIIQJPVe8a+HZQa+qjxSEA=
|
||||||
github.com/siderolabs/go-blockdevice/v2 v2.0.0-20240604163945-81b69bf28eaa h1:OjQLrcis/GuqaqxnIw2dxp4ZzT/zk5p1GI3NxcMxkrA=
|
github.com/siderolabs/go-blockdevice/v2 v2.0.0-20240607145058-1a51f162a09e h1:PQhtHJj3zwaqehthq0fs2TyW8bW/mlOYoHfZIeSYQ3M=
|
||||||
github.com/siderolabs/go-blockdevice/v2 v2.0.0-20240604163945-81b69bf28eaa/go.mod h1:5GnL7VLNp5/vgiwYP74fi6KuTUfqGcRxQxtto2tzD+I=
|
github.com/siderolabs/go-blockdevice/v2 v2.0.0-20240607145058-1a51f162a09e/go.mod h1:5GnL7VLNp5/vgiwYP74fi6KuTUfqGcRxQxtto2tzD+I=
|
||||||
github.com/siderolabs/go-circular v0.2.0 h1:Xca8zrjF/YsujLbwDSojkKzJe7ngetnpuIJn8N78DJI=
|
github.com/siderolabs/go-circular v0.2.0 h1:Xca8zrjF/YsujLbwDSojkKzJe7ngetnpuIJn8N78DJI=
|
||||||
github.com/siderolabs/go-circular v0.2.0/go.mod h1:rrYCwHLYWmxqrmZP+LjYtwB2a55lxzQi0Ztu1VpWZSc=
|
github.com/siderolabs/go-circular v0.2.0/go.mod h1:rrYCwHLYWmxqrmZP+LjYtwB2a55lxzQi0Ztu1VpWZSc=
|
||||||
github.com/siderolabs/go-cmd v0.1.1 h1:nTouZUSxLeiiEe7hFexSVvaTsY/3O8k1s08BxPRrsps=
|
github.com/siderolabs/go-cmd v0.1.1 h1:nTouZUSxLeiiEe7hFexSVvaTsY/3O8k1s08BxPRrsps=
|
||||||
|
|||||||
167
internal/app/machined/pkg/controllers/block/disks.go
Normal file
167
internal/app/machined/pkg/controllers/block/disks.go
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
// 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"
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/cosi-project/runtime/pkg/controller"
|
||||||
|
"github.com/cosi-project/runtime/pkg/safe"
|
||||||
|
blkdev "github.com/siderolabs/go-blockdevice/v2/block"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/resources/block"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DisksController provides a detailed view of blockdevices of type 'disk'.
|
||||||
|
type DisksController struct{}
|
||||||
|
|
||||||
|
// Name implements controller.Controller interface.
|
||||||
|
func (ctrl *DisksController) Name() string {
|
||||||
|
return "block.DisksController"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inputs implements controller.Controller interface.
|
||||||
|
func (ctrl *DisksController) Inputs() []controller.Input {
|
||||||
|
return []controller.Input{
|
||||||
|
{
|
||||||
|
Namespace: block.NamespaceName,
|
||||||
|
Type: block.DeviceType,
|
||||||
|
Kind: controller.InputWeak,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Outputs implements controller.Controller interface.
|
||||||
|
func (ctrl *DisksController) Outputs() []controller.Output {
|
||||||
|
return []controller.Output{
|
||||||
|
{
|
||||||
|
Type: block.DiskType,
|
||||||
|
Kind: controller.OutputExclusive,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run implements controller.Controller interface.
|
||||||
|
//
|
||||||
|
//nolint:gocyclo
|
||||||
|
func (ctrl *DisksController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error {
|
||||||
|
// lastObservedGenerations holds the last observed generation of each device.
|
||||||
|
//
|
||||||
|
// when the generation of a device changes, the device might have changed and might need to be re-probed.
|
||||||
|
lastObservedGenerations := map[string]int{}
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-r.EventCh():
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
blockdevices, err := safe.ReaderListAll[*block.Device](ctx, r)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to list block devices: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
touchedDisks := map[string]struct{}{}
|
||||||
|
|
||||||
|
for iter := blockdevices.Iterator(); iter.Next(); {
|
||||||
|
device := iter.Value()
|
||||||
|
|
||||||
|
if device.TypedSpec().Type != "disk" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
touchedDisks[device.Metadata().ID()] = struct{}{}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
lastObservedGenerations[device.Metadata().ID()] = device.TypedSpec().Generation
|
||||||
|
|
||||||
|
if err = ctrl.analyzeBlockDevice(ctx, r, logger.With(zap.String("device", device.Metadata().ID())), device, touchedDisks); err != nil {
|
||||||
|
return fmt.Errorf("failed to analyze block device: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
disks, err := safe.ReaderListAll[*block.Disk](ctx, r)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to list disks: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for iter := disks.Iterator(); iter.Next(); {
|
||||||
|
disk := iter.Value()
|
||||||
|
|
||||||
|
if _, ok := touchedDisks[disk.Metadata().ID()]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = r.Destroy(ctx, disk.Metadata()); err != nil {
|
||||||
|
return fmt.Errorf("failed to remove disk: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(lastObservedGenerations, disk.Metadata().ID())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctrl *DisksController) analyzeBlockDevice(ctx context.Context, r controller.Runtime, logger *zap.Logger, device *block.Device, touchedDisks map[string]struct{}) error {
|
||||||
|
bd, err := blkdev.NewFromPath(filepath.Join("/dev", device.Metadata().ID()))
|
||||||
|
if err != nil {
|
||||||
|
logger.Debug("failed to open blockdevice", zap.Error(err))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
size, err := bd.GetSize()
|
||||||
|
if err != nil || size == 0 {
|
||||||
|
return nil //nolint:nilerr
|
||||||
|
}
|
||||||
|
|
||||||
|
if privateDM, _ := bd.IsPrivateDeviceMapper(); privateDM { //nolint:errcheck
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ioSize, err := bd.GetIOSize()
|
||||||
|
if err != nil {
|
||||||
|
logger.Debug("failed to get io size", zap.Error(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
sectorSize := bd.GetSectorSize()
|
||||||
|
|
||||||
|
readOnly, err := bd.IsReadOnly()
|
||||||
|
if err != nil {
|
||||||
|
logger.Debug("failed to get read only", zap.Error(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
props, err := bd.GetProperties()
|
||||||
|
if err != nil {
|
||||||
|
logger.Debug("failed to get properties", zap.Error(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
touchedDisks[device.Metadata().ID()] = struct{}{}
|
||||||
|
|
||||||
|
return safe.WriterModify(ctx, r, block.NewDisk(block.NamespaceName, device.Metadata().ID()), func(d *block.Disk) error {
|
||||||
|
d.TypedSpec().Size = size
|
||||||
|
d.TypedSpec().IOSize = ioSize
|
||||||
|
d.TypedSpec().SectorSize = sectorSize
|
||||||
|
d.TypedSpec().Readonly = readOnly
|
||||||
|
|
||||||
|
d.TypedSpec().Model = props.Model
|
||||||
|
d.TypedSpec().Serial = props.Serial
|
||||||
|
d.TypedSpec().Modalias = props.Modalias
|
||||||
|
d.TypedSpec().WWID = props.WWID
|
||||||
|
d.TypedSpec().BusPath = props.BusPath
|
||||||
|
d.TypedSpec().SubSystem = props.SubSystem
|
||||||
|
d.TypedSpec().Transport = props.Transport
|
||||||
|
d.TypedSpec().Rotational = props.Rotational
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
91
internal/app/machined/pkg/controllers/block/system_disk.go
Normal file
91
internal/app/machined/pkg/controllers/block/system_disk.go
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
// 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"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/cosi-project/runtime/pkg/controller"
|
||||||
|
"github.com/cosi-project/runtime/pkg/safe"
|
||||||
|
"github.com/cosi-project/runtime/pkg/state"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/constants"
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/resources/block"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SystemDiskController provides a detailed view of blockdevices of type 'disk'.
|
||||||
|
type SystemDiskController struct{}
|
||||||
|
|
||||||
|
// Name implements controller.Controller interface.
|
||||||
|
func (ctrl *SystemDiskController) Name() string {
|
||||||
|
return "block.SystemDiskController"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inputs implements controller.Controller interface.
|
||||||
|
func (ctrl *SystemDiskController) Inputs() []controller.Input {
|
||||||
|
return []controller.Input{
|
||||||
|
{
|
||||||
|
Namespace: block.NamespaceName,
|
||||||
|
Type: block.DiscoveredVolumeType,
|
||||||
|
Kind: controller.InputWeak,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Outputs implements controller.Controller interface.
|
||||||
|
func (ctrl *SystemDiskController) Outputs() []controller.Output {
|
||||||
|
return []controller.Output{
|
||||||
|
{
|
||||||
|
Type: block.SystemDiskType,
|
||||||
|
Kind: controller.OutputExclusive,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run implements controller.Controller interface.
|
||||||
|
//
|
||||||
|
//nolint:gocyclo
|
||||||
|
func (ctrl *SystemDiskController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-r.EventCh():
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
discoveredVolumes, err := safe.ReaderListAll[*block.DiscoveredVolume](ctx, r)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to list discovered volumes: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var systemDiskID string
|
||||||
|
|
||||||
|
for iter := discoveredVolumes.Iterator(); iter.Next(); {
|
||||||
|
volume := iter.Value()
|
||||||
|
|
||||||
|
if volume.TypedSpec().PartitionLabel == constants.MetaPartitionLabel {
|
||||||
|
systemDiskID = volume.TypedSpec().Parent
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if systemDiskID != "" {
|
||||||
|
if err = safe.WriterModify(ctx, r, block.NewSystemDisk(block.NamespaceName, block.SystemDiskID), func(d *block.SystemDisk) error {
|
||||||
|
d.TypedSpec().DiskID = systemDiskID
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return fmt.Errorf("failed to write system disk: %w", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err = r.Destroy(ctx, block.NewSystemDisk(block.NamespaceName, block.SystemDiskID).Metadata()); err != nil && !state.IsNotFoundError(err) {
|
||||||
|
return fmt.Errorf("failed to destroy system disk: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -92,6 +92,8 @@ func (ctrl *Controller) Run(ctx context.Context, drainer *runtime.Drainer) error
|
|||||||
V1Alpha1Mode: ctrl.v1alpha1Runtime.State().Platform().Mode(),
|
V1Alpha1Mode: ctrl.v1alpha1Runtime.State().Platform().Mode(),
|
||||||
},
|
},
|
||||||
&block.DiscoveryController{},
|
&block.DiscoveryController{},
|
||||||
|
&block.DisksController{},
|
||||||
|
&block.SystemDiskController{},
|
||||||
&cluster.AffiliateMergeController{},
|
&cluster.AffiliateMergeController{},
|
||||||
cluster.NewConfigController(),
|
cluster.NewConfigController(),
|
||||||
&cluster.DiscoveryServiceController{},
|
&cluster.DiscoveryServiceController{},
|
||||||
|
|||||||
@ -97,6 +97,8 @@ func NewState() (*State, error) {
|
|||||||
for _, r := range []meta.ResourceWithRD{
|
for _, r := range []meta.ResourceWithRD{
|
||||||
&block.Device{},
|
&block.Device{},
|
||||||
&block.DiscoveredVolume{},
|
&block.DiscoveredVolume{},
|
||||||
|
&block.Disk{},
|
||||||
|
&block.SystemDisk{},
|
||||||
&cluster.Affiliate{},
|
&cluster.Affiliate{},
|
||||||
&cluster.Config{},
|
&cluster.Config{},
|
||||||
&cluster.Identity{},
|
&cluster.Identity{},
|
||||||
|
|||||||
@ -7,17 +7,20 @@ package internal
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/siderolabs/gen/xslices"
|
"github.com/cosi-project/runtime/pkg/safe"
|
||||||
bddisk "github.com/siderolabs/go-blockdevice/blockdevice/util/disk"
|
"github.com/cosi-project/runtime/pkg/state"
|
||||||
"google.golang.org/protobuf/types/known/emptypb"
|
"google.golang.org/protobuf/types/known/emptypb"
|
||||||
|
|
||||||
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime"
|
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime"
|
||||||
"github.com/siderolabs/talos/pkg/machinery/api/storage"
|
"github.com/siderolabs/talos/pkg/machinery/api/storage"
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/resources/block"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Server implements storage.StorageService.
|
// Server implements storage.StorageService.
|
||||||
// TODO: this is not a full blown service yet, it's used as the common base in the machine and the maintenance services.
|
//
|
||||||
|
// It is only kept here for compatibility purposes, proper API is to query `block.Disk` resources.
|
||||||
type Server struct {
|
type Server struct {
|
||||||
storage.UnimplementedStorageServiceServer
|
storage.UnimplementedStorageServiceServer
|
||||||
Controller runtime.Controller
|
Controller runtime.Controller
|
||||||
@ -25,32 +28,48 @@ type Server struct {
|
|||||||
|
|
||||||
// Disks implements storage.StorageService.
|
// Disks implements storage.StorageService.
|
||||||
func (s *Server) Disks(ctx context.Context, in *emptypb.Empty) (reply *storage.DisksResponse, err error) {
|
func (s *Server) Disks(ctx context.Context, in *emptypb.Empty) (reply *storage.DisksResponse, err error) {
|
||||||
disks, err := bddisk.List()
|
st := s.Controller.Runtime().State().V1Alpha2().Resources()
|
||||||
|
|
||||||
|
systemDisk, err := safe.StateGetByID[*block.SystemDisk](ctx, st, block.SystemDiskID)
|
||||||
|
if err != nil && !state.IsNotFoundError(err) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
disks, err := safe.StateListAll[*block.Disk](ctx, st)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
systemDisk := s.Controller.Runtime().State().Machine().Disk()
|
diskConv := func(d *block.Disk) (*storage.Disk, error) {
|
||||||
|
var diskType storage.Disk_DiskType
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case d.TypedSpec().Transport == "nvme":
|
||||||
|
diskType = storage.Disk_NVME
|
||||||
|
case d.TypedSpec().Transport == "mmc":
|
||||||
|
diskType = storage.Disk_SD
|
||||||
|
case d.TypedSpec().Rotational:
|
||||||
|
diskType = storage.Disk_HDD
|
||||||
|
case d.TypedSpec().Transport != "":
|
||||||
|
diskType = storage.Disk_SSD
|
||||||
|
}
|
||||||
|
|
||||||
diskConv := func(d *bddisk.Disk) *storage.Disk {
|
|
||||||
return &storage.Disk{
|
return &storage.Disk{
|
||||||
DeviceName: d.DeviceName,
|
DeviceName: filepath.Join("/dev", d.Metadata().ID()),
|
||||||
Model: d.Model,
|
Model: d.TypedSpec().Model,
|
||||||
Size: d.Size,
|
Size: d.TypedSpec().Size,
|
||||||
Name: d.Name,
|
Serial: d.TypedSpec().Serial,
|
||||||
Serial: d.Serial,
|
Modalias: d.TypedSpec().Modalias,
|
||||||
Modalias: d.Modalias,
|
Wwid: d.TypedSpec().WWID,
|
||||||
Uuid: d.UUID,
|
Type: diskType,
|
||||||
Wwid: d.WWID,
|
BusPath: d.TypedSpec().BusPath,
|
||||||
Type: storage.Disk_DiskType(d.Type),
|
SystemDisk: systemDisk != nil && d.Metadata().ID() == systemDisk.TypedSpec().DiskID,
|
||||||
BusPath: d.BusPath,
|
Subsystem: d.TypedSpec().SubSystem,
|
||||||
SystemDisk: systemDisk != nil && d.DeviceName == systemDisk.Device().Name(),
|
Readonly: d.TypedSpec().Readonly,
|
||||||
Subsystem: d.SubSystem,
|
}, nil
|
||||||
Readonly: d.ReadOnly,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
diskList := xslices.Map(disks, diskConv)
|
diskList, _ := safe.Map(disks, diskConv) //nolint:errcheck
|
||||||
|
|
||||||
reply = &storage.DisksResponse{
|
reply = &storage.DisksResponse{
|
||||||
Messages: []*storage.Disks{
|
Messages: []*storage.Disks{
|
||||||
|
|||||||
@ -32,6 +32,10 @@ func (suite *VolumesSuite) SuiteName() string {
|
|||||||
|
|
||||||
// SetupTest ...
|
// SetupTest ...
|
||||||
func (suite *VolumesSuite) SetupTest() {
|
func (suite *VolumesSuite) SetupTest() {
|
||||||
|
if !suite.Capabilities().SupportsVolumes {
|
||||||
|
suite.T().Skip("cluster doesn't support volumes")
|
||||||
|
}
|
||||||
|
|
||||||
suite.ctx, suite.ctxCancel = context.WithTimeout(context.Background(), time.Minute)
|
suite.ctx, suite.ctxCancel = context.WithTimeout(context.Background(), time.Minute)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,10 +48,6 @@ func (suite *VolumesSuite) TearDownTest() {
|
|||||||
|
|
||||||
// TestDiscoveredVolumes verifies that standard Talos partitions are discovered.
|
// TestDiscoveredVolumes verifies that standard Talos partitions are discovered.
|
||||||
func (suite *VolumesSuite) TestDiscoveredVolumes() {
|
func (suite *VolumesSuite) TestDiscoveredVolumes() {
|
||||||
if !suite.Capabilities().SupportsVolumes {
|
|
||||||
suite.T().Skip("cluster doesn't support volumes")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, node := range suite.DiscoverNodeInternalIPs(suite.ctx) {
|
for _, node := range suite.DiscoverNodeInternalIPs(suite.ctx) {
|
||||||
suite.Run(node, func() {
|
suite.Run(node, func() {
|
||||||
suite.testDiscoveredVolumes(node)
|
suite.testDiscoveredVolumes(node)
|
||||||
@ -114,6 +114,60 @@ func (suite *VolumesSuite) testDiscoveredVolumes(node string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestSystemDisk verifies that Talos system disk is discovered.
|
||||||
|
func (suite *VolumesSuite) TestSystemDisk() {
|
||||||
|
for _, node := range suite.DiscoverNodeInternalIPs(suite.ctx) {
|
||||||
|
suite.Run(node, func() {
|
||||||
|
ctx := client.WithNode(suite.ctx, node)
|
||||||
|
|
||||||
|
systemDisk, err := safe.StateGetByID[*block.SystemDisk](ctx, suite.Client.COSI, block.SystemDiskID)
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
suite.Assert().NotEmpty(systemDisk.TypedSpec().DiskID)
|
||||||
|
|
||||||
|
suite.T().Logf("system disk: %s", systemDisk.TypedSpec().DiskID)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestDisks verifies that Talos discovers disks.
|
||||||
|
func (suite *VolumesSuite) TestDisks() {
|
||||||
|
for _, node := range suite.DiscoverNodeInternalIPs(suite.ctx) {
|
||||||
|
suite.Run(node, func() {
|
||||||
|
ctx := client.WithNode(suite.ctx, node)
|
||||||
|
|
||||||
|
disks, err := safe.StateListAll[*block.Disk](ctx, suite.Client.COSI)
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
// there should be at least two disks - loop0 for Talos squashfs and a system disk
|
||||||
|
suite.Assert().Greater(disks.Len(), 1)
|
||||||
|
|
||||||
|
var diskNames []string
|
||||||
|
|
||||||
|
for iter := disks.Iterator(); iter.Next(); {
|
||||||
|
disk := iter.Value()
|
||||||
|
|
||||||
|
if disk.TypedSpec().Readonly {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
suite.Assert().NotEmpty(disk.TypedSpec().Size, "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())
|
||||||
|
|
||||||
|
if suite.Cluster != nil {
|
||||||
|
// running on our own provider, transport should be always detected
|
||||||
|
suite.Assert().NotEmpty(disk.TypedSpec().Transport, "disk: %s", disk.Metadata().ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
diskNames = append(diskNames, disk.Metadata().ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
suite.T().Logf("disks: %v", diskNames)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
allSuites = append(allSuites, new(VolumesSuite))
|
allSuites = append(allSuites, new(VolumesSuite))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,10 @@ func (suite *DisksSuite) SuiteName() string {
|
|||||||
|
|
||||||
// TestSuccess runs comand with success.
|
// TestSuccess runs comand with success.
|
||||||
func (suite *DisksSuite) TestSuccess() {
|
func (suite *DisksSuite) TestSuccess() {
|
||||||
|
if suite.Cluster != nil && suite.Cluster.Provisioner() == "docker" {
|
||||||
|
suite.T().Skip("docker provisioner doesn't support disks command")
|
||||||
|
}
|
||||||
|
|
||||||
suite.RunCLI([]string{"disks", "--nodes", suite.RandomDiscoveredNodeInternalIP()})
|
suite.RunCLI([]string{"disks", "--nodes", suite.RandomDiscoveredNodeInternalIP()})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -293,6 +293,190 @@ func (x *DiscoveredVolumeSpec) GetParent() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DiskSpec is the spec for Disks status.
|
||||||
|
type DiskSpec struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
Size uint64 `protobuf:"varint,1,opt,name=size,proto3" json:"size,omitempty"`
|
||||||
|
IoSize uint64 `protobuf:"varint,2,opt,name=io_size,json=ioSize,proto3" json:"io_size,omitempty"`
|
||||||
|
SectorSize uint64 `protobuf:"varint,3,opt,name=sector_size,json=sectorSize,proto3" json:"sector_size,omitempty"`
|
||||||
|
Readonly bool `protobuf:"varint,4,opt,name=readonly,proto3" json:"readonly,omitempty"`
|
||||||
|
Model string `protobuf:"bytes,5,opt,name=model,proto3" json:"model,omitempty"`
|
||||||
|
Serial string `protobuf:"bytes,6,opt,name=serial,proto3" json:"serial,omitempty"`
|
||||||
|
Modalias string `protobuf:"bytes,7,opt,name=modalias,proto3" json:"modalias,omitempty"`
|
||||||
|
Wwid string `protobuf:"bytes,8,opt,name=wwid,proto3" json:"wwid,omitempty"`
|
||||||
|
BusPath string `protobuf:"bytes,9,opt,name=bus_path,json=busPath,proto3" json:"bus_path,omitempty"`
|
||||||
|
SubSystem string `protobuf:"bytes,10,opt,name=sub_system,json=subSystem,proto3" json:"sub_system,omitempty"`
|
||||||
|
Transport string `protobuf:"bytes,11,opt,name=transport,proto3" json:"transport,omitempty"`
|
||||||
|
Rotational bool `protobuf:"varint,12,opt,name=rotational,proto3" json:"rotational,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DiskSpec) Reset() {
|
||||||
|
*x = DiskSpec{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_resource_definitions_block_block_proto_msgTypes[2]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DiskSpec) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DiskSpec) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *DiskSpec) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_resource_definitions_block_block_proto_msgTypes[2]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use DiskSpec.ProtoReflect.Descriptor instead.
|
||||||
|
func (*DiskSpec) Descriptor() ([]byte, []int) {
|
||||||
|
return file_resource_definitions_block_block_proto_rawDescGZIP(), []int{2}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DiskSpec) GetSize() uint64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Size
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DiskSpec) GetIoSize() uint64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.IoSize
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DiskSpec) GetSectorSize() uint64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.SectorSize
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DiskSpec) GetReadonly() bool {
|
||||||
|
if x != nil {
|
||||||
|
return x.Readonly
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DiskSpec) GetModel() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Model
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DiskSpec) GetSerial() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Serial
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DiskSpec) GetModalias() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Modalias
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DiskSpec) GetWwid() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Wwid
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DiskSpec) GetBusPath() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.BusPath
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DiskSpec) GetSubSystem() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.SubSystem
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DiskSpec) GetTransport() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Transport
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DiskSpec) GetRotational() bool {
|
||||||
|
if x != nil {
|
||||||
|
return x.Rotational
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SystemDiskSpec is the spec for SystemDisks status.
|
||||||
|
type SystemDiskSpec struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
DiskId string `protobuf:"bytes,1,opt,name=disk_id,json=diskId,proto3" json:"disk_id,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SystemDiskSpec) Reset() {
|
||||||
|
*x = SystemDiskSpec{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_resource_definitions_block_block_proto_msgTypes[3]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SystemDiskSpec) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*SystemDiskSpec) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *SystemDiskSpec) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_resource_definitions_block_block_proto_msgTypes[3]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use SystemDiskSpec.ProtoReflect.Descriptor instead.
|
||||||
|
func (*SystemDiskSpec) Descriptor() ([]byte, []int) {
|
||||||
|
return file_resource_definitions_block_block_proto_rawDescGZIP(), []int{3}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SystemDiskSpec) GetDiskId() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.DiskId
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
var File_resource_definitions_block_block_proto protoreflect.FileDescriptor
|
var File_resource_definitions_block_block_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
var file_resource_definitions_block_block_proto_rawDesc = []byte{
|
var file_resource_definitions_block_block_proto_rawDesc = []byte{
|
||||||
@ -348,12 +532,36 @@ var file_resource_definitions_block_block_proto_rawDesc = []byte{
|
|||||||
0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68,
|
0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68,
|
||||||
0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x50, 0x61,
|
0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x50, 0x61,
|
||||||
0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x10, 0x20, 0x01,
|
0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x10, 0x20, 0x01,
|
||||||
0x28, 0x09, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x42, 0x4a, 0x5a, 0x48, 0x67, 0x69,
|
0x28, 0x09, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x22, 0xca, 0x02, 0x0a, 0x08, 0x44,
|
||||||
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69, 0x64, 0x65, 0x72, 0x6f, 0x6c,
|
0x69, 0x73, 0x6b, 0x53, 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18,
|
||||||
0x61, 0x62, 0x73, 0x2f, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6d, 0x61,
|
0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69,
|
||||||
0x63, 0x68, 0x69, 0x6e, 0x65, 0x72, 0x79, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f,
|
0x6f, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x69, 0x6f,
|
||||||
0x75, 0x72, 0x63, 0x65, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73,
|
0x53, 0x69, 0x7a, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x73,
|
||||||
0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x73, 0x65, 0x63, 0x74, 0x6f,
|
||||||
|
0x72, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c,
|
||||||
|
0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c,
|
||||||
|
0x79, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
|
||||||
|
0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x69, 0x61,
|
||||||
|
0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x12,
|
||||||
|
0x1a, 0x0a, 0x08, 0x6d, 0x6f, 0x64, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28,
|
||||||
|
0x09, 0x52, 0x08, 0x6d, 0x6f, 0x64, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x77,
|
||||||
|
0x77, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x77, 0x77, 0x69, 0x64, 0x12,
|
||||||
|
0x19, 0x0a, 0x08, 0x62, 0x75, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28,
|
||||||
|
0x09, 0x52, 0x07, 0x62, 0x75, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x75,
|
||||||
|
0x62, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
|
||||||
|
0x73, 0x75, 0x62, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x72, 0x61,
|
||||||
|
0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x72,
|
||||||
|
0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x6f, 0x74, 0x61, 0x74,
|
||||||
|
0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x72, 0x6f, 0x74,
|
||||||
|
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x22, 0x29, 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, 0x42, 0x4a, 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 (
|
var (
|
||||||
@ -368,10 +576,12 @@ func file_resource_definitions_block_block_proto_rawDescGZIP() []byte {
|
|||||||
return file_resource_definitions_block_block_proto_rawDescData
|
return file_resource_definitions_block_block_proto_rawDescData
|
||||||
}
|
}
|
||||||
|
|
||||||
var file_resource_definitions_block_block_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
var file_resource_definitions_block_block_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||||
var file_resource_definitions_block_block_proto_goTypes = []interface{}{
|
var file_resource_definitions_block_block_proto_goTypes = []interface{}{
|
||||||
(*DeviceSpec)(nil), // 0: talos.resource.definitions.block.DeviceSpec
|
(*DeviceSpec)(nil), // 0: talos.resource.definitions.block.DeviceSpec
|
||||||
(*DiscoveredVolumeSpec)(nil), // 1: talos.resource.definitions.block.DiscoveredVolumeSpec
|
(*DiscoveredVolumeSpec)(nil), // 1: talos.resource.definitions.block.DiscoveredVolumeSpec
|
||||||
|
(*DiskSpec)(nil), // 2: talos.resource.definitions.block.DiskSpec
|
||||||
|
(*SystemDiskSpec)(nil), // 3: talos.resource.definitions.block.SystemDiskSpec
|
||||||
}
|
}
|
||||||
var file_resource_definitions_block_block_proto_depIdxs = []int32{
|
var file_resource_definitions_block_block_proto_depIdxs = []int32{
|
||||||
0, // [0:0] is the sub-list for method output_type
|
0, // [0:0] is the sub-list for method output_type
|
||||||
@ -411,6 +621,30 @@ func file_resource_definitions_block_block_proto_init() {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
file_resource_definitions_block_block_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*DiskSpec); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_resource_definitions_block_block_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*SystemDiskSpec); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
type x struct{}
|
type x struct{}
|
||||||
out := protoimpl.TypeBuilder{
|
out := protoimpl.TypeBuilder{
|
||||||
@ -418,7 +652,7 @@ func file_resource_definitions_block_block_proto_init() {
|
|||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: file_resource_definitions_block_block_proto_rawDesc,
|
RawDescriptor: file_resource_definitions_block_block_proto_rawDesc,
|
||||||
NumEnums: 0,
|
NumEnums: 0,
|
||||||
NumMessages: 2,
|
NumMessages: 4,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 0,
|
NumServices: 0,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -233,6 +233,163 @@ func (m *DiscoveredVolumeSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error)
|
|||||||
return len(dAtA) - i, nil
|
return len(dAtA) - i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *DiskSpec) 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 *DiskSpec) MarshalToVT(dAtA []byte) (int, error) {
|
||||||
|
size := m.SizeVT()
|
||||||
|
return m.MarshalToSizedBufferVT(dAtA[:size])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *DiskSpec) 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 m.Rotational {
|
||||||
|
i--
|
||||||
|
if m.Rotational {
|
||||||
|
dAtA[i] = 1
|
||||||
|
} else {
|
||||||
|
dAtA[i] = 0
|
||||||
|
}
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x60
|
||||||
|
}
|
||||||
|
if len(m.Transport) > 0 {
|
||||||
|
i -= len(m.Transport)
|
||||||
|
copy(dAtA[i:], m.Transport)
|
||||||
|
i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Transport)))
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x5a
|
||||||
|
}
|
||||||
|
if len(m.SubSystem) > 0 {
|
||||||
|
i -= len(m.SubSystem)
|
||||||
|
copy(dAtA[i:], m.SubSystem)
|
||||||
|
i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.SubSystem)))
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x52
|
||||||
|
}
|
||||||
|
if len(m.BusPath) > 0 {
|
||||||
|
i -= len(m.BusPath)
|
||||||
|
copy(dAtA[i:], m.BusPath)
|
||||||
|
i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.BusPath)))
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x4a
|
||||||
|
}
|
||||||
|
if len(m.Wwid) > 0 {
|
||||||
|
i -= len(m.Wwid)
|
||||||
|
copy(dAtA[i:], m.Wwid)
|
||||||
|
i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Wwid)))
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x42
|
||||||
|
}
|
||||||
|
if len(m.Modalias) > 0 {
|
||||||
|
i -= len(m.Modalias)
|
||||||
|
copy(dAtA[i:], m.Modalias)
|
||||||
|
i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Modalias)))
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x3a
|
||||||
|
}
|
||||||
|
if len(m.Serial) > 0 {
|
||||||
|
i -= len(m.Serial)
|
||||||
|
copy(dAtA[i:], m.Serial)
|
||||||
|
i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Serial)))
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x32
|
||||||
|
}
|
||||||
|
if len(m.Model) > 0 {
|
||||||
|
i -= len(m.Model)
|
||||||
|
copy(dAtA[i:], m.Model)
|
||||||
|
i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Model)))
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x2a
|
||||||
|
}
|
||||||
|
if m.Readonly {
|
||||||
|
i--
|
||||||
|
if m.Readonly {
|
||||||
|
dAtA[i] = 1
|
||||||
|
} else {
|
||||||
|
dAtA[i] = 0
|
||||||
|
}
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x20
|
||||||
|
}
|
||||||
|
if m.SectorSize != 0 {
|
||||||
|
i = protohelpers.EncodeVarint(dAtA, i, uint64(m.SectorSize))
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x18
|
||||||
|
}
|
||||||
|
if m.IoSize != 0 {
|
||||||
|
i = protohelpers.EncodeVarint(dAtA, i, uint64(m.IoSize))
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x10
|
||||||
|
}
|
||||||
|
if m.Size != 0 {
|
||||||
|
i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Size))
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x8
|
||||||
|
}
|
||||||
|
return len(dAtA) - i, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *SystemDiskSpec) 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 *SystemDiskSpec) MarshalToVT(dAtA []byte) (int, error) {
|
||||||
|
size := m.SizeVT()
|
||||||
|
return m.MarshalToSizedBufferVT(dAtA[:size])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *SystemDiskSpec) 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.DiskId) > 0 {
|
||||||
|
i -= len(m.DiskId)
|
||||||
|
copy(dAtA[i:], m.DiskId)
|
||||||
|
i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.DiskId)))
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0xa
|
||||||
|
}
|
||||||
|
return len(dAtA) - i, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (m *DeviceSpec) SizeVT() (n int) {
|
func (m *DeviceSpec) SizeVT() (n int) {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return 0
|
return 0
|
||||||
@ -338,6 +495,73 @@ func (m *DiscoveredVolumeSpec) SizeVT() (n int) {
|
|||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *DiskSpec) SizeVT() (n int) {
|
||||||
|
if m == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
var l int
|
||||||
|
_ = l
|
||||||
|
if m.Size != 0 {
|
||||||
|
n += 1 + protohelpers.SizeOfVarint(uint64(m.Size))
|
||||||
|
}
|
||||||
|
if m.IoSize != 0 {
|
||||||
|
n += 1 + protohelpers.SizeOfVarint(uint64(m.IoSize))
|
||||||
|
}
|
||||||
|
if m.SectorSize != 0 {
|
||||||
|
n += 1 + protohelpers.SizeOfVarint(uint64(m.SectorSize))
|
||||||
|
}
|
||||||
|
if m.Readonly {
|
||||||
|
n += 2
|
||||||
|
}
|
||||||
|
l = len(m.Model)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||||
|
}
|
||||||
|
l = len(m.Serial)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||||
|
}
|
||||||
|
l = len(m.Modalias)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||||
|
}
|
||||||
|
l = len(m.Wwid)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||||
|
}
|
||||||
|
l = len(m.BusPath)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||||
|
}
|
||||||
|
l = len(m.SubSystem)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||||
|
}
|
||||||
|
l = len(m.Transport)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||||
|
}
|
||||||
|
if m.Rotational {
|
||||||
|
n += 2
|
||||||
|
}
|
||||||
|
n += len(m.unknownFields)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *SystemDiskSpec) SizeVT() (n int) {
|
||||||
|
if m == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
var l int
|
||||||
|
_ = l
|
||||||
|
l = len(m.DiskId)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||||
|
}
|
||||||
|
n += len(m.unknownFields)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
func (m *DeviceSpec) UnmarshalVT(dAtA []byte) error {
|
func (m *DeviceSpec) UnmarshalVT(dAtA []byte) error {
|
||||||
l := len(dAtA)
|
l := len(dAtA)
|
||||||
iNdEx := 0
|
iNdEx := 0
|
||||||
@ -1065,3 +1289,458 @@ func (m *DiscoveredVolumeSpec) UnmarshalVT(dAtA []byte) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
func (m *DiskSpec) 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: DiskSpec: wiretype end group for non-group")
|
||||||
|
}
|
||||||
|
if fieldNum <= 0 {
|
||||||
|
return fmt.Errorf("proto: DiskSpec: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||||
|
}
|
||||||
|
switch fieldNum {
|
||||||
|
case 1:
|
||||||
|
if wireType != 0 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Size", wireType)
|
||||||
|
}
|
||||||
|
m.Size = 0
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return protohelpers.ErrIntOverflow
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
m.Size |= uint64(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
if wireType != 0 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field IoSize", wireType)
|
||||||
|
}
|
||||||
|
m.IoSize = 0
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return protohelpers.ErrIntOverflow
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
m.IoSize |= uint64(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
if wireType != 0 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field SectorSize", wireType)
|
||||||
|
}
|
||||||
|
m.SectorSize = 0
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return protohelpers.ErrIntOverflow
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
m.SectorSize |= uint64(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
if wireType != 0 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Readonly", wireType)
|
||||||
|
}
|
||||||
|
var v int
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return protohelpers.ErrIntOverflow
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
v |= int(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.Readonly = bool(v != 0)
|
||||||
|
case 5:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Model", 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.Model = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
|
case 6:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Serial", 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.Serial = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
|
case 7:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Modalias", 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.Modalias = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
|
case 8:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Wwid", 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.Wwid = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
|
case 9:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field BusPath", 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.BusPath = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
|
case 10:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field SubSystem", 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.SubSystem = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
|
case 11:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Transport", 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.Transport = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
|
case 12:
|
||||||
|
if wireType != 0 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Rotational", wireType)
|
||||||
|
}
|
||||||
|
var v int
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return protohelpers.ErrIntOverflow
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
v |= int(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.Rotational = bool(v != 0)
|
||||||
|
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
|
||||||
|
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: SystemDiskSpec: wiretype end group for non-group")
|
||||||
|
}
|
||||||
|
if fieldNum <= 0 {
|
||||||
|
return fmt.Errorf("proto: SystemDiskSpec: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||||
|
}
|
||||||
|
switch fieldNum {
|
||||||
|
case 1:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field DiskId", 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.DiskId = 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
|
||||||
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import (
|
|||||||
"github.com/siderolabs/talos/pkg/machinery/resources/v1alpha1"
|
"github.com/siderolabs/talos/pkg/machinery/resources/v1alpha1"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate deep-copy -type DeviceSpec -type DiscoveredVolumeSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go .
|
//go:generate deep-copy -type DeviceSpec -type DiscoveredVolumeSpec -type DiskSpec -type SystemDiskSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go .
|
||||||
|
|
||||||
// NamespaceName contains configuration resources.
|
// NamespaceName contains configuration resources.
|
||||||
const NamespaceName resource.Namespace = v1alpha1.NamespaceName
|
const NamespaceName resource.Namespace = v1alpha1.NamespaceName
|
||||||
|
|||||||
@ -27,6 +27,8 @@ func TestRegisterResource(t *testing.T) {
|
|||||||
for _, resource := range []meta.ResourceWithRD{
|
for _, resource := range []meta.ResourceWithRD{
|
||||||
&block.Device{},
|
&block.Device{},
|
||||||
&block.DiscoveredVolume{},
|
&block.DiscoveredVolume{},
|
||||||
|
&block.Disk{},
|
||||||
|
&block.SystemDisk{},
|
||||||
} {
|
} {
|
||||||
assert.NoError(t, resourceRegistry.Register(ctx, resource))
|
assert.NoError(t, resourceRegistry.Register(ctx, resource))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// 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/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
// Code generated by "deep-copy -type DeviceSpec -type DiscoveredVolumeSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go ."; DO NOT EDIT.
|
// Code generated by "deep-copy -type DeviceSpec -type DiscoveredVolumeSpec -type DiskSpec -type SystemDiskSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go ."; DO NOT EDIT.
|
||||||
|
|
||||||
package block
|
package block
|
||||||
|
|
||||||
@ -17,3 +17,15 @@ func (o DiscoveredVolumeSpec) DeepCopy() DiscoveredVolumeSpec {
|
|||||||
var cp DiscoveredVolumeSpec = o
|
var cp DiscoveredVolumeSpec = o
|
||||||
return cp
|
return cp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopy generates a deep copy of DiskSpec.
|
||||||
|
func (o DiskSpec) DeepCopy() DiskSpec {
|
||||||
|
var cp DiskSpec = o
|
||||||
|
return cp
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy generates a deep copy of SystemDiskSpec.
|
||||||
|
func (o SystemDiskSpec) DeepCopy() SystemDiskSpec {
|
||||||
|
var cp SystemDiskSpec = o
|
||||||
|
return cp
|
||||||
|
}
|
||||||
|
|||||||
99
pkg/machinery/resources/block/disk.go
Normal file
99
pkg/machinery/resources/block/disk.go
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
// 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DiskType is type of Disk resource.
|
||||||
|
const DiskType = resource.Type("Disks.block.talos.dev")
|
||||||
|
|
||||||
|
// Disk resource holds status of hardware disks.
|
||||||
|
type Disk = typed.Resource[DiskSpec, DiskExtension]
|
||||||
|
|
||||||
|
// DiskSpec is the spec for Disks status.
|
||||||
|
//
|
||||||
|
//gotagsrewrite:gen
|
||||||
|
type DiskSpec struct {
|
||||||
|
Size uint64 `yaml:"size" protobuf:"1"`
|
||||||
|
IOSize uint `yaml:"ioSize" protobuf:"2"`
|
||||||
|
SectorSize uint `yaml:"sectorSize" protobuf:"3"`
|
||||||
|
|
||||||
|
Readonly bool `yaml:"readonly" protobuf:"4"`
|
||||||
|
|
||||||
|
Model string `yaml:"model,omitempty" protobuf:"5"`
|
||||||
|
Serial string `yaml:"serial,omitempty" protobuf:"6"`
|
||||||
|
Modalias string `yaml:"modalias,omitempty" protobuf:"7"`
|
||||||
|
WWID string `yaml:"wwid,omitempty" protobuf:"8"`
|
||||||
|
BusPath string `yaml:"busPath,omitempty" protobuf:"9"`
|
||||||
|
SubSystem string `yaml:"subSystem,omitempty" protobuf:"10"`
|
||||||
|
Transport string `yaml:"transport,omitempty" protobuf:"11"`
|
||||||
|
Rotational bool `yaml:"rotational,omitempty" protobuf:"12"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDisk initializes a BlockDisk resource.
|
||||||
|
func NewDisk(namespace resource.Namespace, id resource.ID) *Disk {
|
||||||
|
return typed.NewResource[DiskSpec, DiskExtension](
|
||||||
|
resource.NewMetadata(namespace, DiskType, id, resource.VersionUndefined),
|
||||||
|
DiskSpec{},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DiskExtension is auxiliary resource data for BlockDisk.
|
||||||
|
type DiskExtension struct{}
|
||||||
|
|
||||||
|
// ResourceDefinition implements meta.ResourceDefinitionProvider interface.
|
||||||
|
func (DiskExtension) ResourceDefinition() meta.ResourceDefinitionSpec {
|
||||||
|
return meta.ResourceDefinitionSpec{
|
||||||
|
Type: DiskType,
|
||||||
|
Aliases: []resource.Type{},
|
||||||
|
DefaultNamespace: NamespaceName,
|
||||||
|
PrintColumns: []meta.PrintColumn{
|
||||||
|
{
|
||||||
|
Name: "Size",
|
||||||
|
JSONPath: `{.size}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Read Only",
|
||||||
|
JSONPath: `{.readonly}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Transport",
|
||||||
|
JSONPath: `{.transport}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Rotational",
|
||||||
|
JSONPath: `{.rotational}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "WWID",
|
||||||
|
JSONPath: `{.wwid}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Model",
|
||||||
|
JSONPath: `{.model}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Serial",
|
||||||
|
JSONPath: `{.serial}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
proto.RegisterDefaultTypes()
|
||||||
|
|
||||||
|
err := protobuf.RegisterDynamic[DiskSpec](DiskType, &Disk{})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
65
pkg/machinery/resources/block/system_disk.go
Normal file
65
pkg/machinery/resources/block/system_disk.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SystemDiskType is type of SystemDisk resource.
|
||||||
|
const SystemDiskType = resource.Type("SystemDisks.block.talos.dev")
|
||||||
|
|
||||||
|
// SystemDisk resource holds ID of the disk which is the Talos system disk.
|
||||||
|
type SystemDisk = typed.Resource[SystemDiskSpec, SystemDiskExtension]
|
||||||
|
|
||||||
|
// SystemDiskID is the singleton resource ID.
|
||||||
|
const SystemDiskID resource.ID = "system-disk"
|
||||||
|
|
||||||
|
// SystemDiskSpec is the spec for SystemDisks status.
|
||||||
|
//
|
||||||
|
//gotagsrewrite:gen
|
||||||
|
type SystemDiskSpec struct {
|
||||||
|
DiskID string `yaml:"diskID" protobuf:"1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSystemDisk initializes a BlockSystemDisk resource.
|
||||||
|
func NewSystemDisk(namespace resource.Namespace, id resource.ID) *SystemDisk {
|
||||||
|
return typed.NewResource[SystemDiskSpec, SystemDiskExtension](
|
||||||
|
resource.NewMetadata(namespace, SystemDiskType, id, resource.VersionUndefined),
|
||||||
|
SystemDiskSpec{},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SystemDiskExtension is auxiliary resource data for BlockSystemDisk.
|
||||||
|
type SystemDiskExtension struct{}
|
||||||
|
|
||||||
|
// ResourceDefinition implements meta.ResourceDefinitionProvider interface.
|
||||||
|
func (SystemDiskExtension) ResourceDefinition() meta.ResourceDefinitionSpec {
|
||||||
|
return meta.ResourceDefinitionSpec{
|
||||||
|
Type: SystemDiskType,
|
||||||
|
Aliases: []resource.Type{},
|
||||||
|
DefaultNamespace: NamespaceName,
|
||||||
|
PrintColumns: []meta.PrintColumn{
|
||||||
|
{
|
||||||
|
Name: "Disk",
|
||||||
|
JSONPath: `{.diskID}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
proto.RegisterDefaultTypes()
|
||||||
|
|
||||||
|
err := protobuf.RegisterDynamic[SystemDiskSpec](SystemDiskType, &SystemDisk{})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -40,6 +40,7 @@ type LaunchConfig struct {
|
|||||||
|
|
||||||
// VM options
|
// VM options
|
||||||
DiskPaths []string
|
DiskPaths []string
|
||||||
|
DiskDrivers []string
|
||||||
VCPUCount int64
|
VCPUCount int64
|
||||||
MemSize int64
|
MemSize int64
|
||||||
QemuExecutable string
|
QemuExecutable string
|
||||||
@ -327,26 +328,65 @@ func launchVM(config *LaunchConfig) error {
|
|||||||
"-no-reboot",
|
"-no-reboot",
|
||||||
"-boot", fmt.Sprintf("order=%s,reboot-timeout=5000", bootOrder),
|
"-boot", fmt.Sprintf("order=%s,reboot-timeout=5000", bootOrder),
|
||||||
"-smbios", fmt.Sprintf("type=1,uuid=%s", config.NodeUUID),
|
"-smbios", fmt.Sprintf("type=1,uuid=%s", config.NodeUUID),
|
||||||
"-chardev",
|
"-chardev", fmt.Sprintf("socket,path=%s/%s.sock,server=on,wait=off,id=qga0", config.StatePath, config.Hostname),
|
||||||
fmt.Sprintf("socket,path=%s/%s.sock,server=on,wait=off,id=qga0", config.StatePath, config.Hostname),
|
"-device", "virtio-serial",
|
||||||
"-device",
|
"-device", "virtserialport,chardev=qga0,name=org.qemu.guest_agent.0",
|
||||||
"virtio-serial",
|
"-device", "i6300esb,id=watchdog0",
|
||||||
"-device",
|
|
||||||
"virtserialport,chardev=qga0,name=org.qemu.guest_agent.0",
|
|
||||||
"-device",
|
|
||||||
"i6300esb,id=watchdog0",
|
|
||||||
"-watchdog-action",
|
"-watchdog-action",
|
||||||
"pause",
|
"pause",
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, disk := range config.DiskPaths {
|
var (
|
||||||
driver := "virtio"
|
scsiAttached, ahciAttached, nvmeAttached bool
|
||||||
|
ahciBus int
|
||||||
|
)
|
||||||
|
|
||||||
if i > 0 {
|
for i, disk := range config.DiskPaths {
|
||||||
driver = "ide"
|
driver := config.DiskDrivers[i]
|
||||||
|
|
||||||
|
switch driver {
|
||||||
|
case "virtio":
|
||||||
|
args = append(args, "-drive", fmt.Sprintf("format=raw,if=virtio,file=%s,cache=none,", disk))
|
||||||
|
case "ide":
|
||||||
|
args = append(args, "-drive", fmt.Sprintf("format=raw,if=ide,file=%s,cache=none,", disk))
|
||||||
|
case "ahci":
|
||||||
|
if !ahciAttached {
|
||||||
|
args = append(args, "-device", "ahci,id=ahci0")
|
||||||
|
ahciAttached = true
|
||||||
}
|
}
|
||||||
|
|
||||||
args = append(args, "-drive", fmt.Sprintf("format=raw,if=%s,file=%s,cache=unsafe", driver, disk))
|
args = append(args,
|
||||||
|
"-drive", fmt.Sprintf("id=ide%d,format=raw,if=none,file=%s", i, disk),
|
||||||
|
"-device", fmt.Sprintf("ide-hd,drive=ide%d,bus=ahci0.%d", i, ahciBus),
|
||||||
|
)
|
||||||
|
|
||||||
|
ahciBus++
|
||||||
|
case "scsi":
|
||||||
|
if !scsiAttached {
|
||||||
|
args = append(args, "-device", "virtio-scsi-pci,id=scsi0")
|
||||||
|
scsiAttached = true
|
||||||
|
}
|
||||||
|
|
||||||
|
args = append(args,
|
||||||
|
"-drive", fmt.Sprintf("id=scsi%d,format=raw,if=none,file=%s,discard=unmap,aio=native,cache=none", i, disk),
|
||||||
|
"-device", fmt.Sprintf("scsi-hd,drive=scsi%d,bus=scsi0.0", i),
|
||||||
|
)
|
||||||
|
case "nvme":
|
||||||
|
if !nvmeAttached {
|
||||||
|
// [TODO]: once Talos is fixed, use multipath NVME: https://qemu-project.gitlab.io/qemu/system/devices/nvme.html
|
||||||
|
args = append(args,
|
||||||
|
"-device", "nvme,id=nvme-ctrl-0,serial=deadbeef",
|
||||||
|
)
|
||||||
|
nvmeAttached = true
|
||||||
|
}
|
||||||
|
|
||||||
|
args = append(args,
|
||||||
|
"-drive", fmt.Sprintf("id=nvme%d,format=raw,if=none,file=%s,discard=unmap,aio=native,cache=none", i, disk),
|
||||||
|
"-device", fmt.Sprintf("nvme-ns,drive=nvme%d", i),
|
||||||
|
)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unsupported disk driver %q", driver)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
machineArg := config.MachineType
|
machineArg := config.MachineType
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import (
|
|||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
|
"github.com/siderolabs/gen/xslices"
|
||||||
"github.com/siderolabs/go-procfs/procfs"
|
"github.com/siderolabs/go-procfs/procfs"
|
||||||
|
|
||||||
"github.com/siderolabs/talos/pkg/machinery/constants"
|
"github.com/siderolabs/talos/pkg/machinery/constants"
|
||||||
@ -114,9 +115,25 @@ func (p *provisioner) createNode(state *vm.State, clusterReq provision.ClusterRe
|
|||||||
defaultBootOrder = nodeReq.DefaultBootOrder
|
defaultBootOrder = nodeReq.DefaultBootOrder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// backwards compatibility, set Driver if not set
|
||||||
|
for i := range nodeReq.Disks {
|
||||||
|
if nodeReq.Disks[i].Driver != "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if i == 0 {
|
||||||
|
nodeReq.Disks[i].Driver = "virtio"
|
||||||
|
} else {
|
||||||
|
nodeReq.Disks[i].Driver = "ide"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
launchConfig := LaunchConfig{
|
launchConfig := LaunchConfig{
|
||||||
QemuExecutable: arch.QemuExecutable(),
|
QemuExecutable: arch.QemuExecutable(),
|
||||||
DiskPaths: diskPaths,
|
DiskPaths: diskPaths,
|
||||||
|
DiskDrivers: xslices.Map(nodeReq.Disks, func(disk *provision.Disk) string {
|
||||||
|
return disk.Driver
|
||||||
|
}),
|
||||||
VCPUCount: vcpuCount,
|
VCPUCount: vcpuCount,
|
||||||
MemSize: memSize,
|
MemSize: memSize,
|
||||||
KernelArgs: cmdline.String(),
|
KernelArgs: cmdline.String(),
|
||||||
|
|||||||
@ -158,6 +158,10 @@ type Disk struct {
|
|||||||
SkipPreallocate bool
|
SkipPreallocate bool
|
||||||
// Partitions represents the list of partitions.
|
// Partitions represents the list of partitions.
|
||||||
Partitions []*v1alpha1.DiskPartition
|
Partitions []*v1alpha1.DiskPartition
|
||||||
|
// Driver for the disk.
|
||||||
|
//
|
||||||
|
// Supported types: "virtio", "ide", "ahci", "scsi", "nvme".
|
||||||
|
Driver string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeRequest describes a request for a node.
|
// NodeRequest describes a request for a node.
|
||||||
|
|||||||
@ -29,6 +29,8 @@ description: Talos gRPC API reference.
|
|||||||
- [resource/definitions/block/block.proto](#resource/definitions/block/block.proto)
|
- [resource/definitions/block/block.proto](#resource/definitions/block/block.proto)
|
||||||
- [DeviceSpec](#talos.resource.definitions.block.DeviceSpec)
|
- [DeviceSpec](#talos.resource.definitions.block.DeviceSpec)
|
||||||
- [DiscoveredVolumeSpec](#talos.resource.definitions.block.DiscoveredVolumeSpec)
|
- [DiscoveredVolumeSpec](#talos.resource.definitions.block.DiscoveredVolumeSpec)
|
||||||
|
- [DiskSpec](#talos.resource.definitions.block.DiskSpec)
|
||||||
|
- [SystemDiskSpec](#talos.resource.definitions.block.SystemDiskSpec)
|
||||||
|
|
||||||
- [resource/definitions/cluster/cluster.proto](#resource/definitions/cluster/cluster.proto)
|
- [resource/definitions/cluster/cluster.proto](#resource/definitions/cluster/cluster.proto)
|
||||||
- [AffiliateSpec](#talos.resource.definitions.cluster.AffiliateSpec)
|
- [AffiliateSpec](#talos.resource.definitions.cluster.AffiliateSpec)
|
||||||
@ -813,6 +815,47 @@ DiscoveredVolumeSpec is the spec for DiscoveredVolumes status.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="talos.resource.definitions.block.DiskSpec"></a>
|
||||||
|
|
||||||
|
### DiskSpec
|
||||||
|
DiskSpec is the spec for Disks status.
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Label | Description |
|
||||||
|
| ----- | ---- | ----- | ----------- |
|
||||||
|
| size | [uint64](#uint64) | | |
|
||||||
|
| io_size | [uint64](#uint64) | | |
|
||||||
|
| sector_size | [uint64](#uint64) | | |
|
||||||
|
| readonly | [bool](#bool) | | |
|
||||||
|
| model | [string](#string) | | |
|
||||||
|
| serial | [string](#string) | | |
|
||||||
|
| modalias | [string](#string) | | |
|
||||||
|
| wwid | [string](#string) | | |
|
||||||
|
| bus_path | [string](#string) | | |
|
||||||
|
| sub_system | [string](#string) | | |
|
||||||
|
| transport | [string](#string) | | |
|
||||||
|
| rotational | [bool](#bool) | | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="talos.resource.definitions.block.SystemDiskSpec"></a>
|
||||||
|
|
||||||
|
### SystemDiskSpec
|
||||||
|
SystemDiskSpec is the spec for SystemDisks status.
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Label | Description |
|
||||||
|
| ----- | ---- | ----- | ----------- |
|
||||||
|
| disk_id | [string](#string) | | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- end messages -->
|
<!-- end messages -->
|
||||||
|
|
||||||
<!-- end enums -->
|
<!-- end enums -->
|
||||||
|
|||||||
@ -122,6 +122,7 @@ talosctl cluster create [flags]
|
|||||||
-p, --exposed-ports string Comma-separated list of ports/protocols to expose on init node. Ex -p <hostPort>:<containerPort>/<protocol (tcp or udp)> (Docker provisioner only)
|
-p, --exposed-ports string Comma-separated list of ports/protocols to expose on init node. Ex -p <hostPort>:<containerPort>/<protocol (tcp or udp)> (Docker provisioner only)
|
||||||
--extra-boot-kernel-args string add extra kernel args to the initial boot from vmlinuz and initramfs (QEMU only)
|
--extra-boot-kernel-args string add extra kernel args to the initial boot from vmlinuz and initramfs (QEMU only)
|
||||||
--extra-disks int number of extra disks to create for each worker VM
|
--extra-disks int number of extra disks to create for each worker VM
|
||||||
|
--extra-disks-drivers strings driver for each extra disk (virtio, ide, ahci, scsi, nvme)
|
||||||
--extra-disks-size int default limit on disk size in MB (each VM) (default 5120)
|
--extra-disks-size int default limit on disk size in MB (each VM) (default 5120)
|
||||||
--extra-uefi-search-paths strings additional search paths for UEFI firmware (only applies when UEFI is enabled)
|
--extra-uefi-search-paths strings additional search paths for UEFI firmware (only applies when UEFI is enabled)
|
||||||
-h, --help help for create
|
-h, --help help for create
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user