Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VM, NIC and disk hydration #225

Open
wants to merge 38 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
edc6710
Draft of adding hydration
mduppre Feb 21, 2024
2b8694e
Comment out settings that are null
mduppre Mar 20, 2024
a18e826
Merge pull request #207 from microsoft/users/mduppre/CloudAgentVmHydr…
mduppre Mar 25, 2024
d24c670
add vm discovery for cloudagent
katl-msft Apr 4, 2024
608350f
Temporarily use VirtualMachineDiscovery
mduppre Apr 4, 2024
099919a
Comment out placeholder data that we're not populating in nodeagent
mduppre Apr 4, 2024
5d1210c
Merge pull request #227 from microsoft/users/katlynho/VmHydration
katl-msft Apr 4, 2024
569d24a
fix crash in mocctl show, need to uncomment other fields
neerajdixit-msft2 Apr 23, 2024
1c755a5
uncomment all fields in VM protobuf
neerajdixit-msft2 May 2, 2024
57c4696
Merge pull request #231 from microsoft/users/ndixit/CloudAgentBugFixes
neerajdixit-msft2 May 2, 2024
8205d42
OS data changes
neerajdixit-msft2 May 31, 2024
91edfd2
Draft of adding hydration
mduppre Feb 21, 2024
01d0f62
Comment out settings that are null
mduppre Mar 20, 2024
0c84f62
add vm discovery for cloudagent
katl-msft Apr 4, 2024
02f6808
Temporarily use VirtualMachineDiscovery
mduppre Apr 4, 2024
390f041
Comment out placeholder data that we're not populating in nodeagent
mduppre Apr 4, 2024
75ad9c6
fix crash in mocctl show, need to uncomment other fields
neerajdixit-msft2 Apr 23, 2024
9a8dfb1
uncomment all fields in VM protobuf
neerajdixit-msft2 May 2, 2024
cde427c
OS data changes
neerajdixit-msft2 May 31, 2024
1784116
Merge branch 'users/trailblazer/VmHydration' into users/trailblazer/r…
mduppre Jun 24, 2024
dd89941
Merge pull request #243 from microsoft/users/trailblazer/rebase0618
mduppre Jun 24, 2024
ac865c7
hydrate network as a separate process from vm hydration (#251)
katl-msft Jul 29, 2024
81d9611
Merge branch 'main' into users/trailblazer/VmHydration
yingzhan-msft Jul 29, 2024
05b8e88
remove discovery code
yingzhan-msft Jul 30, 2024
619c29d
data disk hydration draft
katl-msft Aug 1, 2024
8ae1c89
Revert accidentally checked in go.mod and go.sum
mduppre Aug 12, 2024
ed947d7
Try again with updated pull from target branch
mduppre Aug 12, 2024
aa796c8
Add more comments
mduppre Aug 12, 2024
cd60bd2
MOC sdk API change to include VM structure
neerajdixit-msft2 Aug 13, 2024
a191eb1
disk hydration
yingzhan-msft Aug 15, 2024
8fa55a9
Merge branch 'users/trailblazer/VmHydration' into users/katlynho/data…
mduppre Aug 21, 2024
1e31171
Merge pull request #256 from microsoft/users/katlynho/datadisk-hydration
mduppre Aug 21, 2024
71c6ebc
Merge branch 'main' into users/trailblazer/VmHydration
mduppre Sep 6, 2024
3c99cc9
Add hydrated as a bootstrapengine state
mduppre Sep 22, 2024
1809ecf
Merge pull request #268 from microsoft/users/mduppre/bug_fix
mduppre Sep 27, 2024
4d2fbaf
Merge branch 'main' into users/ndixit/MasterMerge1030
neerajdixit-msft2 Oct 30, 2024
c8364e6
change VHD get type
neerajdixit-msft2 Oct 30, 2024
c61eb10
Merge pull request #288 from microsoft/users/ndixit/MasterMerge1030
neerajdixit-msft2 Oct 31, 2024
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
1 change: 1 addition & 0 deletions services/compute/compute.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type OperatingSystemBootstrapEngine string
const (
CloudInit OperatingSystemBootstrapEngine = "CloudInit"
WindowsAnswerFiles OperatingSystemBootstrapEngine = "WindowsAnswerFiles"
Hydrated OperatingSystemBootstrapEngine = "Hydrated"
)

type VMType string
Expand Down
6 changes: 6 additions & 0 deletions services/compute/virtualmachine/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
type Service interface {
Get(context.Context, string, string) (*[]compute.VirtualMachine, error)
CreateOrUpdate(context.Context, string, string, *compute.VirtualMachine) (*compute.VirtualMachine, error)
Hydrate(context.Context, string, string, *compute.VirtualMachine) (*compute.VirtualMachine, error)
Delete(context.Context, string, string) error
Query(context.Context, string, string) (*[]compute.VirtualMachine, error)
Start(context.Context, string, string) error
Expand Down Expand Up @@ -60,6 +61,11 @@ func (c *VirtualMachineClient) CreateOrUpdate(ctx context.Context, group, name s
return c.internal.CreateOrUpdate(ctx, group, name, compute)
}

// Hydrate methods creates MOC representation of the VM resource
func (c *VirtualMachineClient) Hydrate(ctx context.Context, group, name string, compute *compute.VirtualMachine) (*compute.VirtualMachine, error) {
return c.internal.Hydrate(ctx, group, name, compute)
}

// Delete methods invokes delete of the compute resource
func (c *VirtualMachineClient) Delete(ctx context.Context, group string, name string) error {
return c.internal.Delete(ctx, group, name)
Expand Down
37 changes: 31 additions & 6 deletions services/compute/virtualmachine/virtualmachine.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package virtualmachine

import (
"github.com/google/go-cmp/cmp"
"github.com/microsoft/moc-sdk-for-go/services/compute"
"github.com/microsoft/moc/pkg/convert"
"github.com/microsoft/moc/pkg/errors"
Expand Down Expand Up @@ -555,13 +556,23 @@ func (c *client) getWssdVirtualMachineProxyConfiguration(proxyConfig *compute.Pr

// Conversion functions from wssdcloudcompute to compute

func (c *client) getVirtualMachine(vm *wssdcloudcompute.VirtualMachine, group string) *compute.VirtualMachine {
func (c *client) getVirtualMachine(vm *wssdcloudcompute.VirtualMachine) *compute.VirtualMachine {
if vm == nil {
return &compute.VirtualMachine{}
}

vmtype := compute.Tenant
if vm.VmType == wssdcloudcompute.VMType_LOADBALANCER {
vmtype = compute.LoadBalancer
} else if vm.VmType == wssdcloudcompute.VMType_STACKEDCONTROLPLANE {
vmtype = compute.StackedControlPlane
}

version := ""
if vm.Status != nil && vm.Status.Version != nil {
version = vm.Status.Version.Number
}

return &compute.VirtualMachine{
Name: &vm.Name,
ID: &vm.Id,
Expand All @@ -583,7 +594,7 @@ func (c *client) getVirtualMachine(vm *wssdcloudcompute.VirtualMachine, group st
Host: c.getVirtualMachineHostDescription(vm),
ZoneConfiguration: c.getZoneConfiguration(vm.ZoneConfiguration),
},
Version: &vm.Status.Version.Number,
Version: &version,
Location: &vm.LocationName,
}
}
Expand Down Expand Up @@ -744,6 +755,10 @@ func (c *client) getVirtualMachineNetworkProfile(n *wssdcloudcompute.NetworkConf
NetworkInterfaces: &[]compute.NetworkInterfaceReference{},
}

if n == nil {
return np
}

for _, nic := range n.Interfaces {
if nic == nil {
continue
Expand Down Expand Up @@ -793,12 +808,12 @@ func (c *client) getVirtualMachineGuestInstanceView(g *wssdcommon.VirtualMachine
}

func (c *client) getVirtualMachineWindowsConfiguration(windowsConfiguration *wssdcloudcompute.WindowsConfiguration) *compute.WindowsConfiguration {
wc := &compute.WindowsConfiguration{
RDP: &compute.RDPConfiguration{},
if windowsConfiguration == nil || cmp.Equal(windowsConfiguration, wssdcloudcompute.WindowsConfiguration{}) {
return nil
}

if windowsConfiguration == nil {
return wc
wc := &compute.WindowsConfiguration{
RDP: &compute.RDPConfiguration{},
}

if windowsConfiguration.WinRMConfiguration != nil && len(windowsConfiguration.WinRMConfiguration.Listeners) >= 1 {
Expand Down Expand Up @@ -830,6 +845,10 @@ func (c *client) getVirtualMachineWindowsConfiguration(windowsConfiguration *wss
}

func (c *client) getVirtualMachineLinuxConfiguration(linuxConfiguration *wssdcloudcompute.LinuxConfiguration) *compute.LinuxConfiguration {
if linuxConfiguration == nil || cmp.Equal(linuxConfiguration, wssdcloudcompute.LinuxConfiguration{}) {
return nil
}

lc := &compute.LinuxConfiguration{}

if linuxConfiguration != nil {
Expand Down Expand Up @@ -860,6 +879,10 @@ func (c *client) getInstanceViewStatus(status *wssdcommon.InstanceViewStatus) *c
}

func (c *client) getVirtualMachineOSProfile(o *wssdcloudcompute.OperatingSystemConfiguration) *compute.OSProfile {
if o == nil {
return &compute.OSProfile{}
}

osType := compute.Windows
switch o.Ostype {
case wssdcommon.OperatingSystemType_LINUX:
Expand All @@ -870,6 +893,8 @@ func (c *client) getVirtualMachineOSProfile(o *wssdcloudcompute.OperatingSystemC

osBootstrapEngine := compute.CloudInit
switch o.OsBootstrapEngine {
case wssdcommon.OperatingSystemBootstrapEngine_HYDRATED:
osBootstrapEngine = compute.Hydrated
case wssdcommon.OperatingSystemBootstrapEngine_WINDOWS_ANSWER_FILES:
osBootstrapEngine = compute.WindowsAnswerFiles
case wssdcommon.OperatingSystemBootstrapEngine_CLOUD_INIT:
Expand Down
20 changes: 19 additions & 1 deletion services/compute/virtualmachine/wssd.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,24 @@ func (c *client) CreateOrUpdate(ctx context.Context, group, name string, sg *com
return &(*vms)[0], nil
}

// Hydrate
func (c *client) Hydrate(ctx context.Context, group, name string, sg *compute.VirtualMachine) (*compute.VirtualMachine, error) {
request, err := c.getVirtualMachineRequest(wssdcloudproto.Operation_HYDRATE, group, name, sg)
if err != nil {
return nil, err
}
response, err := c.VirtualMachineAgentClient.Invoke(ctx, request)
if err != nil {
return nil, err
}
vms := c.getVirtualMachineFromResponse(response, group)
if len(*vms) == 0 {
return nil, fmt.Errorf("hydration of Virtual Machine failed to unknown reason")
}

return &(*vms)[0], nil
}

// Delete methods invokes create or update on the client
func (c *client) Delete(ctx context.Context, group, name string) error {
vm, err := c.Get(ctx, group, name)
Expand Down Expand Up @@ -327,7 +345,7 @@ func (c *client) getVirtualMachineRunCommandResponse(mocResponse *wssdcloudcompu
func (c *client) getVirtualMachineFromResponse(response *wssdcloudcompute.VirtualMachineResponse, group string) *[]compute.VirtualMachine {
vms := []compute.VirtualMachine{}
for _, vm := range response.GetVirtualMachines() {
vms = append(vms, *(c.getVirtualMachine(vm, group)))
vms = append(vms, *(c.getVirtualMachine(vm)))
}

return &vms
Expand Down
6 changes: 6 additions & 0 deletions services/network/networkinterface/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
type Service interface {
Get(context.Context, string, string) (*[]network.Interface, error)
CreateOrUpdate(context.Context, string, string, *network.Interface) (*network.Interface, error)
Hydrate(context.Context, string, string, *network.Interface) (*network.Interface, error)
Delete(context.Context, string, string) error
Precheck(ctx context.Context, group string, networkInterfaces []*network.Interface) (bool, error)
}
Expand Down Expand Up @@ -44,6 +45,11 @@ func (c *InterfaceClient) CreateOrUpdate(ctx context.Context, group, name string
return c.internal.CreateOrUpdate(ctx, group, name, networkInterface)
}

// Hydrate methods invokes hydrate on the client
func (c *InterfaceClient) Hydrate(ctx context.Context, group, name string, networkInterface *network.Interface) (*network.Interface, error) {
return c.internal.Hydrate(ctx, group, name, networkInterface)
}

// Delete methods invokes delete of the network interface resource
func (c *InterfaceClient) Delete(ctx context.Context, group, name string) error {
return c.internal.Delete(ctx, group, name)
Expand Down
11 changes: 10 additions & 1 deletion services/network/networkinterface/networkinterface.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,15 +148,24 @@ func getWssdNetworkInterfaceIPConfig(ipConfig *network.InterfaceIPConfiguration,

// Conversion function from wssdcloud network interface to network interface
func getNetworkInterface(server, group string, c *wssdcloudnetwork.NetworkInterface) (*network.Interface, error) {
if c == nil {
return &network.Interface{}, nil
}

ipConfigs := []network.InterfaceIPConfiguration{}
for _, wssdipconfig := range c.IpConfigurations {
ipConfigs = append(ipConfigs, *(getNetworkIpConfig(wssdipconfig)))
}

version := ""
if c.Status != nil && c.Status.Version != nil {
version = c.Status.Version.Number
}

vnetIntf := &network.Interface{
Name: &c.Name,
ID: &c.Id,
Version: &c.Status.Version.Number,
Version: &version,
InterfacePropertiesFormat: &network.InterfacePropertiesFormat{
MacAddress: &c.Macaddress,
// TODO: Type
Expand Down
18 changes: 18 additions & 0 deletions services/network/networkinterface/wssd.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,24 @@ func (c *client) CreateOrUpdate(ctx context.Context, group, name string, vnetInt
return &(*vnets)[0], nil
}

// Hydrate
func (c *client) Hydrate(ctx context.Context, group, name string, networkInterface *network.Interface) (*network.Interface, error) {
request, err := c.getNetworkInterfaceRequest(wssdcloudcommon.Operation_HYDRATE, group, name, networkInterface)
if err != nil {
return nil, err
}
response, err := c.NetworkInterfaceAgentClient.Invoke(ctx, request)
if err != nil {
return nil, err
}
vnics, err := c.getInterfacesFromResponse(group, response)
if err != nil {
return nil, err
}

return &(*vnics)[0], nil
}

// Delete methods invokes create or update on the client
func (c *client) Delete(ctx context.Context, group, name string) error {
vnetInterface, err := c.Get(ctx, group, name)
Expand Down
8 changes: 8 additions & 0 deletions services/storage/virtualharddisk/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
// Service interface
type Service interface {
Get(context.Context, string, string, string) (*[]storage.VirtualHardDisk, error)
Hydrate(context.Context, string, string, string, *storage.VirtualHardDisk) (*storage.VirtualHardDisk, error)
CreateOrUpdate(context.Context, string, string, string, *storage.VirtualHardDisk, string, common.ImageSource) (*storage.VirtualHardDisk, error)
Delete(context.Context, string, string, string) error
Precheck(context.Context, string, string, []*storage.VirtualHardDisk) (bool, error)
Expand Down Expand Up @@ -48,6 +49,13 @@ func (c *VirtualHardDiskClient) CreateOrUpdate(ctx context.Context, group, conta
return c.internal.CreateOrUpdate(ctx, group, container, name, storage, "", common.ImageSource_LOCAL_SOURCE)
}

// The entry point for the hydrate call takes the group name, container name and the name of the disk file. The group is standard input for every call.
// Ultimately, we need the full path on disk to the disk file which we assemble from the path of the container plus the file name of the disk.
// (e.g. "C:\ClusterStorage\Userdata_1\abc123" for the container path and "my_disk.vhd" for the disk name)
func (c *VirtualHardDiskClient) Hydrate(ctx context.Context, group, container, name string, storage *storage.VirtualHardDisk) (*storage.VirtualHardDisk, error) {
return c.internal.Hydrate(ctx, group, container, name, storage)
}

// Delete methods invokes delete of the storage resource
func (c *VirtualHardDiskClient) Delete(ctx context.Context, group, container, name string) error {
return c.internal.Delete(ctx, group, container, name)
Expand Down
23 changes: 22 additions & 1 deletion services/storage/virtualharddisk/wssd.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,35 @@ func (c *client) CreateOrUpdate(ctx context.Context, group, container, name stri
return &((*vhds)[0]), nil
}

// The hydrate call takes the group name, container name and the name of the disk file. The group is standard input for every call.
// Ultimately, we need the full path on disk to the disk file which we assemble from the path of the container plus the file name of the disk.
// (e.g. "C:\ClusterStorage\Userdata_1\abc123" for the container path and "my_disk.vhd" for the disk name)
func (c *client) Hydrate(ctx context.Context, group, container, name string, vhd *storage.VirtualHardDisk) (*storage.VirtualHardDisk, error) {
request, err := getVirtualHardDiskRequest(wssdcloudcommon.Operation_HYDRATE, group, container, name, vhd, "", common.ImageSource_LOCAL_SOURCE)
if err != nil {
return nil, err
}
response, err := c.VirtualHardDiskAgentClient.Invoke(ctx, request)
if err != nil {
return nil, err
}
vhds := getVirtualHardDisksFromResponse(response, group)

if len(*vhds) == 0 {
return nil, fmt.Errorf("[VirtualHardDisk][Hydrate] Unexpected error: Hydrating a storage interface returned no result")
}

return &((*vhds)[0]), nil
}

// Delete methods invokes create or update on the client
func (c *client) Delete(ctx context.Context, group, container, name string) error {
vhd, err := c.Get(ctx, group, container, name)
if err != nil {
return err
}
if len(*vhd) == 0 {
return fmt.Errorf("Virtual Network [%s] not found", name)
return fmt.Errorf("[VirtualHardDisk][Delete] %s: not found", name)
}

request, err := getVirtualHardDiskRequest(wssdcloudcommon.Operation_DELETE, group, container, name, &(*vhd)[0], "", common.ImageSource_LOCAL_SOURCE)
Expand Down
Loading