Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"path"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -63,6 +64,7 @@ type VirtualMachineOptions struct {
SecureBootTemplateId string
HighMmioBaseInMB int32
HighMmioGapInMB int32
DataVhdPaths []string
}

const plan9Port = 564
Expand All @@ -83,6 +85,11 @@ func CreateVirtualMachineSpec(opts *VirtualMachineOptions) (*VirtualMachineSpec,
if err := wclayer.GrantVmAccess(opts.Id, opts.IsoPath); err != nil {
return nil, err
}
for _, vhdPath := range opts.DataVhdPaths {
if err := wclayer.GrantVmAccess(opts.Id, vhdPath); err != nil {
return nil, err
}
}

// determine which schema version to use
schemaVersion := getSchemaVersion(opts)
Expand Down Expand Up @@ -131,6 +138,17 @@ func CreateVirtualMachineSpec(opts *VirtualMachineOptions) (*VirtualMachineSpec,
},
}

numberofdisk := len(spec.VirtualMachine.Devices.Scsi["primary"].Attachments)
for index, dataVhdPath := range opts.DataVhdPaths {
datavhdAttachment := hcsschema.Attachment{
Path: dataVhdPath,
Type_: "VirtualDisk",
}

indexKey := fmt.Sprint(numberofdisk + index)
spec.VirtualMachine.Devices.Scsi["primary"].Attachments[indexKey] = datavhdAttachment
}

if len(opts.VnicId) > 0 {
spec.VirtualMachine.Devices.NetworkAdapters["ext"] = hcsschema.NetworkAdapter{
EndpointId: opts.VnicId,
Expand Down Expand Up @@ -731,3 +749,71 @@ func getSchemaVersion(opts *VirtualMachineOptions) hcsschema.Version {
Minor: 1,
}
}

func (vm *VirtualMachineSpec) GetDiskInformation(diskPath string) (controlNumber int, err error) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

func

move these functions to line#722, keep them in group with other functions for VirtualMachineSpec.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetDiskInformation

return controller location and controller number

for key, value := range vm.spec.VirtualMachine.Devices.Scsi["primary"].Attachments {
if value.Path == diskPath {
controlNumber, err = strconv.Atoi(key)
return
}
}

return 0, errors.New("diskpath not found in attached devices")
}

func (vm *VirtualMachineSpec) AttachVhd(vhdPath string) (lun int, err error) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lun

return controller location and controller number

ctx, cancel := context.WithTimeout(context.Background(), 60*time.Minute)
defer cancel()
system, err := hcs.OpenComputeSystem(ctx, vm.ID)
if err != nil {
return 0, err
}
defer system.Close()

if err := wclayer.GrantVmAccess(vm.ID, vhdPath); err != nil {
return 0, err
}

for lun := 0; lun < 256; lun++ {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lun

why attach the same vhd from lun 0? We should find the free lun and attach the vhd using the free lun.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as far as i can tell there is no way to find the next free lun though any hcs/hcsshim calls. unless we want to make a sperate service to track the lun for each vm we create, we will have to get it through trial and error. The spec will not help us in this case since it is not stored anywhere and will not be populated if we call the GetVirtualMachineSpec function to retrieve the VirtualMachineSpec struct. I can start the lun count at 2 since 0 and 1 are required for creation.

request := hcsschema.ModifySettingRequest{
RequestType: requesttype.Add,
ResourcePath: fmt.Sprintf("VirtualMachine/Devices/Scsi/Primary/Attachments/%d", lun),
Settings: hcsschema.Attachment{
Type_: "VirtualDisk",
Path: vhdPath,
},
}
if err = system.Modify(ctx, request); err != nil {
// error caused by lun collision
if strings.Contains(err.Error(), "Unspecified error") {
continue
} else {
return 0, err
}
} else {
return lun, nil
}
}

return 0, errors.New("No available LUN for disk to be attached")
}

func (vm *VirtualMachineSpec) DetachVhd(lun int) (err error) {
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Minute)
defer cancel()
system, err := hcs.OpenComputeSystem(ctx, vm.ID)
if err != nil {
return err
}
defer system.Close()

request := hcsschema.ModifySettingRequest{
RequestType: requesttype.Remove,
ResourcePath: fmt.Sprintf("VirtualMachine/Devices/Scsi/Primary/Attachments/%d", lun),
}
if err = system.Modify(ctx, request); err != nil {
return err
}

return nil
}