Skip to content

Commit

Permalink
add isWaitForPIInstanceShutoff
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelkad committed Jan 23, 2024
1 parent 7e7f663 commit 1bff930
Showing 1 changed file with 71 additions and 16 deletions.
87 changes: 71 additions & 16 deletions ibm/service/power/resource_ibm_pi_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,33 +392,50 @@ func resourceIBMPIInstanceCreate(ctx context.Context, d *schema.ResourceData, me
d.SetId(fmt.Sprintf("%s/%s", cloudInstanceID, *(*pvmList)[0].PvmInstanceID))

for _, s := range *pvmList {
_, err = isWaitForPIInstanceAvailable(ctx, client, *s.PvmInstanceID, instanceReadyStatus)
if err != nil {
return diag.FromErr(err)
if dt, ok := d.GetOk(PIInstanceDeploymentType); ok && dt.(string) == "VMNoStorage" {
_, err = isWaitForPIInstanceShutoff(ctx, client, *s.PvmInstanceID, instanceReadyStatus)
if err != nil {
return diag.FromErr(err)
}
} else {
_, err = isWaitForPIInstanceAvailable(ctx, client, *s.PvmInstanceID, instanceReadyStatus)
if err != nil {
return diag.FromErr(err)
}
}

}
body := &models.PVMInstanceUpdate{}
if vod, ok := d.GetOk(PIVirtualOpticalDevice); ok {
body.CloudInitialization.VirtualOpticalDevice = vod.(string)
}

// If Storage Pool Affinity is given as false we need to update the vm instance.
// Default value is true which indicates that all volumes attached to the server
// must reside in the same storage pool.
storagePoolAffinity := d.Get(PIInstanceStoragePoolAffinity).(bool)
if !storagePoolAffinity {
body.StoragePoolAffinity = &storagePoolAffinity
}

if !storagePoolAffinity || body.CloudInitialization.VirtualOpticalDevice != "" {
for _, s := range *pvmList {

body := &models.PVMInstanceUpdate{
StoragePoolAffinity: &storagePoolAffinity,
}
// This is a synchronous process hence no need to check for health status
_, err = client.Update(*s.PvmInstanceID, body)
if err != nil {
return diag.FromErr(err)
}
}
}
// If virtual optical device provided then update cloud initialization
if vod, ok := d.GetOk(PIVirtualOpticalDevice); ok {
for _, s := range *pvmList {
body := &models.PVMInstanceUpdate{
CloudInitialization: &models.CloudInitialization{
VirtualOpticalDevice: vod.(string),
},
}
_, err = client.Update(*s.PvmInstanceID, body)
if err != nil {
return diag.FromErr(err)
}
}
}

return resourceIBMPIInstanceRead(ctx, d, meta)

Expand Down Expand Up @@ -505,7 +522,6 @@ func resourceIBMPIInstanceRead(ctx context.Context, d *schema.ResourceData, meta
d.Set("min_virtual_cores", powervmdata.VirtualCores.Min)
}
d.Set(helpers.PIInstanceLicenseRepositoryCapacity, powervmdata.LicenseRepositoryCapacity)
d.Set(PIInstanceDeploymentType, powervmdata.DeploymentType)

return nil
}
Expand Down Expand Up @@ -855,9 +871,6 @@ func isPIInstanceRefreshFunc(client *st.IBMPIInstanceClient, id, instanceReadySt
if err != nil {
return nil, "", err
}
if *pvm.Status == "SHUTOFF" && (pvm.Health.Status == instanceReadyStatus || pvm.Health.Status == helpers.PIInstanceHealthOk) {
return pvm, StatusShutoff, nil
}
// Check for `instanceReadyStatus` health status and also the final health status "OK"
if *pvm.Status == helpers.PIInstanceAvailable && (pvm.Health.Status == instanceReadyStatus || pvm.Health.Status == helpers.PIInstanceHealthOk) {
return pvm, helpers.PIInstanceAvailable, nil
Expand All @@ -875,6 +888,48 @@ func isPIInstanceRefreshFunc(client *st.IBMPIInstanceClient, id, instanceReadySt
}
}

func isWaitForPIInstanceShutoff(ctx context.Context, client *st.IBMPIInstanceClient, id string, instanceReadyStatus string) (interface{}, error) {
log.Printf("Waiting for PIInstance (%s) to be shutoff and health active ", id)

queryTimeOut := activeTimeOut
if instanceReadyStatus == helpers.PIInstanceHealthWarning {
queryTimeOut = warningTimeOut
}

stateConf := &resource.StateChangeConf{
Pending: []string{StatusPending, helpers.PIInstanceBuilding, helpers.PIInstanceHealthWarning},
Target: []string{helpers.PIInstanceHealthOk, StatusError, "", StatusShutoff},
Refresh: isPIInstanceShutoffRefreshFunc(client, id, instanceReadyStatus),
Delay: 30 * time.Second,
MinTimeout: queryTimeOut,
Timeout: 120 * time.Minute,
}

return stateConf.WaitForStateContext(ctx)
}
func isPIInstanceShutoffRefreshFunc(client *st.IBMPIInstanceClient, id, instanceReadyStatus string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {

pvm, err := client.Get(id)
if err != nil {
return nil, "", err
}
if *pvm.Status == StatusShutoff && (pvm.Health.Status == instanceReadyStatus || pvm.Health.Status == helpers.PIInstanceHealthOk) {
return pvm, StatusShutoff, nil
}
if *pvm.Status == StatusError {
if pvm.Fault != nil {
err = fmt.Errorf("failed to create the lpar: %s", pvm.Fault.Message)
} else {
err = fmt.Errorf("failed to create the lpar")
}
return pvm, *pvm.Status, err
}

return pvm, helpers.PIInstanceBuilding, nil
}
}

// This function takes the input string and encodes into base64 if isn't already encoded
func encodeBase64(userData string) string {
_, err := base64.StdEncoding.DecodeString(userData)
Expand Down

0 comments on commit 1bff930

Please sign in to comment.