From 9ff12602f58a350e22345eb1b29c110147500acf Mon Sep 17 00:00:00 2001 From: Daniel Rossbach Date: Sat, 15 Jan 2022 22:25:41 +0100 Subject: [PATCH 1/3] qemu driver: Add option to configure drive_interface --- drivers/qemu/driver.go | 25 ++++++++++++++++++++++++- drivers/qemu/driver_test.go | 21 ++++++++++++++++++--- website/content/docs/drivers/qemu.mdx | 4 ++++ 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/drivers/qemu/driver.go b/drivers/qemu/driver.go index 4a3db808220a..b12db11574a0 100644 --- a/drivers/qemu/driver.go +++ b/drivers/qemu/driver.go @@ -92,6 +92,7 @@ var ( // a taskConfig within a job. It is returned in the TaskConfigSchema RPC taskConfigSpec = hclspec.NewObject(map[string]*hclspec.Spec{ "image_path": hclspec.NewAttr("image_path", "string", true), + "drive_interface": hclspec.NewAttr("drive_interface", "string", false), "accelerator": hclspec.NewAttr("accelerator", "string", false), "graceful_shutdown": hclspec.NewAttr("graceful_shutdown", "bool", false), "args": hclspec.NewAttr("args", "list(string)", false), @@ -121,6 +122,7 @@ type TaskConfig struct { Args []string `codec:"args"` // extra arguments to qemu executable PortMap hclutils.MapStrInt `codec:"port_map"` // A map of host port and the port name defined in the image manifest file GracefulShutdown bool `codec:"graceful_shutdown"` + DriveInterface string `codec:"drive_interface"` // Use interface for image } // TaskState is the state which is encoded in the handle returned in StartTask. @@ -344,6 +346,19 @@ func isAllowedImagePath(allowedPaths []string, allocDir, imagePath string) bool return false } +func isAllowedDriveInterface(driveInterface string) bool { + // hardocoded list of drive interfaces, Qemu currently supports + var interfaceList = []string{"ide", "scsi", "sd", "mtd", "floppy", "pflash", "virtio", "none"} + + for _, ai := range interfaceList { + if driveInterface == ai { + return true + } + } + + return false +} + // validateArgs ensures that all QEMU command line params are in the // allowlist. This function must be called after all interpolation has // taken place. @@ -414,12 +429,20 @@ func (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *drive return nil, nil, err } + driveInterface := "ide" + if driverConfig.DriveInterface != "" { + driveInterface = driverConfig.DriveInterface + } + if !isAllowedDriveInterface(driveInterface) { + return nil, nil, fmt.Errorf("Unsupported drive_interface") + } + args := []string{ absPath, "-machine", "type=pc,accel=" + accelerator, "-name", vmID, "-m", mem, - "-drive", "file=" + vmPath, + "-drive", "file=" + vmPath + ",if=" + driveInterface, "-nographic", } diff --git a/drivers/qemu/driver_test.go b/drivers/qemu/driver_test.go index 8777c7de5783..74ada3004b3a 100644 --- a/drivers/qemu/driver_test.go +++ b/drivers/qemu/driver_test.go @@ -399,6 +399,7 @@ func TestConfig_ParseAllHCL(t *testing.T) { cfgStr := ` config { image_path = "/tmp/image_path" + drive_interface = "virtio" accelerator = "kvm" args = ["arg1", "arg2"] port_map { @@ -409,9 +410,10 @@ config { }` expected := &TaskConfig{ - ImagePath: "/tmp/image_path", - Accelerator: "kvm", - Args: []string{"arg1", "arg2"}, + ImagePath: "/tmp/image_path", + DriveInterface: "virtio", + Accelerator: "kvm", + Args: []string{"arg1", "arg2"}, PortMap: map[string]int{ "http": 80, "https": 443, @@ -425,6 +427,19 @@ config { require.EqualValues(t, expected, tc) } +func TestIsAllowedDriveInterface(t *testing.T) { + validInterfaces := []string{"ide", "scsi", "sd", "mtd", "floppy", "pflash", "virtio", "none"} + invalidInterfaces := []string{"foo", "virtio-foo"} + + for _, i := range validInterfaces { + require.Truef(t, isAllowedDriveInterface(i), "drive_interface should be allowed: %v", i) + } + + for _, i := range invalidInterfaces { + require.Falsef(t, isAllowedDriveInterface(i), "drive_interface should be not allowed: %v", i) + } +} + func TestIsAllowedImagePath(t *testing.T) { allowedPaths := []string{"/tmp", "/opt/qemu"} allocDir := "/opt/nomad/some-alloc-dir" diff --git a/website/content/docs/drivers/qemu.mdx b/website/content/docs/drivers/qemu.mdx index 7ba7630c36b2..583f2c2f3784 100644 --- a/website/content/docs/drivers/qemu.mdx +++ b/website/content/docs/drivers/qemu.mdx @@ -42,6 +42,10 @@ The `qemu` driver supports the following configuration in the job spec: contains the image in a subfolder, the path will need to be the relative path (`subdir/from_archive/my.img`). +- `drive_interface` - (Optional) This option defines on which type of interface + the drive is connected. Available types are: `ide`, `scsi`, `sd`, `mtd`, + `floppy`, `pflash`, `virtio` and `none`. Default is `ide`. + - `accelerator` - (Optional) The type of accelerator to use in the invocation. If the host machine has `qemu` installed with KVM support, users can specify `kvm` for the `accelerator`. Default is `tcg`. From 5b8b34e980b7fa7cb966f04052fff14a15e05f53 Mon Sep 17 00:00:00 2001 From: Daniel Rossbach Date: Fri, 10 Jun 2022 15:26:40 +0200 Subject: [PATCH 2/3] Update drivers/qemu/driver.go Co-authored-by: Tim Gross --- drivers/qemu/driver.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/qemu/driver.go b/drivers/qemu/driver.go index b12db11574a0..1e2f960e26c2 100644 --- a/drivers/qemu/driver.go +++ b/drivers/qemu/driver.go @@ -346,11 +346,11 @@ func isAllowedImagePath(allowedPaths []string, allocDir, imagePath string) bool return false } -func isAllowedDriveInterface(driveInterface string) bool { - // hardocoded list of drive interfaces, Qemu currently supports - var interfaceList = []string{"ide", "scsi", "sd", "mtd", "floppy", "pflash", "virtio", "none"} +// hardcoded list of drive interfaces, Qemu currently supports +var allowedDriveInterfaces = []string{"ide", "scsi", "sd", "mtd", "floppy", "pflash", "virtio", "none"} - for _, ai := range interfaceList { +func isAllowedDriveInterface(driveInterface string) bool { + for _, ai := range allowedDriveInterfaces { if driveInterface == ai { return true } From f70fac8a821cd41897ff045fc507981510fbe967 Mon Sep 17 00:00:00 2001 From: Daniel Rossbach Date: Fri, 10 Jun 2022 15:37:28 +0200 Subject: [PATCH 3/3] Add changelog entry --- .changelog/11864.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/11864.txt diff --git a/.changelog/11864.txt b/.changelog/11864.txt new file mode 100644 index 000000000000..9ca1db038bda --- /dev/null +++ b/.changelog/11864.txt @@ -0,0 +1,3 @@ +```release-note:improvement +qemu: Added option to configure `drive_interface` +```