Skip to content

Commit

Permalink
Refine instance update (#353)
Browse files Browse the repository at this point in the history
  • Loading branch information
karencfv authored Oct 3, 2024
1 parent 10ab870 commit d85888a
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 26 deletions.
2 changes: 1 addition & 1 deletion docs/resources/oxide_instance.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ page_title: "oxide_instance Resource - terraform-provider-oxide"

This resource manages instances.

-> Boot disk updates will stop and reboot the instance.
-> Boot disk, disk attachment, and network interface updates will stop and reboot the instance.

-> When setting a boot disk, the boot disk ID should also be included as part of `disk_attachments`.

Expand Down
61 changes: 40 additions & 21 deletions internal/provider/resource_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,28 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques
ctx, cancel := context.WithTimeout(ctx, updateTimeout)
defer cancel()

// The instance must be stopped for all updates
stopParams := oxide.InstanceStopParams{
Instance: oxide.NameOrId(state.ID.ValueString()),
}
_, err := r.client.InstanceStop(ctx, stopParams)
if err != nil {
if !is404(err) {
resp.Diagnostics.AddError(
"Unable to stop instance:",
"API error: "+err.Error(),
)
return
}
}

diags = waitForInstanceStop(ctx, r.client, updateTimeout, state.ID.ValueString())
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
tflog.Trace(ctx, fmt.Sprintf("stopped instance with ID: %v", state.ID.ValueString()), map[string]any{"success": true})

// Update disk attachments
//
// We attach new disks first in case the new boot disk is one of the newly added
Expand All @@ -584,26 +606,6 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques

// Update instance only if boot_disk_id changes
if state.BootDiskID != plan.BootDiskID {
stopParams := oxide.InstanceStopParams{
Instance: oxide.NameOrId(state.ID.ValueString()),
}
_, err := r.client.InstanceStop(ctx, stopParams)
if err != nil {
if !is404(err) {
resp.Diagnostics.AddError(
"Unable to stop instance:",
"API error: "+err.Error(),
)
return
}
}

diags = waitForInstanceStop(ctx, r.client, updateTimeout, state.ID.ValueString())
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
tflog.Trace(ctx, fmt.Sprintf("stopped instance with ID: %v", state.ID.ValueString()), map[string]any{"success": true})

params := oxide.InstanceUpdateParams{
Instance: oxide.NameOrId(state.ID.ValueString()),
Expand All @@ -620,7 +622,9 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques
return
}

tflog.Trace(ctx, fmt.Sprintf("updated instance with ID: %v", instance.Id), map[string]any{"success": true})
tflog.Trace(ctx, fmt.Sprintf(
"updated boot disk forinstance with ID: %v", instance.Id), map[string]any{"success": true},
)
}

// Check state and if it has an ID that the plan doesn't then detach it
Expand Down Expand Up @@ -651,6 +655,18 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques
return
}

startParams := oxide.InstanceStartParams{Instance: oxide.NameOrId(state.ID.ValueString())}
_, err = r.client.InstanceStart(ctx, startParams)
if err != nil {
if !is404(err) {
resp.Diagnostics.AddError(
"Unable to start instance:",
"API error: "+err.Error(),
)
return
}
}

// Read instance to retrieve modified time value if this is the only update we are doing
params := oxide.InstanceViewParams{
Instance: oxide.NameOrId(state.ID.ValueString()),
Expand Down Expand Up @@ -764,8 +780,11 @@ func waitForInstanceStop(ctx context.Context, client *oxide.Client, timeout time
Pending: []string{
string(oxide.InstanceStateCreating),
string(oxide.InstanceStateStarting),
string(oxide.InstanceStateRunning),
string(oxide.InstanceStateStopping),
string(oxide.InstanceStateRebooting),
string(oxide.InstanceStateMigrating),
string(oxide.InstanceStateRepairing),
},
Target: []string{string(oxide.InstanceStateStopped)},
Timeout: timeout,
Expand Down
8 changes: 4 additions & 4 deletions internal/provider/resource_instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ resource "oxide_instance" "{{.BlockName}}" {
host_name = "terraform-acc-myhost"
memory = 1073741824
ncpus = 1
start_on_create = false
start_on_create = true
disk_attachments = [oxide_disk.{{.DiskBlockName}}.id, oxide_disk.{{.DiskBlockName2}}.id]
}
`
Expand Down Expand Up @@ -511,7 +511,7 @@ resource "oxide_instance" "{{.BlockName}}" {
host_name = "terraform-acc-myhost"
memory = 1073741824
ncpus = 1
start_on_create = false
start_on_create = true
disk_attachments = [oxide_disk.{{.DiskBlockName}}.id]
}
`
Expand Down Expand Up @@ -658,7 +658,7 @@ func checkResourceInstanceDisk(resourceName, instanceName string) resource.TestC
resource.TestCheckResourceAttr(resourceName, "host_name", "terraform-acc-myhost"),
resource.TestCheckResourceAttr(resourceName, "memory", "1073741824"),
resource.TestCheckResourceAttr(resourceName, "ncpus", "1"),
resource.TestCheckResourceAttr(resourceName, "start_on_create", "false"),
resource.TestCheckResourceAttr(resourceName, "start_on_create", "true"),
resource.TestCheckResourceAttrSet(resourceName, "disk_attachments.0"),
resource.TestCheckResourceAttrSet(resourceName, "project_id"),
resource.TestCheckResourceAttrSet(resourceName, "time_created"),
Expand All @@ -675,7 +675,7 @@ func checkResourceInstanceDiskUpdate(resourceName, instanceName string) resource
resource.TestCheckResourceAttr(resourceName, "host_name", "terraform-acc-myhost"),
resource.TestCheckResourceAttr(resourceName, "memory", "1073741824"),
resource.TestCheckResourceAttr(resourceName, "ncpus", "1"),
resource.TestCheckResourceAttr(resourceName, "start_on_create", "false"),
resource.TestCheckResourceAttr(resourceName, "start_on_create", "true"),
resource.TestCheckResourceAttrSet(resourceName, "project_id"),
resource.TestCheckResourceAttrSet(resourceName, "time_created"),
resource.TestCheckResourceAttrSet(resourceName, "time_modified"),
Expand Down

0 comments on commit d85888a

Please sign in to comment.