Skip to content

Commit

Permalink
Merge pull request #23 from spectrocloud/2281-allow-multiple-drives
Browse files Browse the repository at this point in the history
Allow the user to create more than one drives on the VM
  • Loading branch information
jimmykarily authored Apr 5, 2024
2 parents d1dc260 + 24e54b2 commit c5da712
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 38 deletions.
52 changes: 32 additions & 20 deletions pkg/machine/qemu.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,34 @@ type QEMU struct {
func (q *QEMU) Create(ctx context.Context) (context.Context, error) {
log.Info("Create qemu machine")

driveSize := q.driveSize()
drive := q.machineConfig.Drive
if q.machineConfig.AutoDriveSetup && q.machineConfig.Drive == "" {
err := q.CreateDisk(fmt.Sprintf("%s.img", q.machineConfig.ID), driveSize)
if err != nil {
return ctx, fmt.Errorf("creating disk with size %s: %w", driveSize, err)
driveSizes := q.driveSizes()
userDrives := q.machineConfig.Drives
if q.machineConfig.AutoDriveSetup && len(userDrives) == 0 {
for i, s := range driveSizes {
filename := fmt.Sprintf("%s-%d.img", q.machineConfig.ID, i)
err := q.CreateDisk(filename, s)
if err != nil {
return ctx, fmt.Errorf("creating disk with size %s: %w", s, err)
}
userDrives = append(userDrives, filepath.Join(q.machineConfig.StateDir, filename))
}
drive = filepath.Join(q.machineConfig.StateDir, fmt.Sprintf("%s.img", q.machineConfig.ID))
}

genDrives := func(m types.MachineConfig) []string {
drives := []string{}
allDrives := []string{}
if m.ISO != "" {
drives = append(drives, "-drive", fmt.Sprintf("if=ide,media=cdrom,file=%s", m.ISO))
allDrives = append(allDrives, "-drive", fmt.Sprintf("if=ide,media=cdrom,file=%s", m.ISO))
}
if m.DataSource != "" {
drives = append(drives, "-drive", fmt.Sprintf("if=ide,media=cdrom,file=%s", m.DataSource))
allDrives = append(allDrives, "-drive", fmt.Sprintf("if=ide,media=cdrom,file=%s", m.DataSource))
}
if drive != "" {
drives = append(drives, "-drive", fmt.Sprintf("if=virtio,media=disk,file=%s", drive))
if len(userDrives) != 0 {
for _, d := range userDrives {
allDrives = append(allDrives, "-drive", fmt.Sprintf("if=virtio,media=disk,file=%s", d))
}
}

return drives
return allDrives
}

processName := "/usr/bin/qemu-system-x86_64"
Expand All @@ -56,7 +61,9 @@ func (q *QEMU) Create(ctx context.Context) (context.Context, error) {
}

log.Infof("Starting VM with %s [ Memory: %s, CPU: %s ]", processName, q.machineConfig.Memory, q.machineConfig.CPU)
log.Infof("HD at %s, state directory at %s", drive, q.machineConfig.StateDir)
for _, d := range userDrives {
log.Infof("HD at %s, state directory at %s", d, q.machineConfig.StateDir)
}
if q.machineConfig.ISO != "" {
log.Infof("ISO at %s", q.machineConfig.ISO)
}
Expand Down Expand Up @@ -258,13 +265,18 @@ func (q *QEMU) monitorSockFile() string {
return path.Join(q.machineConfig.StateDir, "qemu-monitor.sock")
}

// Converts the user's drive size (which is Mb as a string) to the qemu format.
// Converts the user's drive sizes (which are Mb as strings) to the qemu format.
// https://qemu.readthedocs.io/en/latest/tools/qemu-img.html#cmdoption-qemu-img-arg-create
func (q *QEMU) driveSize() string {
driveSize := types.DefaultDriveSize
if q.machineConfig.Drive != "" {
driveSize = q.machineConfig.Drive
func (q *QEMU) driveSizes() []string {
sizes := []string{}

for _, s := range q.machineConfig.DriveSizes {
sizes = append(sizes, fmt.Sprintf("%sM", s))
}

if len(sizes) == 0 {
sizes = append(sizes, fmt.Sprintf("%sM", types.DefaultDriveSize))
}

return fmt.Sprintf("%sM", driveSize)
return sizes
}
8 changes: 4 additions & 4 deletions pkg/machine/types/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ type MachineConfig struct {
ISOChecksum string `yaml:"isoChecksum,omitempty"`

DataSource string `yaml:"datasource,omitempty"`
Drive string `yaml:"drive,omitempty"`
DriveSize string `yaml:"drivesize,omitempty"`
Drives []string `yaml:"drives,omitempty"`
DriveSizes []string `yaml:"driveSizes,omitempty"`
AutoDriveSetup bool `yaml:"auto_drive,omitempty"`
ID string `yaml:"id,omitempty"`
Memory string `yaml:"memory,omitempty"`
Expand Down Expand Up @@ -166,7 +166,7 @@ func WithISO(iso string) MachineOption {
func WithDrive(drive string) MachineOption {
return func(mc *MachineConfig) error {
if drive != "" {
mc.Drive = drive
mc.Drives = append(mc.Drives, drive)
}

return nil
Expand All @@ -176,7 +176,7 @@ func WithDrive(drive string) MachineOption {
func WithDriveSize(drivesize string) MachineOption {
return func(mc *MachineConfig) error {
if drivesize != "" {
mc.DriveSize = drivesize
mc.DriveSizes = append(mc.DriveSizes, drivesize)
}

return nil
Expand Down
39 changes: 25 additions & 14 deletions pkg/machine/vbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,35 +65,38 @@ func (v *VBox) Create(ctx context.Context) (context.Context, error) {
return ctx, fmt.Errorf("while set VM: %w - %s", err, out)
}

driveSize := types.DefaultDriveSize
if v.machineConfig.Drive != "" {
driveSize = v.machineConfig.Drive
}
drive := v.machineConfig.Drive
if v.machineConfig.AutoDriveSetup && v.machineConfig.Drive == "" {
err := v.CreateDisk(fmt.Sprintf("%s.vdi", v.machineConfig.ID), driveSize)
if err != nil {
return ctx, err
driveSizes := v.driveSizes()
userDrives := v.machineConfig.Drives
if v.machineConfig.AutoDriveSetup && len(userDrives) == 0 {
for i, s := range driveSizes {
err := v.CreateDisk(fmt.Sprintf("%s-%d.vdi", v.machineConfig.ID, i), s)
if err != nil {
return ctx, err
}
userDrives = append(userDrives, filepath.Join(v.machineConfig.StateDir, fmt.Sprintf("%s-%d.vdi", v.machineConfig.ID, i)))
}
drive = filepath.Join(v.machineConfig.StateDir, fmt.Sprintf("%s.vdi", v.machineConfig.ID))
}

if drive != "" {
out, err = utils.SH(fmt.Sprintf(`VBoxManage storageattach "%s" --storagectl "sata controller" --port 0 --device 0 --type hdd --medium %s`, v.machineConfig.ID, drive))
totalDrives := 0
for _, d := range userDrives {
totalDrives++
out, err = utils.SH(fmt.Sprintf(`VBoxManage storageattach "%s-%d" --storagectl "sata controller" --port %d --device 0 --type hdd --medium %s`, v.machineConfig.ID, totalDrives-1, totalDrives, d))
if err != nil {
return ctx, fmt.Errorf("while set VM: %w - %s", err, out)
}
}

if v.machineConfig.ISO != "" {
out, err = utils.SH(fmt.Sprintf(`VBoxManage storageattach "%s" --storagectl "sata controller" --port 1 --device 0 --type dvddrive --medium %s`, v.machineConfig.ID, v.machineConfig.ISO))
totalDrives++
out, err = utils.SH(fmt.Sprintf(`VBoxManage storageattach "%s" --storagectl "sata controller" --port %d --device 0 --type dvddrive --medium %s`, v.machineConfig.ID, totalDrives-1, v.machineConfig.ISO))
if err != nil {
return ctx, fmt.Errorf("while set VM: %w - %s", err, out)
}
}

if v.machineConfig.DataSource != "" {
out, err = utils.SH(fmt.Sprintf(`VBoxManage storageattach "%s" --storagectl "sata controller" --port 2 --device 0 --type dvddrive --medium %s`, v.machineConfig.ID, v.machineConfig.DataSource))
totalDrives++
out, err = utils.SH(fmt.Sprintf(`VBoxManage storageattach "%s" --storagectl "sata controller" --port %d --device 0 --type dvddrive --medium %s`, v.machineConfig.ID, totalDrives-1, v.machineConfig.DataSource))
if err != nil {
return ctx, fmt.Errorf("while set VM: %w - %s", err, out)
}
Expand Down Expand Up @@ -140,3 +143,11 @@ func (v *VBox) ReceiveFile(src, dst string) error {
func (v *VBox) SendFile(src, dst, permissions string) error {
return controller.SendFile(v, src, dst, permissions)
}

func (v *VBox) driveSizes() []string {
if len(v.machineConfig.DriveSizes) != 0 {
return v.machineConfig.DriveSizes
}

return []string{types.DefaultDriveSize}
}

0 comments on commit c5da712

Please sign in to comment.