Skip to content

Commit

Permalink
feat: adds GPU support to packer plugin nutanix
Browse files Browse the repository at this point in the history
  • Loading branch information
faiq committed May 2, 2024
1 parent 9a6752c commit eb801eb
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 2 deletions.
7 changes: 6 additions & 1 deletion builder/nutanix/config.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:generate packer-sdc mapstructure-to-hcl2 -type Config,Category,ClusterConfig,VmConfig,VmDisk,VmNIC
//go:generate packer-sdc mapstructure-to-hcl2 -type Config,Category,ClusterConfig,VmConfig,VmDisk,VmNIC,GPU

package nutanix

Expand Down Expand Up @@ -45,6 +45,10 @@ type Config struct {
ctx interpolate.Context
}

type GPU struct {
Name string `mapstructure:"name" json:"name" required:"false"`
}

type Category struct {
Key string `mapstructure:"key" json:"key" required:"false"`
Value string `mapstructure:"value" json:"value" required:"false"`
Expand Down Expand Up @@ -86,6 +90,7 @@ type VmConfig struct {
UserData string `mapstructure:"user_data" json:"user_data" required:"false"`
VMCategories []Category `mapstructure:"vm_categories" required:"false"`
Project string `mapstructure:"project" required:"false"`
GPU []GPU `mapstructure:"gpu" required:"false"`
}

func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
Expand Down
27 changes: 27 additions & 0 deletions builder/nutanix/config.hcl2spec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions builder/nutanix/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,37 @@ func findSubnetByName(conn *v3.Client, name string) (*v3.SubnetIntentResponse, e
return found[0], nil
}

func findGPUByName(conn *v3.Client, name string) (*v3.VMGpu, error) {
hosts, err := conn.V3.ListAllHost()
if err != nil {
return nil, err
}

for _, host := range hosts.Entities {
if host == nil ||
host.Status == nil ||
host.Status.ClusterReference == nil ||
host.Status.Resources == nil ||
len(host.Status.Resources.GPUList) == 0 {
continue
}

for _, peGpu := range host.Status.Resources.GPUList {
if peGpu == nil {
continue
}
if peGpu.Name == name {
return &v3.VMGpu{
DeviceID: peGpu.DeviceID,
Vendor: &peGpu.Vendor,
Mode: &peGpu.Mode,
}, nil
}
}
}
return nil, fmt.Errorf("failed to find GPU %s", name)
}

func sourceImageExists(conn *v3.Client, name string, uri string) (*v3.ImageIntentResponse, error) {
filter := fmt.Sprintf("name==%s", name)
resp, err := conn.V3.ListAllImage(filter)
Expand Down Expand Up @@ -441,6 +472,15 @@ func (d *NutanixDriver) CreateRequest(vm VmConfig, state multistep.StateBag) (*v
}
NICList = append(NICList, &newNIC)
}
GPUList := make([]*v3.VMGpu, 0, len(vm.GPU))
for _, gpu := range vm.GPU {
vmGPU, err := findGPUByName(conn, gpu.Name)
if err != nil {
return nil, fmt.Errorf("error while findGPUByName %s", err.Error())
}
GPUList = append(GPUList, vmGPU)
}

PowerStateOn := "ON"

cluster := &v3.ClusterIntentResponse{}
Expand All @@ -466,6 +506,7 @@ func (d *NutanixDriver) CreateRequest(vm VmConfig, state multistep.StateBag) (*v
PowerState: &PowerStateOn,
DiskList: DiskList,
NicList: NICList,
GpuList: GPUList,
},
ClusterReference: BuildReference(*cluster.Metadata.UUID, "cluster"),
Description: StringPtr(fmt.Sprintf(vmDescription, d.Config.VmConfig.ImageName)),
Expand Down
14 changes: 13 additions & 1 deletion docs/builders/nutanix.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ These parameters allow to define information about platform and temporary VM use
- `ip_wait_timeout` (duration string | ex: "0h42m0s") - Amount of time to wait for VM's IP, similar to 'ssh_timeout'. Defaults to 15m (15 minutes). See the Golang [ParseDuration](https://golang.org/pkg/time/#ParseDuration) documentation for full details.
- `vm_categories` ([]Category) - Assign Categories to the vm.
- `project` (string) - Assign Project to the vm.

- `gpu` ([] GPU) - GPU in cluster name to be attached on temporary VM.


## Output configuration
Expand Down Expand Up @@ -153,6 +153,18 @@ Sample

Note: Categories must already be present in Prism Central.

## GPU Configuration

Use `GPU` to assign a GPU that is present on `cluster-name` on the temporary vm. Add the name of the GPU you wish to attach.

Sample

```hcl
gpu {
name = "Ampere 40"
}
```

## Samples

You can find samples [here](https://github.com/nutanix-cloud-native/packer-plugin-nutanix/tree/main/example) for these instructions usage.

0 comments on commit eb801eb

Please sign in to comment.