diff --git a/cmd/talosctl/cmd/mgmt/cluster/create.go b/cmd/talosctl/cmd/mgmt/cluster/create.go index be237b4679..d3c5334d5e 100644 --- a/cmd/talosctl/cmd/mgmt/cluster/create.go +++ b/cmd/talosctl/cmd/mgmt/cluster/create.go @@ -119,6 +119,7 @@ var ( nodeVmlinuzPath string nodeInitramfsPath string nodeISOPath string + nodeUSBPath string nodeDiskImagePath string nodeIPXEBootScript string applyConfigEnabled bool @@ -223,6 +224,9 @@ func downloadBootAssets(ctx context.Context) error { { path: &nodeISOPath, }, + { + path: &nodeUSBPath, + }, { path: &nodeDiskImagePath, }, @@ -462,6 +466,7 @@ func create(ctx context.Context) error { KernelPath: nodeVmlinuzPath, InitramfsPath: nodeInitramfsPath, ISOPath: nodeISOPath, + USBPath: nodeUSBPath, IPXEBootScript: nodeIPXEBootScript, DiskImagePath: nodeDiskImagePath, @@ -1239,6 +1244,7 @@ func init() { createCmd.Flags().StringVar(&nodeInstallImage, nodeInstallImageFlag, helpers.DefaultImage(images.DefaultInstallerImageRepository), "the installer image to use") createCmd.Flags().StringVar(&nodeVmlinuzPath, "vmlinuz-path", helpers.ArtifactPath(constants.KernelAssetWithArch), "the compressed kernel image to use") createCmd.Flags().StringVar(&nodeISOPath, "iso-path", "", "the ISO path to use for the initial boot (VM only)") + createCmd.Flags().StringVar(&nodeUSBPath, "usb-path", "", "the USB stick image path to use for the initial boot (VM only)") createCmd.Flags().StringVar(&nodeInitramfsPath, "initrd-path", helpers.ArtifactPath(constants.InitramfsAssetWithArch), "initramfs image to use") createCmd.Flags().StringVar(&nodeDiskImagePath, "disk-image-path", "", "disk image to use") createCmd.Flags().StringVar(&nodeIPXEBootScript, "ipxe-boot-script", "", "iPXE boot script (URL) to use") diff --git a/pkg/provision/providers/qemu/launch.go b/pkg/provision/providers/qemu/launch.go index 4a06f0f0d3..d73f231d03 100644 --- a/pkg/provision/providers/qemu/launch.go +++ b/pkg/provision/providers/qemu/launch.go @@ -47,6 +47,7 @@ type LaunchConfig struct { KernelImagePath string InitrdPath string ISOPath string + USBPath string ExtraISOPath string PFlashImages []string KernelArgs string @@ -439,12 +440,19 @@ func launchVM(config *LaunchConfig) error { } if !diskBootable || !config.BootloaderEnabled { - if config.ISOPath != "" { + switch { + case config.ISOPath != "": args = append(args, "-drive", fmt.Sprintf("file=%s,media=cdrom", config.ISOPath), ) - } else if config.KernelImagePath != "" { + case config.USBPath != "": + args = append(args, + "-drive", fmt.Sprintf("if=none,id=stick,format=raw,file=%s", config.USBPath), + "-device", "nec-usb-xhci,id=xhci", + "-device", "usb-storage,bus=xhci.0,drive=stick,removable=on", + ) + case config.KernelImagePath != "": args = append(args, "-kernel", config.KernelImagePath, "-initrd", config.InitrdPath, diff --git a/pkg/provision/providers/qemu/node.go b/pkg/provision/providers/qemu/node.go index be1d8e5a18..0c235aee31 100644 --- a/pkg/provision/providers/qemu/node.go +++ b/pkg/provision/providers/qemu/node.go @@ -221,6 +221,7 @@ func (p *provisioner) createNode(state *vm.State, clusterReq provision.ClusterRe launchConfig.KernelImagePath = strings.ReplaceAll(clusterReq.KernelPath, constants.ArchVariable, opts.TargetArch) launchConfig.InitrdPath = strings.ReplaceAll(clusterReq.InitramfsPath, constants.ArchVariable, opts.TargetArch) launchConfig.ISOPath = strings.ReplaceAll(clusterReq.ISOPath, constants.ArchVariable, opts.TargetArch) + launchConfig.USBPath = strings.ReplaceAll(clusterReq.USBPath, constants.ArchVariable, opts.TargetArch) } launchConfig.StatePath, err = state.StatePath() diff --git a/pkg/provision/request.go b/pkg/provision/request.go index d8f831319f..a682f82a58 100644 --- a/pkg/provision/request.go +++ b/pkg/provision/request.go @@ -33,6 +33,7 @@ type ClusterRequest struct { KernelPath string InitramfsPath string ISOPath string + USBPath string DiskImagePath string IPXEBootScript string diff --git a/website/content/v1.9/reference/cli.md b/website/content/v1.9/reference/cli.md index 7074170d26..3c35282c97 100644 --- a/website/content/v1.9/reference/cli.md +++ b/website/content/v1.9/reference/cli.md @@ -198,6 +198,7 @@ talosctl cluster create [flags] --skip-kubeconfig skip merging kubeconfig from the created cluster --talos-version string the desired Talos version to generate config for (if not set, defaults to image version) --talosconfig string The path to the Talos configuration file. Defaults to 'TALOSCONFIG' env variable if set, otherwise '$HOME/.talos/config' and '/var/run/secrets/talos.dev/config' in order. + --usb-path string the USB stick image path to use for the initial boot (VM only) --use-vip use a virtual IP for the controlplane endpoint instead of the loadbalancer --user-disk strings list of disks to create for each VM in format: ::: --vmlinuz-path string the compressed kernel image to use (default "_out/vmlinuz-${ARCH}")