fix: rework the 'metal-iso' config acquisition
Fixes #9538 Re-do the implementation by using the volume management primitives, so that we can avoid/skip old code. This should fix all issues related to the partition/whole disk. Fix issues in the volume management (exposed, as we haven't used it this way before). Build a test case in `talosctl cluster create` to inject machine config via `metal-iso`. Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com> (cherry picked from commit d39393879a1f98ac3de7a96808301d1e07fd95f3)
This commit is contained in:
parent
7ef5796500
commit
0e96e99b26
9
.github/workflows/ci.yaml
vendored
9
.github/workflows/ci.yaml
vendored
@ -1,6 +1,6 @@
|
||||
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
|
||||
#
|
||||
# Generated on 2024-10-08T12:03:35Z by kres 34e72ac.
|
||||
# Generated on 2024-10-25T14:37:51Z by kres 6d3cad4.
|
||||
|
||||
name: default
|
||||
concurrency:
|
||||
@ -2283,6 +2283,13 @@ jobs:
|
||||
WITH_NETWORK_CHAOS: "yes"
|
||||
run: |
|
||||
sudo -E make e2e-qemu
|
||||
- name: e2e-metal-iso
|
||||
env:
|
||||
IMAGE_REGISTRY: registry.dev.siderolabs.io
|
||||
SHORT_INTEGRATION_TEST: "yes"
|
||||
WITH_CONFIG_INJECTION_METHOD: metal-iso
|
||||
run: |
|
||||
sudo -E make e2e-qemu
|
||||
- name: save artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
|
@ -1,6 +1,6 @@
|
||||
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
|
||||
#
|
||||
# Generated on 2024-09-09T12:40:13Z by kres 8be5fa7.
|
||||
# Generated on 2024-10-25T14:37:51Z by kres 6d3cad4.
|
||||
|
||||
name: integration-misc-3-cron
|
||||
concurrency:
|
||||
@ -85,6 +85,13 @@ jobs:
|
||||
WITH_NETWORK_CHAOS: "yes"
|
||||
run: |
|
||||
sudo -E make e2e-qemu
|
||||
- name: e2e-metal-iso
|
||||
env:
|
||||
IMAGE_REGISTRY: registry.dev.siderolabs.io
|
||||
SHORT_INTEGRATION_TEST: "yes"
|
||||
WITH_CONFIG_INJECTION_METHOD: metal-iso
|
||||
run: |
|
||||
sudo -E make e2e-qemu
|
||||
- name: save artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
|
@ -865,6 +865,13 @@ spec:
|
||||
SHORT_INTEGRATION_TEST: yes
|
||||
WITH_NETWORK_CHAOS: yes
|
||||
IMAGE_REGISTRY: registry.dev.siderolabs.io
|
||||
- name: e2e-metal-iso
|
||||
command: e2e-qemu
|
||||
withSudo: true
|
||||
environment:
|
||||
SHORT_INTEGRATION_TEST: yes
|
||||
WITH_CONFIG_INJECTION_METHOD: "metal-iso"
|
||||
IMAGE_REGISTRY: registry.dev.siderolabs.io
|
||||
- name: save-talos-logs
|
||||
conditions:
|
||||
- always
|
||||
|
@ -372,6 +372,9 @@ enum BlockEncryptionProviderType {
|
||||
enum BlockFilesystemType {
|
||||
FILESYSTEM_TYPE_NONE = 0;
|
||||
FILESYSTEM_TYPE_XFS = 1;
|
||||
FILESYSTEM_TYPE_VFAT = 2;
|
||||
FILESYSTEM_TYPE_EXT4 = 3;
|
||||
FILESYSTEM_TYPE_ISO9660 = 4;
|
||||
}
|
||||
|
||||
// BlockVolumePhase describes volume phase.
|
||||
|
@ -188,6 +188,7 @@ var (
|
||||
withFirewall string
|
||||
withUUIDHostnames bool
|
||||
withSiderolinkAgent agentFlag
|
||||
configInjectionMethodFlag string
|
||||
)
|
||||
|
||||
// createCmd represents the cluster up command.
|
||||
@ -827,6 +828,17 @@ func create(ctx context.Context) error {
|
||||
// Add talosconfig to provision options, so we'll have it to parse there
|
||||
provisionOptions = append(provisionOptions, provision.WithTalosConfig(configBundle.TalosConfig()))
|
||||
|
||||
var configInjectionMethod provision.ConfigInjectionMethod
|
||||
|
||||
switch configInjectionMethodFlag {
|
||||
case "", "default", "http":
|
||||
configInjectionMethod = provision.ConfigInjectionMethodHTTP
|
||||
case "metal-iso":
|
||||
configInjectionMethod = provision.ConfigInjectionMethodMetalISO
|
||||
default:
|
||||
return fmt.Errorf("unknown config injection method %q", configInjectionMethod)
|
||||
}
|
||||
|
||||
// Create the controlplane nodes.
|
||||
for i := range controlplanes {
|
||||
var cfg config.Provider
|
||||
@ -844,16 +856,17 @@ func create(ctx context.Context) error {
|
||||
}
|
||||
|
||||
nodeReq := provision.NodeRequest{
|
||||
Name: nodeName(clusterName, "controlplane", i+1, nodeUUID),
|
||||
Type: machine.TypeControlPlane,
|
||||
IPs: nodeIPs,
|
||||
Memory: controlPlaneMemory,
|
||||
NanoCPUs: controlPlaneNanoCPUs,
|
||||
Disks: disks,
|
||||
SkipInjectingConfig: skipInjectingConfig,
|
||||
BadRTC: badRTC,
|
||||
ExtraKernelArgs: extraKernelArgs,
|
||||
UUID: pointer.To(nodeUUID),
|
||||
Name: nodeName(clusterName, "controlplane", i+1, nodeUUID),
|
||||
Type: machine.TypeControlPlane,
|
||||
IPs: nodeIPs,
|
||||
Memory: controlPlaneMemory,
|
||||
NanoCPUs: controlPlaneNanoCPUs,
|
||||
Disks: disks,
|
||||
SkipInjectingConfig: skipInjectingConfig,
|
||||
ConfigInjectionMethod: configInjectionMethod,
|
||||
BadRTC: badRTC,
|
||||
ExtraKernelArgs: extraKernelArgs,
|
||||
UUID: pointer.To(nodeUUID),
|
||||
}
|
||||
|
||||
if withInitNode && i == 0 {
|
||||
@ -871,6 +884,7 @@ func create(ctx context.Context) error {
|
||||
}
|
||||
|
||||
nodeReq.Config = cfg
|
||||
|
||||
request.Nodes = append(request.Nodes, nodeReq)
|
||||
}
|
||||
|
||||
@ -913,17 +927,18 @@ func create(ctx context.Context) error {
|
||||
|
||||
request.Nodes = append(request.Nodes,
|
||||
provision.NodeRequest{
|
||||
Name: nodeName(clusterName, "worker", i, nodeUUID),
|
||||
Type: machine.TypeWorker,
|
||||
IPs: nodeIPs,
|
||||
Memory: workerMemory,
|
||||
NanoCPUs: workerNanoCPUs,
|
||||
Disks: disks,
|
||||
Config: cfg,
|
||||
SkipInjectingConfig: skipInjectingConfig,
|
||||
BadRTC: badRTC,
|
||||
ExtraKernelArgs: extraKernelArgs,
|
||||
UUID: pointer.To(nodeUUID),
|
||||
Name: nodeName(clusterName, "worker", i, nodeUUID),
|
||||
Type: machine.TypeWorker,
|
||||
IPs: nodeIPs,
|
||||
Memory: workerMemory,
|
||||
NanoCPUs: workerNanoCPUs,
|
||||
Disks: disks,
|
||||
Config: cfg,
|
||||
ConfigInjectionMethod: configInjectionMethod,
|
||||
SkipInjectingConfig: skipInjectingConfig,
|
||||
BadRTC: badRTC,
|
||||
ExtraKernelArgs: extraKernelArgs,
|
||||
UUID: pointer.To(nodeUUID),
|
||||
})
|
||||
}
|
||||
|
||||
@ -1251,6 +1266,7 @@ func init() {
|
||||
createCmd.Flags().StringVar(&withFirewall, firewallFlag, "", "inject firewall rules into the cluster, value is default policy - accept/block (QEMU only)")
|
||||
createCmd.Flags().BoolVar(&withUUIDHostnames, "with-uuid-hostnames", false, "use machine UUIDs as default hostnames (QEMU only)")
|
||||
createCmd.Flags().Var(&withSiderolinkAgent, "with-siderolink", "enables the use of siderolink agent as configuration apply mechanism. `true` or `wireguard` enables the agent, `tunnel` enables the agent with grpc tunneling") //nolint:lll
|
||||
createCmd.Flags().StringVar(&configInjectionMethodFlag, "config-injection-method", "", "a method to inject machine config: default is HTTP server, 'metal-iso' to mount an ISO (QEMU only)")
|
||||
|
||||
createCmd.MarkFlagsMutuallyExclusive(inputDirFlag, nodeInstallImageFlag)
|
||||
createCmd.MarkFlagsMutuallyExclusive(inputDirFlag, configDebugFlag)
|
||||
|
@ -184,6 +184,14 @@ EOF
|
||||
;;
|
||||
esac
|
||||
|
||||
case "${WITH_CONFIG_INJECTION_METHOD:-default}" in
|
||||
default)
|
||||
;;
|
||||
*)
|
||||
QEMU_FLAGS+=("--config-injection-method=${WITH_CONFIG_INJECTION_METHOD}")
|
||||
;;
|
||||
esac
|
||||
|
||||
function create_cluster {
|
||||
build_registry_mirrors
|
||||
|
||||
|
@ -212,7 +212,10 @@ func (ctrl *DiscoveryController) rescan(ctx context.Context, r controller.Runtim
|
||||
dv.TypedSpec().Type = device.TypedSpec().Type
|
||||
dv.TypedSpec().DevicePath = device.TypedSpec().DevicePath
|
||||
dv.TypedSpec().Parent = device.TypedSpec().Parent
|
||||
dv.TypedSpec().ParentDevPath = filepath.Join("/dev", device.TypedSpec().Parent)
|
||||
|
||||
if device.TypedSpec().Parent != "" {
|
||||
dv.TypedSpec().ParentDevPath = filepath.Join("/dev", device.TypedSpec().Parent)
|
||||
}
|
||||
|
||||
dv.TypedSpec().SetSize(info.Size)
|
||||
dv.TypedSpec().SectorSize = info.SectorSize
|
||||
|
@ -7,21 +7,19 @@ package metal
|
||||
|
||||
import (
|
||||
"context"
|
||||
stderrors "errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/cosi-project/runtime/pkg/resource"
|
||||
"github.com/cosi-project/runtime/pkg/safe"
|
||||
"github.com/cosi-project/runtime/pkg/state"
|
||||
"github.com/siderolabs/gen/channel"
|
||||
"github.com/siderolabs/go-blockdevice/blockdevice/filesystem"
|
||||
"github.com/siderolabs/go-blockdevice/blockdevice/probe"
|
||||
"github.com/siderolabs/go-pointer"
|
||||
"github.com/siderolabs/go-procfs/procfs"
|
||||
"github.com/siderolabs/go-retry/retry"
|
||||
"golang.org/x/sys/unix"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime"
|
||||
@ -29,9 +27,13 @@ import (
|
||||
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime/v1alpha1/platform/internal/netutils"
|
||||
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime/v1alpha1/platform/metal/oauth2"
|
||||
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime/v1alpha1/platform/metal/url"
|
||||
"github.com/siderolabs/talos/internal/pkg/mount/v2"
|
||||
"github.com/siderolabs/talos/pkg/download"
|
||||
"github.com/siderolabs/talos/pkg/machinery/cel"
|
||||
"github.com/siderolabs/talos/pkg/machinery/cel/celenv"
|
||||
"github.com/siderolabs/talos/pkg/machinery/constants"
|
||||
"github.com/siderolabs/talos/pkg/machinery/meta"
|
||||
"github.com/siderolabs/talos/pkg/machinery/resources/block"
|
||||
"github.com/siderolabs/talos/pkg/machinery/resources/hardware"
|
||||
runtimeres "github.com/siderolabs/talos/pkg/machinery/resources/runtime"
|
||||
)
|
||||
@ -119,40 +121,69 @@ func (m *Metal) Mode() runtime.Mode {
|
||||
return runtime.ModeMetal
|
||||
}
|
||||
|
||||
func metalISOMatch() cel.Expression {
|
||||
return cel.MustExpression(cel.ParseBooleanExpression(
|
||||
fmt.Sprintf("volume.label == '%s' || volume.partition_label == '%s'", constants.MetalConfigISOLabel, constants.MetalConfigISOLabel),
|
||||
celenv.VolumeLocator(),
|
||||
))
|
||||
}
|
||||
|
||||
func readConfigFromISO(ctx context.Context, r state.State) ([]byte, error) {
|
||||
if err := netutils.WaitForDevicesReady(ctx, r); err != nil {
|
||||
return nil, fmt.Errorf("failed to wait for devices: %w", err)
|
||||
volumeID := "platform/metal/config"
|
||||
|
||||
// create a volume which matches the expected filesystem label
|
||||
vc := block.NewVolumeConfig(block.NamespaceName, volumeID)
|
||||
vc.Metadata().Labels().Set(block.PlatformLabel, "")
|
||||
vc.TypedSpec().Type = block.VolumeTypePartition
|
||||
vc.TypedSpec().Locator = block.LocatorSpec{
|
||||
Match: metalISOMatch(),
|
||||
}
|
||||
vc.TypedSpec().Mount = block.MountSpec{
|
||||
TargetPath: mnt,
|
||||
}
|
||||
|
||||
dev, err := probe.GetDevWithFileSystemLabel(constants.MetalConfigISOLabel)
|
||||
if err := r.Create(ctx, vc); err != nil && !state.IsConflictError(err) {
|
||||
return nil, fmt.Errorf("error creating user disk volume configuration: %w", err)
|
||||
}
|
||||
|
||||
// wait for the volume to be either ready or missing (includes waiting for devices to be ready)
|
||||
volumeStatus, err := safe.StateWatchFor[*block.VolumeStatus](ctx,
|
||||
r,
|
||||
block.NewVolumeStatus(vc.Metadata().Namespace(), vc.Metadata().ID()).Metadata(),
|
||||
state.WithEventTypes(state.Created, state.Updated),
|
||||
state.WithCondition(func(r resource.Resource) (bool, error) {
|
||||
phase := r.(*block.VolumeStatus).TypedSpec().Phase
|
||||
|
||||
return phase == block.VolumePhaseReady || phase == block.VolumePhaseMissing, nil
|
||||
}),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find %s iso: %w", constants.MetalConfigISOLabel, err)
|
||||
return nil, fmt.Errorf("failed to watch for volume status: %w", err)
|
||||
}
|
||||
|
||||
//nolint:errcheck
|
||||
defer dev.Close()
|
||||
if volumeStatus.TypedSpec().Phase == block.VolumePhaseMissing {
|
||||
return nil, fmt.Errorf("failed to find volume with machine configuration %s", vc.TypedSpec().Locator.Match)
|
||||
}
|
||||
|
||||
sb, err := filesystem.Probe(dev.Device().Name())
|
||||
// mount the volume, unmount when done
|
||||
unmounter, err := mount.NewPoint(volumeStatus.TypedSpec().MountLocation, vc.TypedSpec().Mount.TargetPath, volumeStatus.TypedSpec().Filesystem.String(), mount.WithReadonly()).Mount()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("failed to mount volume: %w", err)
|
||||
}
|
||||
|
||||
if sb == nil {
|
||||
return nil, stderrors.New("error while substituting filesystem type")
|
||||
}
|
||||
|
||||
if err = unix.Mount(dev.Device().Name(), mnt, sb.Type(), unix.MS_RDONLY, ""); err != nil {
|
||||
return nil, fmt.Errorf("failed to mount iso: %w", err)
|
||||
}
|
||||
defer unmounter() //nolint:errcheck
|
||||
|
||||
b, err := os.ReadFile(filepath.Join(mnt, filepath.Base(constants.ConfigPath)))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read config: %s", err.Error())
|
||||
return nil, fmt.Errorf("read config: %w", err)
|
||||
}
|
||||
|
||||
if err = unix.Unmount(mnt, 0); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmount: %w", err)
|
||||
}
|
||||
log.Printf("read machine config from volume: %s (filesystem %q, UUID %q, size %s)",
|
||||
volumeStatus.TypedSpec().Location,
|
||||
volumeStatus.TypedSpec().Filesystem,
|
||||
volumeStatus.TypedSpec().UUID,
|
||||
volumeStatus.TypedSpec().PrettySize,
|
||||
)
|
||||
|
||||
return b, nil
|
||||
}
|
||||
|
@ -1935,8 +1935,11 @@ func (BlockEncryptionProviderType) EnumDescriptor() ([]byte, []int) {
|
||||
type BlockFilesystemType int32
|
||||
|
||||
const (
|
||||
BlockFilesystemType_FILESYSTEM_TYPE_NONE BlockFilesystemType = 0
|
||||
BlockFilesystemType_FILESYSTEM_TYPE_XFS BlockFilesystemType = 1
|
||||
BlockFilesystemType_FILESYSTEM_TYPE_NONE BlockFilesystemType = 0
|
||||
BlockFilesystemType_FILESYSTEM_TYPE_XFS BlockFilesystemType = 1
|
||||
BlockFilesystemType_FILESYSTEM_TYPE_VFAT BlockFilesystemType = 2
|
||||
BlockFilesystemType_FILESYSTEM_TYPE_EXT4 BlockFilesystemType = 3
|
||||
BlockFilesystemType_FILESYSTEM_TYPE_ISO9660 BlockFilesystemType = 4
|
||||
)
|
||||
|
||||
// Enum value maps for BlockFilesystemType.
|
||||
@ -1944,10 +1947,16 @@ var (
|
||||
BlockFilesystemType_name = map[int32]string{
|
||||
0: "FILESYSTEM_TYPE_NONE",
|
||||
1: "FILESYSTEM_TYPE_XFS",
|
||||
2: "FILESYSTEM_TYPE_VFAT",
|
||||
3: "FILESYSTEM_TYPE_EXT4",
|
||||
4: "FILESYSTEM_TYPE_ISO9660",
|
||||
}
|
||||
BlockFilesystemType_value = map[string]int32{
|
||||
"FILESYSTEM_TYPE_NONE": 0,
|
||||
"FILESYSTEM_TYPE_XFS": 1,
|
||||
"FILESYSTEM_TYPE_NONE": 0,
|
||||
"FILESYSTEM_TYPE_XFS": 1,
|
||||
"FILESYSTEM_TYPE_VFAT": 2,
|
||||
"FILESYSTEM_TYPE_EXT4": 3,
|
||||
"FILESYSTEM_TYPE_ISO9660": 4,
|
||||
}
|
||||
)
|
||||
|
||||
@ -2695,76 +2704,81 @@ var file_resource_definitions_enums_enums_proto_rawDesc = []byte{
|
||||
0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x56, 0x49,
|
||||
0x44, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x45, 0x4e,
|
||||
0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x44, 0x45,
|
||||
0x52, 0x5f, 0x4c, 0x55, 0x4b, 0x53, 0x32, 0x10, 0x01, 0x2a, 0x48, 0x0a, 0x13, 0x42, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65,
|
||||
0x12, 0x18, 0x0a, 0x14, 0x46, 0x49, 0x4c, 0x45, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f, 0x54,
|
||||
0x59, 0x50, 0x45, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x46, 0x49,
|
||||
0x4c, 0x45, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x58, 0x46,
|
||||
0x53, 0x10, 0x01, 0x2a, 0xe3, 0x01, 0x0a, 0x10, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x6f, 0x6c,
|
||||
0x75, 0x6d, 0x65, 0x50, 0x68, 0x61, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4f, 0x4c, 0x55,
|
||||
0x4d, 0x45, 0x5f, 0x50, 0x48, 0x41, 0x53, 0x45, 0x5f, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47,
|
||||
0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x50, 0x48, 0x41,
|
||||
0x53, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x56,
|
||||
0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x50, 0x48, 0x41, 0x53, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x53,
|
||||
0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f,
|
||||
0x50, 0x48, 0x41, 0x53, 0x45, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12,
|
||||
0x1c, 0x0a, 0x18, 0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x50, 0x48, 0x41, 0x53, 0x45, 0x5f,
|
||||
0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x45, 0x44, 0x10, 0x04, 0x12, 0x19, 0x0a,
|
||||
0x15, 0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x50, 0x48, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x52,
|
||||
0x45, 0x50, 0x41, 0x52, 0x45, 0x44, 0x10, 0x05, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4f, 0x4c, 0x55,
|
||||
0x4d, 0x45, 0x5f, 0x50, 0x48, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x59, 0x10, 0x06,
|
||||
0x12, 0x17, 0x0a, 0x13, 0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x50, 0x48, 0x41, 0x53, 0x45,
|
||||
0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0x10, 0x07, 0x2a, 0x59, 0x0a, 0x0f, 0x42, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x15,
|
||||
0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x41, 0x52, 0x54,
|
||||
0x49, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x56, 0x4f, 0x4c, 0x55, 0x4d,
|
||||
0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x49, 0x53, 0x4b, 0x10, 0x01, 0x12, 0x15, 0x0a,
|
||||
0x11, 0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, 0x4d, 0x50,
|
||||
0x46, 0x53, 0x10, 0x02, 0x2a, 0x53, 0x0a, 0x11, 0x4b, 0x75, 0x62, 0x65, 0x73, 0x70, 0x61, 0x6e,
|
||||
0x50, 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x45, 0x45,
|
||||
0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10,
|
||||
0x00, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x45, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f,
|
||||
0x55, 0x50, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x45, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41,
|
||||
0x54, 0x45, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x02, 0x2a, 0x88, 0x01, 0x0a, 0x12, 0x4e, 0x65,
|
||||
0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72,
|
||||
0x12, 0x12, 0x0a, 0x0e, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55,
|
||||
0x4c, 0x54, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x43,
|
||||
0x4d, 0x44, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x4f, 0x4e, 0x46,
|
||||
0x49, 0x47, 0x5f, 0x50, 0x4c, 0x41, 0x54, 0x46, 0x4f, 0x52, 0x4d, 0x10, 0x02, 0x12, 0x13, 0x0a,
|
||||
0x0f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52,
|
||||
0x10, 0x03, 0x12, 0x20, 0x0a, 0x1c, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x4d, 0x41, 0x43,
|
||||
0x48, 0x49, 0x4e, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, 0x41, 0x54, 0x49,
|
||||
0x4f, 0x4e, 0x10, 0x04, 0x2a, 0x4b, 0x0a, 0x0f, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4f,
|
||||
0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x0e, 0x4f, 0x50, 0x45, 0x52, 0x41,
|
||||
0x54, 0x4f, 0x52, 0x5f, 0x44, 0x48, 0x43, 0x50, 0x34, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x4f,
|
||||
0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x44, 0x48, 0x43, 0x50, 0x36, 0x10, 0x01, 0x12,
|
||||
0x10, 0x0a, 0x0c, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x56, 0x49, 0x50, 0x10,
|
||||
0x02, 0x2a, 0x9b, 0x02, 0x0a, 0x13, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x4d, 0x61, 0x63,
|
||||
0x68, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x41, 0x43,
|
||||
0x48, 0x49, 0x4e, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f,
|
||||
0x57, 0x4e, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f,
|
||||
0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12,
|
||||
0x1c, 0x0a, 0x18, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45,
|
||||
0x5f, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x1d, 0x0a,
|
||||
0x19, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x4d,
|
||||
0x41, 0x49, 0x4e, 0x54, 0x45, 0x4e, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15,
|
||||
0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x52, 0x55,
|
||||
0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 0x1b, 0x0a, 0x17, 0x4d, 0x41, 0x43, 0x48, 0x49,
|
||||
0x4e, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x52, 0x45, 0x42, 0x4f, 0x4f, 0x54, 0x49,
|
||||
0x4e, 0x47, 0x10, 0x05, 0x12, 0x1f, 0x0a, 0x1b, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f,
|
||||
0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x48, 0x55, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x44,
|
||||
0x4f, 0x57, 0x4e, 0x10, 0x06, 0x12, 0x1b, 0x0a, 0x17, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45,
|
||||
0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x52, 0x45, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47,
|
||||
0x10, 0x07, 0x12, 0x1b, 0x0a, 0x17, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x53, 0x54,
|
||||
0x41, 0x47, 0x45, 0x5f, 0x55, 0x50, 0x47, 0x52, 0x41, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x08, 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, 0x65, 0x6e, 0x75, 0x6d, 0x73, 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,
|
||||
0x65, 0x6e, 0x75, 0x6d, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x52, 0x5f, 0x4c, 0x55, 0x4b, 0x53, 0x32, 0x10, 0x01, 0x2a, 0x99, 0x01, 0x0a, 0x13, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70,
|
||||
0x65, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x49, 0x4c, 0x45, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f,
|
||||
0x54, 0x59, 0x50, 0x45, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x46,
|
||||
0x49, 0x4c, 0x45, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x58,
|
||||
0x46, 0x53, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x49, 0x4c, 0x45, 0x53, 0x59, 0x53, 0x54,
|
||||
0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x56, 0x46, 0x41, 0x54, 0x10, 0x02, 0x12, 0x18,
|
||||
0x0a, 0x14, 0x46, 0x49, 0x4c, 0x45, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50,
|
||||
0x45, 0x5f, 0x45, 0x58, 0x54, 0x34, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x49, 0x4c, 0x45,
|
||||
0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x53, 0x4f, 0x39,
|
||||
0x36, 0x36, 0x30, 0x10, 0x04, 0x2a, 0xe3, 0x01, 0x0a, 0x10, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56,
|
||||
0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x50, 0x68, 0x61, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4f,
|
||||
0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x50, 0x48, 0x41, 0x53, 0x45, 0x5f, 0x57, 0x41, 0x49, 0x54, 0x49,
|
||||
0x4e, 0x47, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x50,
|
||||
0x48, 0x41, 0x53, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x18, 0x0a,
|
||||
0x14, 0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x50, 0x48, 0x41, 0x53, 0x45, 0x5f, 0x4d, 0x49,
|
||||
0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4f, 0x4c, 0x55, 0x4d,
|
||||
0x45, 0x5f, 0x50, 0x48, 0x41, 0x53, 0x45, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x45, 0x44, 0x10,
|
||||
0x03, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x50, 0x48, 0x41, 0x53,
|
||||
0x45, 0x5f, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x45, 0x44, 0x10, 0x04, 0x12,
|
||||
0x19, 0x0a, 0x15, 0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x50, 0x48, 0x41, 0x53, 0x45, 0x5f,
|
||||
0x50, 0x52, 0x45, 0x50, 0x41, 0x52, 0x45, 0x44, 0x10, 0x05, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4f,
|
||||
0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x50, 0x48, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x59,
|
||||
0x10, 0x06, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x50, 0x48, 0x41,
|
||||
0x53, 0x45, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0x10, 0x07, 0x2a, 0x59, 0x0a, 0x0f, 0x42,
|
||||
0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19,
|
||||
0x0a, 0x15, 0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x41,
|
||||
0x52, 0x54, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x56, 0x4f, 0x4c,
|
||||
0x55, 0x4d, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x49, 0x53, 0x4b, 0x10, 0x01, 0x12,
|
||||
0x15, 0x0a, 0x11, 0x56, 0x4f, 0x4c, 0x55, 0x4d, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54,
|
||||
0x4d, 0x50, 0x46, 0x53, 0x10, 0x02, 0x2a, 0x53, 0x0a, 0x11, 0x4b, 0x75, 0x62, 0x65, 0x73, 0x70,
|
||||
0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x50,
|
||||
0x45, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57,
|
||||
0x4e, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x45, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54,
|
||||
0x45, 0x5f, 0x55, 0x50, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x45, 0x45, 0x52, 0x5f, 0x53,
|
||||
0x54, 0x41, 0x54, 0x45, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x02, 0x2a, 0x88, 0x01, 0x0a, 0x12,
|
||||
0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79,
|
||||
0x65, 0x72, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x44, 0x45, 0x46,
|
||||
0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47,
|
||||
0x5f, 0x43, 0x4d, 0x44, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x4f,
|
||||
0x4e, 0x46, 0x49, 0x47, 0x5f, 0x50, 0x4c, 0x41, 0x54, 0x46, 0x4f, 0x52, 0x4d, 0x10, 0x02, 0x12,
|
||||
0x13, 0x0a, 0x0f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54,
|
||||
0x4f, 0x52, 0x10, 0x03, 0x12, 0x20, 0x0a, 0x1c, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x4d,
|
||||
0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, 0x41,
|
||||
0x54, 0x49, 0x4f, 0x4e, 0x10, 0x04, 0x2a, 0x4b, 0x0a, 0x0f, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72,
|
||||
0x6b, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x0e, 0x4f, 0x50, 0x45,
|
||||
0x52, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x44, 0x48, 0x43, 0x50, 0x34, 0x10, 0x00, 0x12, 0x12, 0x0a,
|
||||
0x0e, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x44, 0x48, 0x43, 0x50, 0x36, 0x10,
|
||||
0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x56, 0x49,
|
||||
0x50, 0x10, 0x02, 0x2a, 0x9b, 0x02, 0x0a, 0x13, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x4d,
|
||||
0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x19, 0x0a, 0x15, 0x4d,
|
||||
0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x55, 0x4e, 0x4b,
|
||||
0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e,
|
||||
0x45, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x49, 0x4e, 0x47, 0x10,
|
||||
0x01, 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x53, 0x54, 0x41,
|
||||
0x47, 0x45, 0x5f, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12,
|
||||
0x1d, 0x0a, 0x19, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45,
|
||||
0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x54, 0x45, 0x4e, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x03, 0x12, 0x19,
|
||||
0x0a, 0x15, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f,
|
||||
0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 0x1b, 0x0a, 0x17, 0x4d, 0x41, 0x43,
|
||||
0x48, 0x49, 0x4e, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x52, 0x45, 0x42, 0x4f, 0x4f,
|
||||
0x54, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x12, 0x1f, 0x0a, 0x1b, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e,
|
||||
0x45, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x48, 0x55, 0x54, 0x54, 0x49, 0x4e, 0x47,
|
||||
0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x06, 0x12, 0x1b, 0x0a, 0x17, 0x4d, 0x41, 0x43, 0x48, 0x49,
|
||||
0x4e, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x52, 0x45, 0x53, 0x45, 0x54, 0x54, 0x49,
|
||||
0x4e, 0x47, 0x10, 0x07, 0x12, 0x1b, 0x0a, 0x17, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f,
|
||||
0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x55, 0x50, 0x47, 0x52, 0x41, 0x44, 0x49, 0x4e, 0x47, 0x10,
|
||||
0x08, 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, 0x65, 0x6e, 0x75, 0x6d, 0x73, 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, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -142,6 +142,16 @@ func (expr *Expression) UnmarshalText(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer.
|
||||
func (expr Expression) String() string {
|
||||
b, err := expr.MarshalText()
|
||||
if err != nil {
|
||||
return "ERROR: " + err.Error()
|
||||
}
|
||||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// IsZero returns true if the expression is zero.
|
||||
func (expr Expression) IsZero() bool {
|
||||
return expr.ast == nil && expr.expression == nil
|
||||
|
@ -27,6 +27,9 @@ const NamespaceName resource.Namespace = v1alpha1.NamespaceName
|
||||
// UserDiskLabel is the label for user disks.
|
||||
const UserDiskLabel = "talos.dev/user-disk"
|
||||
|
||||
// PlatformLabel is the label for platform volumes.
|
||||
const PlatformLabel = "talos.dev/platform"
|
||||
|
||||
// WaitForVolumePhase waits for the volume to reach the expected phase(s).
|
||||
func WaitForVolumePhase(ctx context.Context, st state.State, volumeID string, expectedPhases ...VolumePhase) (*VolumeStatus, error) {
|
||||
volumeStatus, err := st.WatchFor(ctx,
|
||||
|
@ -11,6 +11,9 @@ type FilesystemType int
|
||||
//
|
||||
//structprotogen:gen_enum
|
||||
const (
|
||||
FilesystemTypeNone FilesystemType = iota // none
|
||||
FilesystemTypeXFS // xfs
|
||||
FilesystemTypeNone FilesystemType = iota // none
|
||||
FilesystemTypeXFS // xfs
|
||||
FilesystemTypeVFAT // vfat
|
||||
FilesystemTypeEXT4 // ext4
|
||||
FilesystemTypeISO9660 // iso9660
|
||||
)
|
||||
|
@ -199,11 +199,11 @@ func (i *VolumePhase) UnmarshalText(text []byte) error {
|
||||
return err
|
||||
}
|
||||
|
||||
const _FilesystemTypeName = "nonexfs"
|
||||
const _FilesystemTypeName = "nonexfsvfatext4iso9660"
|
||||
|
||||
var _FilesystemTypeIndex = [...]uint8{0, 4, 7}
|
||||
var _FilesystemTypeIndex = [...]uint8{0, 4, 7, 11, 15, 22}
|
||||
|
||||
const _FilesystemTypeLowerName = "nonexfs"
|
||||
const _FilesystemTypeLowerName = "nonexfsvfatext4iso9660"
|
||||
|
||||
func (i FilesystemType) String() string {
|
||||
if i < 0 || i >= FilesystemType(len(_FilesystemTypeIndex)-1) {
|
||||
@ -218,20 +218,32 @@ func _FilesystemTypeNoOp() {
|
||||
var x [1]struct{}
|
||||
_ = x[FilesystemTypeNone-(0)]
|
||||
_ = x[FilesystemTypeXFS-(1)]
|
||||
_ = x[FilesystemTypeVFAT-(2)]
|
||||
_ = x[FilesystemTypeEXT4-(3)]
|
||||
_ = x[FilesystemTypeISO9660-(4)]
|
||||
}
|
||||
|
||||
var _FilesystemTypeValues = []FilesystemType{FilesystemTypeNone, FilesystemTypeXFS}
|
||||
var _FilesystemTypeValues = []FilesystemType{FilesystemTypeNone, FilesystemTypeXFS, FilesystemTypeVFAT, FilesystemTypeEXT4, FilesystemTypeISO9660}
|
||||
|
||||
var _FilesystemTypeNameToValueMap = map[string]FilesystemType{
|
||||
_FilesystemTypeName[0:4]: FilesystemTypeNone,
|
||||
_FilesystemTypeLowerName[0:4]: FilesystemTypeNone,
|
||||
_FilesystemTypeName[4:7]: FilesystemTypeXFS,
|
||||
_FilesystemTypeLowerName[4:7]: FilesystemTypeXFS,
|
||||
_FilesystemTypeName[0:4]: FilesystemTypeNone,
|
||||
_FilesystemTypeLowerName[0:4]: FilesystemTypeNone,
|
||||
_FilesystemTypeName[4:7]: FilesystemTypeXFS,
|
||||
_FilesystemTypeLowerName[4:7]: FilesystemTypeXFS,
|
||||
_FilesystemTypeName[7:11]: FilesystemTypeVFAT,
|
||||
_FilesystemTypeLowerName[7:11]: FilesystemTypeVFAT,
|
||||
_FilesystemTypeName[11:15]: FilesystemTypeEXT4,
|
||||
_FilesystemTypeLowerName[11:15]: FilesystemTypeEXT4,
|
||||
_FilesystemTypeName[15:22]: FilesystemTypeISO9660,
|
||||
_FilesystemTypeLowerName[15:22]: FilesystemTypeISO9660,
|
||||
}
|
||||
|
||||
var _FilesystemTypeNames = []string{
|
||||
_FilesystemTypeName[0:4],
|
||||
_FilesystemTypeName[4:7],
|
||||
_FilesystemTypeName[7:11],
|
||||
_FilesystemTypeName[11:15],
|
||||
_FilesystemTypeName[15:22],
|
||||
}
|
||||
|
||||
// FilesystemTypeString retrieves an enum value from the enum constants string name.
|
||||
|
@ -46,6 +46,7 @@ type LaunchConfig struct {
|
||||
KernelImagePath string
|
||||
InitrdPath string
|
||||
ISOPath string
|
||||
ExtraISOPath string
|
||||
PFlashImages []string
|
||||
KernelArgs string
|
||||
MonitorPath string
|
||||
@ -383,6 +384,13 @@ func launchVM(config *LaunchConfig) error {
|
||||
|
||||
args = append(args, pflashArgs...)
|
||||
|
||||
if config.ExtraISOPath != "" {
|
||||
args = append(args,
|
||||
"-drive",
|
||||
fmt.Sprintf("file=%s,media=cdrom", config.ExtraISOPath),
|
||||
)
|
||||
}
|
||||
|
||||
// check if disk is empty/wiped
|
||||
diskBootable, err := checkPartitions(config)
|
||||
if err != nil {
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -20,6 +21,7 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/siderolabs/gen/xslices"
|
||||
"github.com/siderolabs/go-cmd/pkg/cmd"
|
||||
"github.com/siderolabs/go-procfs/procfs"
|
||||
|
||||
"github.com/siderolabs/talos/pkg/machinery/constants"
|
||||
@ -89,15 +91,28 @@ func (p *provisioner) createNode(state *vm.State, clusterReq provision.ClusterRe
|
||||
}
|
||||
}
|
||||
|
||||
var nodeConfig string
|
||||
var (
|
||||
nodeConfig string
|
||||
extraISOPath string
|
||||
)
|
||||
|
||||
if !nodeReq.SkipInjectingConfig {
|
||||
cmdline.Append("talos.config", "{TALOS_CONFIG_URL}") // to be patched by launcher
|
||||
|
||||
nodeConfig, err = nodeReq.Config.EncodeString()
|
||||
if err != nil {
|
||||
return provision.NodeInfo{}, err
|
||||
}
|
||||
|
||||
switch nodeReq.ConfigInjectionMethod {
|
||||
case provision.ConfigInjectionMethodHTTP:
|
||||
cmdline.Append("talos.config", "{TALOS_CONFIG_URL}") // to be patched by launcher
|
||||
case provision.ConfigInjectionMethodMetalISO:
|
||||
cmdline.Append("talos.config", "metal-iso")
|
||||
|
||||
extraISOPath, err = p.createMetalConfigISO(state, nodeReq.Name, nodeConfig)
|
||||
if err != nil {
|
||||
return provision.NodeInfo{}, fmt.Errorf("error creating metal-iso: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nodeUUID := uuid.New()
|
||||
@ -137,6 +152,7 @@ func (p *provisioner) createNode(state *vm.State, clusterReq provision.ClusterRe
|
||||
VCPUCount: vcpuCount,
|
||||
MemSize: memSize,
|
||||
KernelArgs: cmdline.String(),
|
||||
ExtraISOPath: extraISOPath,
|
||||
PFlashImages: pflashImages,
|
||||
MonitorPath: state.GetRelativePath(fmt.Sprintf("%s.monitor", nodeReq.Name)),
|
||||
EnableKVM: opts.TargetArch == runtime.GOARCH,
|
||||
@ -304,3 +320,25 @@ func (p *provisioner) populateSystemDisk(disks []string, clusterReq provision.Cl
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *provisioner) createMetalConfigISO(state *vm.State, nodeName, config string) (string, error) {
|
||||
isoPath := state.GetRelativePath(nodeName + "-metal-config.iso")
|
||||
|
||||
tmpDir, err := os.MkdirTemp("", "talos-metal-config-iso")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
defer os.RemoveAll(tmpDir) //nolint:errcheck
|
||||
|
||||
if err = os.WriteFile(filepath.Join(tmpDir, "config.yaml"), []byte(config), 0o644); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
_, err = cmd.Run("mkisofs", "-joliet", "-rock", "-volid", "metal-iso", "-output", isoPath, tmpDir)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return isoPath, nil
|
||||
}
|
||||
|
@ -164,12 +164,24 @@ type Disk struct {
|
||||
Driver string
|
||||
}
|
||||
|
||||
// ConfigInjectionMethod describes how to inject configuration into the node.
|
||||
type ConfigInjectionMethod int
|
||||
|
||||
const (
|
||||
// ConfigInjectionMethodHTTP injects configuration via HTTP.
|
||||
ConfigInjectionMethodHTTP ConfigInjectionMethod = iota
|
||||
// ConfigInjectionMethodMetalISO injects configuration via Metal ISO.
|
||||
ConfigInjectionMethodMetalISO
|
||||
)
|
||||
|
||||
// NodeRequest describes a request for a node.
|
||||
type NodeRequest struct {
|
||||
Name string
|
||||
IPs []netip.Addr
|
||||
Config config.Provider
|
||||
Type machine.Type
|
||||
Name string
|
||||
IPs []netip.Addr
|
||||
Type machine.Type
|
||||
|
||||
Config config.Provider
|
||||
ConfigInjectionMethod ConfigInjectionMethod
|
||||
|
||||
// Share of CPUs, in 1e-9 fractions
|
||||
NanoCPUs int64
|
||||
|
@ -1346,6 +1346,9 @@ BlockFilesystemType describes filesystem type.
|
||||
| ---- | ------ | ----------- |
|
||||
| FILESYSTEM_TYPE_NONE | 0 | |
|
||||
| FILESYSTEM_TYPE_XFS | 1 | |
|
||||
| FILESYSTEM_TYPE_VFAT | 2 | |
|
||||
| FILESYSTEM_TYPE_EXT4 | 3 | |
|
||||
| FILESYSTEM_TYPE_ISO9660 | 4 | |
|
||||
|
||||
|
||||
|
||||
|
@ -99,6 +99,7 @@ talosctl cluster create [flags]
|
||||
--cni-bundle-url string URL to download CNI bundle from (VM only) (default "https://github.com/siderolabs/talos/releases/download/v1.8.1/talosctl-cni-bundle-${ARCH}.tar.gz")
|
||||
--cni-cache-dir string CNI cache directory path (VM only) (default "/home/user/.talos/cni/cache")
|
||||
--cni-conf-dir string CNI config directory path (VM only) (default "/home/user/.talos/cni/conf.d")
|
||||
--config-injection-method string a method to inject machine config: default is HTTP server, 'metal-iso' to mount an ISO (QEMU only)
|
||||
--config-patch stringArray patch generated machineconfigs (applied to all node types), use @file to read a patch from file
|
||||
--config-patch-control-plane stringArray patch generated machineconfigs (applied to 'init' and 'controlplane' types)
|
||||
--config-patch-worker stringArray patch generated machineconfigs (applied to 'worker' type)
|
||||
|
Loading…
x
Reference in New Issue
Block a user