Skip to content

Commit

Permalink
Enable linked multiple flexible GPUs to VM
Browse files Browse the repository at this point in the history
fixes #220
  • Loading branch information
outscale-toa committed Oct 27, 2023
1 parent f8a63be commit 86c7570
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 114 deletions.
238 changes: 129 additions & 109 deletions outscale/resource_outscale_flexible_gpu_link.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,20 @@ func resourceOutscaleOAPIFlexibleGpuLink() *schema.Resource {
return &schema.Resource{
Create: resourceOutscaleOAPIFlexibleGpuLinkCreate,
Read: resourceOutscaleOAPIFlexibleGpuLinkRead,
Update: resourceFlexibleGpuLinkUpdate,
Delete: resourceOutscaleOAPIFlexibleGpuLinkDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"flexible_gpu_id": {
Type: schema.TypeString,
"flexible_gpu_ids": {
Type: schema.TypeSet,
Required: true,
ForceNew: true,
MinItems: 1,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"vm_id": {
Type: schema.TypeString,
Expand All @@ -42,61 +46,31 @@ func resourceOutscaleOAPIFlexibleGpuLink() *schema.Resource {

func resourceOutscaleOAPIFlexibleGpuLinkCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*OutscaleClient).OSCAPI

flexGpuID := d.Get("flexible_gpu_id").(string)
vmId := d.Get("vm_id").(string)
GpuIdsList := utils.SetToStringSlice(d.Get("flexible_gpu_ids").(*schema.Set))

filter := &oscgo.FiltersFlexibleGpu{
FlexibleGpuIds: &[]string{flexGpuID},
}
reqFlex := &oscgo.ReadFlexibleGpusRequest{
Filters: filter,
}
reqLink := oscgo.LinkFlexibleGpuRequest{
FlexibleGpuId: flexGpuID,
VmId: vmId,
}
var resp oscgo.LinkFlexibleGpuResponse
err := resource.Retry(60*time.Second, func() *resource.RetryError {
var err error
rp, httpResp, err := conn.FlexibleGpuApi.LinkFlexibleGpu(
context.Background()).LinkFlexibleGpuRequest(reqLink).Execute()
if err != nil {
return utils.CheckThrottling(httpResp, err)
for _, flexGpuID := range GpuIdsList {
var resp oscgo.LinkFlexibleGpuResponse
reqLink := oscgo.LinkFlexibleGpuRequest{
FlexibleGpuId: flexGpuID,
VmId: vmId,
}
resp = rp
return nil
})

if err != nil {
return fmt.Errorf("Error Link flexibe gpu: %s", err.Error())
}

if !resp.HasResponseContext() {
return fmt.Errorf("Error there is not Link flexible gpu (%s)", err)
}

var respV oscgo.ReadFlexibleGpusResponse
err = resource.Retry(60*time.Second, func() *resource.RetryError {
rp, httpResp, err := conn.FlexibleGpuApi.ReadFlexibleGpus(context.Background()).
ReadFlexibleGpusRequest(*reqFlex).Execute()
err := resource.Retry(60*time.Second, func() *resource.RetryError {
var err error
rp, httpResp, err := conn.FlexibleGpuApi.LinkFlexibleGpu(
context.Background()).LinkFlexibleGpuRequest(reqLink).Execute()
if err != nil {
return utils.CheckThrottling(httpResp, err)
}
resp = rp
return nil
})
if err != nil {
return utils.CheckThrottling(httpResp, err)
return fmt.Errorf("Error Link flexibe gpu: %s", err.Error())
}
if !resp.HasResponseContext() {
return fmt.Errorf("Error there is not Link flexible gpu (%s)", err)
}
respV = rp
return nil
})

if err != nil {
return fmt.Errorf("error reading the FlexibleGpu %s", err)
}

if err := utils.IsResponseEmptyOrMutiple(len(respV.GetFlexibleGpus()), "FlexibleGpu"); err != nil {
return err
}

if (*respV.FlexibleGpus)[0].GetState() != "attaching" {
return fmt.Errorf("Unable to link Flexible GPU")
}

if err := changeShutdownBehavior(conn, vmId); err != nil {
Expand All @@ -108,19 +82,15 @@ func resourceOutscaleOAPIFlexibleGpuLinkCreate(d *schema.ResourceData, meta inte

func resourceOutscaleOAPIFlexibleGpuLinkRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*OutscaleClient).OSCAPI

flexGpuID := d.Get("flexible_gpu_id").(string)
if flexGpuID == "" {
flexGpuID = d.Id()
}
vmId := d.Get("vm_id").(string)
req := &oscgo.ReadFlexibleGpusRequest{
Filters: &oscgo.FiltersFlexibleGpu{
FlexibleGpuIds: &[]string{flexGpuID},
VmIds: &[]string{vmId},
},
}

var resp oscgo.ReadFlexibleGpusResponse
var err error

err = resource.Retry(60*time.Second, func() *resource.RetryError {
rp, httpResp, err := conn.FlexibleGpuApi.ReadFlexibleGpus(
context.Background()).
Expand All @@ -139,82 +109,132 @@ func resourceOutscaleOAPIFlexibleGpuLinkRead(d *schema.ResourceData, meta interf
d.SetId("")
return nil
}

fg := (*resp.FlexibleGpus)[0]
if err := d.Set("flexible_gpu_id", fg.GetFlexibleGpuId()); err != nil {
flexGpus := resp.GetFlexibleGpus()[:]
readGpuIdsLink := make([]string, len(flexGpus))
for k, flexGpu := range flexGpus {
readGpuIdsLink[k] = flexGpu.GetFlexibleGpuId()
}
if err := d.Set("flexible_gpu_ids", readGpuIdsLink); err != nil {
return err
}
if err := d.Set("vm_id", fg.GetVmId()); err != nil {
if err := d.Set("vm_id", vmId); err != nil {
return err
}
d.SetId(fg.GetFlexibleGpuId())

d.SetId(resource.UniqueId())
return nil
}

func resourceOutscaleOAPIFlexibleGpuLinkDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*OutscaleClient).OSCAPI

flexGpuID := d.Get("flexible_gpu_id").(string)
vmId := d.Get("vm_id").(string)

filter := &oscgo.FiltersFlexibleGpu{
FlexibleGpuIds: &[]string{flexGpuID},
}
reqFlex := &oscgo.ReadFlexibleGpusRequest{
Filters: filter,
}

req := &oscgo.UnlinkFlexibleGpuRequest{
FlexibleGpuId: flexGpuID,
}

GpuIdsList := utils.SetToStringSlice(d.Get("flexible_gpu_ids").(*schema.Set))
var err error
err = resource.Retry(20*time.Second, func() *resource.RetryError {
_, httpResp, err := conn.FlexibleGpuApi.UnlinkFlexibleGpu(
context.Background()).UnlinkFlexibleGpuRequest(*req).Execute()

for _, flexGpuID := range GpuIdsList {
req := &oscgo.UnlinkFlexibleGpuRequest{
FlexibleGpuId: flexGpuID,
}
err = resource.Retry(20*time.Second, func() *resource.RetryError {
_, httpResp, err := conn.FlexibleGpuApi.UnlinkFlexibleGpu(
context.Background()).UnlinkFlexibleGpuRequest(*req).Execute()
if err != nil {
return utils.CheckThrottling(httpResp, err)
}
return nil
})
if err != nil {
return utils.CheckThrottling(httpResp, err)
return err
}
return nil
})

if err != nil {
return err
}

var resp oscgo.ReadFlexibleGpusResponse
err = resource.Retry(60*time.Second, func() *resource.RetryError {
rp, httpResp, err := conn.FlexibleGpuApi.ReadFlexibleGpus(context.Background()).
ReadFlexibleGpusRequest(*reqFlex).Execute()
var resp oscgo.ReadFlexibleGpusResponse
reqFlex := &oscgo.ReadFlexibleGpusRequest{
Filters: &oscgo.FiltersFlexibleGpu{
FlexibleGpuIds: &[]string{flexGpuID},
},
}
err = resource.Retry(60*time.Second, func() *resource.RetryError {
rp, httpResp, err := conn.FlexibleGpuApi.ReadFlexibleGpus(context.Background()).
ReadFlexibleGpusRequest(*reqFlex).Execute()
if err != nil {
return utils.CheckThrottling(httpResp, err)
}
resp = rp
return nil
})
if err != nil {
return utils.CheckThrottling(httpResp, err)
return fmt.Errorf("error reading the FlexibleGpu %s", err)
}
resp = rp
return nil
})
if err != nil {
return fmt.Errorf("error reading the FlexibleGpu %s", err)
}

if len(*resp.FlexibleGpus) != 1 {
return fmt.Errorf("Unable to find Flexible GPU")
}
if (*resp.FlexibleGpus)[0].GetState() != "detaching" {
return fmt.Errorf("Unable to unlink Flexible GPU")
if len(*resp.FlexibleGpus) != 1 {
return fmt.Errorf("Unable to find Flexible GPU")
}
if (*resp.FlexibleGpus)[0].GetState() != "detaching" {
return fmt.Errorf("Unable to unlink Flexible GPU")
}
}

if err := changeShutdownBehavior(conn, vmId); err != nil {
if err := changeShutdownBehavior(conn, d.Get("vm_id").(string)); err != nil {
return fmt.Errorf("Unable to change ShutdownBehavior: %s\n", err)
}

d.SetId("")
return nil
}

func resourceFlexibleGpuLinkUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*OutscaleClient).OSCAPI
vmId := d.Get("vm_id").(string)
oldIds, newIds := d.GetChange("flexible_gpu_ids")

interIds := oldIds.(*schema.Set).Intersection(newIds.(*schema.Set))
toCreate := newIds.(*schema.Set).Difference(interIds)
toRemove := oldIds.(*schema.Set).Difference(interIds)
var err error

if toRemove.Len() > 0 {
for _, flexGpuID := range utils.SetToStringSlice(toRemove) {
req := &oscgo.UnlinkFlexibleGpuRequest{
FlexibleGpuId: flexGpuID,
}
err = resource.Retry(20*time.Second, func() *resource.RetryError {
_, httpResp, err := conn.FlexibleGpuApi.UnlinkFlexibleGpu(
context.Background()).UnlinkFlexibleGpuRequest(*req).Execute()
if err != nil {
return utils.CheckThrottling(httpResp, err)
}
return nil
})
if err != nil {
return err
}
}
}
if toCreate.Len() > 0 {
for _, flexGpuID := range utils.SetToStringSlice(toCreate) {
req := &oscgo.LinkFlexibleGpuRequest{
FlexibleGpuId: flexGpuID,
VmId: vmId,
}
err = resource.Retry(20*time.Second, func() *resource.RetryError {
_, httpResp, err := conn.FlexibleGpuApi.LinkFlexibleGpu(
context.Background()).LinkFlexibleGpuRequest(*req).Execute()
if err != nil {
return utils.CheckThrottling(httpResp, err)
}
return nil
})
if err != nil {
return err
}
}
}
if err := changeShutdownBehavior(conn, vmId); err != nil {
return fmt.Errorf("Unable to change ShutdownBehavior: %s\n", err)
}

return resourceOutscaleOAPIFlexibleGpuLinkRead(d, meta)
}

func changeShutdownBehavior(conn *oscgo.APIClient, vmId string) error {

var resp oscgo.ReadVmsResponse
err := resource.Retry(20*time.Second, func() *resource.RetryError {
rp, httpResp, err := conn.VmApi.ReadVms(context.Background()).ReadVmsRequest(oscgo.ReadVmsRequest{
Expand Down
14 changes: 9 additions & 5 deletions outscale/resource_outscale_flexible_gpu_link_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,21 @@ func testAccOutscaleOAPIFlexibleGpuLinkConfig(omi, vmType, region string) string
}
resource "outscale_flexible_gpu" "fGPU-1" {
resource "outscale_flexible_gpu" "fGPU-1" {
model_name = "nvidia-p6"
generation = "v5"
subregion_name = "%[3]sa"
subregion_name = "%[3]s"
delete_on_vm_deletion = true
}
resource "outscale_flexible_gpu" "fGPU-2" {
model_name = "nvidia-p6"
generation = "v5"
subregion_name = "%[3]s"
delete_on_vm_deletion = true
}
resource "outscale_flexible_gpu_link" "link_fGPU" {
flexible_gpu_id = outscale_flexible_gpu.fGPU-1.flexible_gpu_id
flexible_gpu_ids = [outscale_flexible_gpu.fGPU-1.flexible_gpu_id,outscale_flexible_gpu.fGPU-2.flexible_gpu_id]
vm_id = outscale_vm.basic.vm_id
}
`, omi, vmType, region)
}

0 comments on commit 86c7570

Please sign in to comment.