From 59c51f6201e64e34bd6c2d476cbf9d360a36374c Mon Sep 17 00:00:00 2001 From: Bo Chen Date: Thu, 26 Aug 2021 14:01:27 -0700 Subject: [PATCH] virtcontainers: clh: Migrate to use the updated client APIs The client code (and APIs) for Cloud Hypervisor has been changed dramatically due to the upgrade to `openapi-generator` v5.2.1. This patch migrate the Cloud Hypervisor driver in the kata-runtime to use those updated APIs. The main change from the client code is that it now uses "pointer" type to represent "optional" attributes from the input openapi specification file. Signed-off-by: Bo Chen (cherry picked from commit a6a2e525deddf169a4f98c7d066a8cee9f6d3a7a) --- src/runtime/virtcontainers/clh.go | 117 ++++++++++++++++++++++-------- 1 file changed, 87 insertions(+), 30 deletions(-) diff --git a/src/runtime/virtcontainers/clh.go b/src/runtime/virtcontainers/clh.go index 3a93112540..6154464b27 100644 --- a/src/runtime/virtcontainers/clh.go +++ b/src/runtime/virtcontainers/clh.go @@ -102,6 +102,47 @@ type clhClient interface { VmRemoveDevicePut(ctx context.Context, vmRemoveDevice chclient.VmRemoveDevice) (*http.Response, error) } +type clhClientApi struct { + ApiInternal *chclient.DefaultApiService +} + +func (c *clhClientApi) VmmPingGet(ctx context.Context) (chclient.VmmPingResponse, *http.Response, error) { + return c.ApiInternal.VmmPingGet(ctx).Execute() +} + +func (c *clhClientApi) ShutdownVMM(ctx context.Context) (*http.Response, error) { + return c.ApiInternal.ShutdownVMM(ctx).Execute() +} + +func (c *clhClientApi) CreateVM(ctx context.Context, vmConfig chclient.VmConfig) (*http.Response, error) { + return c.ApiInternal.CreateVM(ctx).VmConfig(vmConfig).Execute() +} + +//nolint:golint +func (c *clhClientApi) VmInfoGet(ctx context.Context) (chclient.VmInfo, *http.Response, error) { + return c.ApiInternal.VmInfoGet(ctx).Execute() +} + +func (c *clhClientApi) BootVM(ctx context.Context) (*http.Response, error) { + return c.ApiInternal.BootVM(ctx).Execute() +} + +func (c *clhClientApi) VmResizePut(ctx context.Context, vmResize chclient.VmResize) (*http.Response, error) { + return c.ApiInternal.VmResizePut(ctx).VmResize(vmResize).Execute() +} + +func (c *clhClientApi) VmAddDevicePut(ctx context.Context, vmAddDevice chclient.VmAddDevice) (chclient.PciDeviceInfo, *http.Response, error) { + return c.ApiInternal.VmAddDevicePut(ctx).VmAddDevice(vmAddDevice).Execute() +} + +func (c *clhClientApi) VmAddDiskPut(ctx context.Context, diskConfig chclient.DiskConfig) (chclient.PciDeviceInfo, *http.Response, error) { + return c.ApiInternal.VmAddDiskPut(ctx).DiskConfig(diskConfig).Execute() +} + +func (c *clhClientApi) VmRemoveDevicePut(ctx context.Context, vmRemoveDevice chclient.VmRemoveDevice) (*http.Response, error) { + return c.ApiInternal.VmRemoveDevicePut(ctx).VmRemoveDevice(vmRemoveDevice).Execute() +} + // // Cloud hypervisor state // @@ -194,16 +235,16 @@ func (clh *cloudHypervisor) createSandbox(ctx context.Context, id string, networ // Convert to int64 openApiClient only support int64 clh.vmconfig.Memory.Size = int64((utils.MemUnit(clh.config.MemorySize) * utils.MiB).ToBytes()) // shared memory should be enabled if using vhost-user(kata uses virtiofsd) - clh.vmconfig.Memory.Shared = true + clh.vmconfig.Memory.Shared = func(b bool) *bool { return &b }(true) hostMemKb, err := getHostMemorySizeKb(procMemInfo) if err != nil { return nil } // OpenAPI only supports int64 values - clh.vmconfig.Memory.HotplugSize = int64((utils.MemUnit(hostMemKb) * utils.KiB).ToBytes()) + clh.vmconfig.Memory.HotplugSize = func(i int64) *int64 { return &i }(int64((utils.MemUnit(hostMemKb) * utils.KiB).ToBytes())) // Set initial amount of cpu's for the virtual machine - clh.vmconfig.Cpus = chclient.CpusConfig{ + clh.vmconfig.Cpus = &chclient.CpusConfig{ // cast to int32, as openAPI has a limitation that it does not support unsigned values BootVcpus: int32(clh.config.NumVCPUs), MaxVcpus: int32(clh.config.DefaultMaxVCPUs), @@ -232,7 +273,7 @@ func (clh *cloudHypervisor) createSandbox(ctx context.Context, id string, networ clh.vmconfig.Cmdline.Args = kernelParamsToString(params) // set random device generator to hypervisor - clh.vmconfig.Rng = chclient.RngConfig{ + clh.vmconfig.Rng = &chclient.RngConfig{ Src: clh.config.EntropySource, } @@ -246,33 +287,36 @@ func (clh *cloudHypervisor) createSandbox(ctx context.Context, id string, networ return errors.New("image path is empty") } - pmem := chclient.PmemConfig{ - File: imagePath, - DiscardWrites: true, + pmem := chclient.NewPmemConfig(imagePath) + *pmem.DiscardWrites = true + if clh.vmconfig.Pmem != nil { + *clh.vmconfig.Pmem = append(*clh.vmconfig.Pmem, *pmem) + } else { + clh.vmconfig.Pmem = &[]chclient.PmemConfig{*pmem} } - clh.vmconfig.Pmem = append(clh.vmconfig.Pmem, pmem) // set the serial console to the cloud hypervisor if clh.config.Debug { - clh.vmconfig.Serial = chclient.ConsoleConfig{ + clh.vmconfig.Serial = &chclient.ConsoleConfig{ Mode: cctTTY, } } else { - clh.vmconfig.Serial = chclient.ConsoleConfig{ + clh.vmconfig.Serial = &chclient.ConsoleConfig{ Mode: cctNULL, } } - clh.vmconfig.Console = chclient.ConsoleConfig{ + clh.vmconfig.Console = &chclient.ConsoleConfig{ Mode: cctOFF, } - clh.vmconfig.Cpus.Topology = chclient.CpuTopology{ - ThreadsPerCore: 1, - CoresPerDie: int32(clh.config.DefaultMaxVCPUs), - DiesPerPackage: 1, - Packages: 1, - } + cpu_topology := chclient.NewCpuTopology() + cpu_topology.ThreadsPerCore = func(i int32) *int32 { return &i }(1) + cpu_topology.CoresPerDie = func(i int32) *int32 { return &i }(int32(clh.config.DefaultMaxVCPUs)) + cpu_topology.DiesPerPackage = func(i int32) *int32 { return &i }(1) + cpu_topology.Packages = func(i int32) *int32 { return &i }(1) + clh.vmconfig.Cpus.Topology = cpu_topology + // Overwrite the default value of HTTP API socket path for cloud hypervisor apiSocketPath, err := clh.apiSocketPath(id) if err != nil { @@ -295,7 +339,9 @@ func (clh *cloudHypervisor) createSandbox(ctx context.Context, id string, networ }, } - clh.APIClient = chclient.NewAPIClient(cfg).DefaultApi + clh.APIClient = &clhClientApi{ + ApiInternal: chclient.NewAPIClient(cfg).DefaultApi, + } clh.virtiofsd = &virtiofsd{ path: clh.config.VirtioFSDaemon, @@ -309,10 +355,15 @@ func (clh *cloudHypervisor) createSandbox(ctx context.Context, id string, networ if clh.config.SGXEPCSize > 0 { epcSection := chclient.SgxEpcConfig{ Size: clh.config.SGXEPCSize, - Prefault: true, + Prefault: func(b bool) *bool { return &b }(true), + } + + if clh.vmconfig.SgxEpc != nil { + *clh.vmconfig.SgxEpc = append(*clh.vmconfig.SgxEpc, epcSection) + } else { + clh.vmconfig.SgxEpc = &[]chclient.SgxEpcConfig{epcSection} } - clh.vmconfig.SgxEpc = append(clh.vmconfig.SgxEpc, epcSection) } return nil @@ -455,9 +506,9 @@ func (clh *cloudHypervisor) hotplugAddBlockDevice(drive *config.BlockDrive) erro blkDevice := chclient.DiskConfig{ Path: drive.File, - Readonly: drive.ReadOnly, - VhostUser: false, - Id: driveID, + Readonly: &drive.ReadOnly, + VhostUser: func(b bool) *bool { return &b }(false), + Id: &driveID, } pciInfo, _, err := cl.VmAddDiskPut(ctx, blkDevice) @@ -475,7 +526,7 @@ func (clh *cloudHypervisor) hotPlugVFIODevice(device config.VFIODev) error { ctx, cancel := context.WithTimeout(context.Background(), clhHotPlugAPITimeout*time.Second) defer cancel() - _, _, err := cl.VmAddDevicePut(ctx, chclient.VmAddDevice{Path: device.SysfsDev, Id: device.ID}) + _, _, err := cl.VmAddDevicePut(ctx, chclient.VmAddDevice{Path: &device.SysfsDev, Id: &device.ID}) if err != nil { err = fmt.Errorf("Failed to hotplug device %+v %s", device, openAPIClientError(err)) } @@ -521,7 +572,7 @@ func (clh *cloudHypervisor) hotplugRemoveDevice(ctx context.Context, devInfo int ctx, cancel := context.WithTimeout(context.Background(), clhHotPlugAPITimeout*time.Second) defer cancel() - _, err := cl.VmRemoveDevicePut(ctx, chclient.VmRemoveDevice{Id: deviceID}) + _, err := cl.VmRemoveDevicePut(ctx, chclient.VmRemoveDevice{Id: &deviceID}) if err != nil { err = fmt.Errorf("failed to hotplug remove (unplug) device %+v: %s", devInfo, openAPIClientError(err)) } @@ -587,7 +638,7 @@ func (clh *cloudHypervisor) resizeMemory(ctx context.Context, reqMemMB uint32, m defer cancelResize() // OpenApi does not support uint64, convert to int64 - resize := chclient.VmResize{DesiredRam: int64(newMem.ToBytes())} + resize := chclient.VmResize{DesiredRam: func(i int64) *int64 { return &i }(int64(newMem.ToBytes()))} clh.Logger().WithFields(log.Fields{"current-memory": currentMem, "new-memory": newMem}).Debug("updating VM memory") if _, err = cl.VmResizePut(ctx, resize); err != nil { clh.Logger().WithError(err).WithFields(log.Fields{"current-memory": currentMem, "new-memory": newMem}).Warnf("failed to update memory %s", openAPIClientError(err)) @@ -629,7 +680,7 @@ func (clh *cloudHypervisor) resizeVCPUs(ctx context.Context, reqVCPUs uint32) (c // Resize (hot-plug) vCPUs via HTTP API ctx, cancel := context.WithTimeout(ctx, clhAPITimeout*time.Second) defer cancel() - if _, err = cl.VmResizePut(ctx, chclient.VmResize{DesiredVcpus: int32(reqVCPUs)}); err != nil { + if _, err = cl.VmResizePut(ctx, chclient.VmResize{DesiredVcpus: func(i int32) *int32 { return &i }(int32(reqVCPUs))}); err != nil { return currentVCPUs, newVCPUs, errors.Wrap(err, "[clh] VmResizePut failed") } @@ -1054,7 +1105,7 @@ func (clh *cloudHypervisor) addVSock(cid int64, path string) { "cid": cid, }).Info("Adding HybridVSock") - clh.vmconfig.Vsock = chclient.VsockConfig{Cid: cid, Socket: path} + clh.vmconfig.Vsock = &chclient.VsockConfig{Cid: cid, Socket: path} } func (clh *cloudHypervisor) addNet(e Endpoint) error { @@ -1076,7 +1127,13 @@ func (clh *cloudHypervisor) addNet(e Endpoint) error { "tap": tapPath, }).Info("Adding Net") - clh.vmconfig.Net = append(clh.vmconfig.Net, chclient.NetConfig{Mac: mac, Tap: tapPath}) + net := chclient.NetConfig{Mac: &mac, Tap: &tapPath} + if clh.vmconfig.Net != nil { + *clh.vmconfig.Net = append(*clh.vmconfig.Net, net) + } else { + clh.vmconfig.Net = &[]chclient.NetConfig{net} + } + return nil } @@ -1099,7 +1156,7 @@ func (clh *cloudHypervisor) addVolume(volume types.Volume) error { numQueues := int32(1) queueSize := int32(1024) - clh.vmconfig.Fs = []chclient.FsConfig{ + clh.vmconfig.Fs = &[]chclient.FsConfig{ { Tag: volume.MountTag, Socket: vfsdSockPath,