qemu driver: Add option to configure drive_interface (#11864)
This commit is contained in:
parent
0443a3b8c1
commit
8c52c03c8c
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:improvement
|
||||||
|
qemu: Added option to configure `drive_interface`
|
||||||
|
```
|
|
@ -95,6 +95,7 @@ var (
|
||||||
// a taskConfig within a job. It is returned in the TaskConfigSchema RPC
|
// a taskConfig within a job. It is returned in the TaskConfigSchema RPC
|
||||||
taskConfigSpec = hclspec.NewObject(map[string]*hclspec.Spec{
|
taskConfigSpec = hclspec.NewObject(map[string]*hclspec.Spec{
|
||||||
"image_path": hclspec.NewAttr("image_path", "string", true),
|
"image_path": hclspec.NewAttr("image_path", "string", true),
|
||||||
|
"drive_interface": hclspec.NewAttr("drive_interface", "string", false),
|
||||||
"accelerator": hclspec.NewAttr("accelerator", "string", false),
|
"accelerator": hclspec.NewAttr("accelerator", "string", false),
|
||||||
"graceful_shutdown": hclspec.NewAttr("graceful_shutdown", "bool", false),
|
"graceful_shutdown": hclspec.NewAttr("graceful_shutdown", "bool", false),
|
||||||
"guest_agent": hclspec.NewAttr("guest_agent", "bool", false),
|
"guest_agent": hclspec.NewAttr("guest_agent", "bool", false),
|
||||||
|
@ -125,6 +126,7 @@ type TaskConfig struct {
|
||||||
Args []string `codec:"args"` // extra arguments to qemu executable
|
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
|
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"`
|
GracefulShutdown bool `codec:"graceful_shutdown"`
|
||||||
|
DriveInterface string `codec:"drive_interface"` // Use interface for image
|
||||||
GuestAgent bool `codec:"guest_agent"`
|
GuestAgent bool `codec:"guest_agent"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,6 +346,19 @@ func isAllowedImagePath(allowedPaths []string, allocDir, imagePath string) bool
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hardcoded list of drive interfaces, Qemu currently supports
|
||||||
|
var allowedDriveInterfaces = []string{"ide", "scsi", "sd", "mtd", "floppy", "pflash", "virtio", "none"}
|
||||||
|
|
||||||
|
func isAllowedDriveInterface(driveInterface string) bool {
|
||||||
|
for _, ai := range allowedDriveInterfaces {
|
||||||
|
if driveInterface == ai {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// validateArgs ensures that all QEMU command line params are in the
|
// validateArgs ensures that all QEMU command line params are in the
|
||||||
// allowlist. This function must be called after all interpolation has
|
// allowlist. This function must be called after all interpolation has
|
||||||
// taken place.
|
// taken place.
|
||||||
|
@ -414,12 +429,20 @@ func (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *drive
|
||||||
return nil, nil, err
|
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{
|
args := []string{
|
||||||
absPath,
|
absPath,
|
||||||
"-machine", "type=pc,accel=" + accelerator,
|
"-machine", "type=pc,accel=" + accelerator,
|
||||||
"-name", vmID,
|
"-name", vmID,
|
||||||
"-m", mem,
|
"-m", mem,
|
||||||
"-drive", "file=" + vmPath,
|
"-drive", "file=" + vmPath + ",if=" + driveInterface,
|
||||||
"-nographic",
|
"-nographic",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -390,6 +390,7 @@ func TestConfig_ParseAllHCL(t *testing.T) {
|
||||||
cfgStr := `
|
cfgStr := `
|
||||||
config {
|
config {
|
||||||
image_path = "/tmp/image_path"
|
image_path = "/tmp/image_path"
|
||||||
|
drive_interface = "virtio"
|
||||||
accelerator = "kvm"
|
accelerator = "kvm"
|
||||||
args = ["arg1", "arg2"]
|
args = ["arg1", "arg2"]
|
||||||
port_map {
|
port_map {
|
||||||
|
@ -400,9 +401,10 @@ config {
|
||||||
}`
|
}`
|
||||||
|
|
||||||
expected := &TaskConfig{
|
expected := &TaskConfig{
|
||||||
ImagePath: "/tmp/image_path",
|
ImagePath: "/tmp/image_path",
|
||||||
Accelerator: "kvm",
|
DriveInterface: "virtio",
|
||||||
Args: []string{"arg1", "arg2"},
|
Accelerator: "kvm",
|
||||||
|
Args: []string{"arg1", "arg2"},
|
||||||
PortMap: map[string]int{
|
PortMap: map[string]int{
|
||||||
"http": 80,
|
"http": 80,
|
||||||
"https": 443,
|
"https": 443,
|
||||||
|
@ -416,6 +418,19 @@ config {
|
||||||
require.EqualValues(t, expected, tc)
|
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) {
|
func TestIsAllowedImagePath(t *testing.T) {
|
||||||
ci.Parallel(t)
|
ci.Parallel(t)
|
||||||
|
|
||||||
|
|
|
@ -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
|
contains the image in a subfolder, the path will need to be the relative path
|
||||||
(`subdir/from_archive/my.img`).
|
(`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.
|
- `accelerator` - (Optional) The type of accelerator to use in the invocation.
|
||||||
If the host machine has `qemu` installed with KVM support, users can specify
|
If the host machine has `qemu` installed with KVM support, users can specify
|
||||||
`kvm` for the `accelerator`. Default is `tcg`.
|
`kvm` for the `accelerator`. Default is `tcg`.
|
||||||
|
|
Loading…
Reference in New Issue