in alibabacloudstack/resource_apsarastack_ecs_instance.go [503:691]
func resourceAlibabacloudStackInstanceUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*connectivity.AlibabacloudStackClient)
ecsService := EcsService{client}
d.Partial(true)
if !d.IsNewResource() {
err := setTags(client, TagResourceInstance, d)
if err != nil {
return errmsgs.WrapError(err)
}
}
if d.HasChange("security_groups") {
if !d.IsNewResource() || d.Get("vswitch_id").(string) == "" {
o, n := d.GetChange("security_groups")
os := o.(*schema.Set)
ns := n.(*schema.Set)
rl := expandStringList(os.Difference(ns).List())
al := expandStringList(ns.Difference(os).List())
if len(al) > 0 {
err := ecsService.JoinSecurityGroups(d.Id(), al)
if err != nil {
return errmsgs.WrapError(err)
}
}
if len(rl) > 0 {
err := ecsService.LeaveSecurityGroups(d.Id(), rl)
if err != nil {
return errmsgs.WrapError(err)
}
}
}
}
run := false
imageUpdate, err := modifyInstanceImage(d, meta, run)
if err != nil {
return errmsgs.WrapError(err)
}
vpcUpdate, err := modifyVpcAttribute(d, meta, run)
if err != nil {
return errmsgs.WrapError(err)
}
passwordUpdate, err := modifyInstanceAttribute(d, meta)
if err != nil {
return errmsgs.WrapError(err)
}
typeUpdate, err := modifyInstanceType(d, meta, run)
if err != nil {
return errmsgs.WrapError(err)
}
if imageUpdate || vpcUpdate || passwordUpdate || typeUpdate {
run = true
instance, errDesc := ecsService.DescribeInstance(d.Id())
if errDesc != nil {
return errmsgs.WrapError(errDesc)
}
if instance.Status == string(Running) {
stopRequest := ecs.CreateStopInstanceRequest()
client.InitRpcRequest(*stopRequest.RpcRequest)
stopRequest.InstanceId = d.Id()
stopRequest.ForceStop = requests.NewBoolean(false)
raw, err := client.WithEcsClient(func(ecsClient *ecs.Client) (interface{}, error) {
return ecsClient.StopInstance(stopRequest)
})
if err != nil {
errmsg := ""
if bresponse, ok := raw.(*ecs.StopInstanceResponse); ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(bresponse.BaseResponse)
}
return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), stopRequest.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)
}
addDebug(stopRequest.GetActionName(), raw)
}
stateConf := BuildStateConf([]string{"Pending", "Running", "Stopping"}, []string{"Stopped"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, ecsService.InstanceStateRefreshFunc(d.Id(), []string{}))
if _, err = stateConf.WaitForState(); err != nil {
return errmsgs.WrapErrorf(err, errmsgs.IdMsg, d.Id())
}
if _, err := modifyInstanceImage(d, meta, run); err != nil {
return errmsgs.WrapError(err)
}
if _, err := modifyVpcAttribute(d, meta, run); err != nil {
return errmsgs.WrapError(err)
}
if _, err := modifyInstanceType(d, meta, run); err != nil {
return errmsgs.WrapError(err)
}
startRequest := ecs.CreateStartInstanceRequest()
client.InitRpcRequest(*startRequest.RpcRequest)
startRequest.InstanceId = d.Id()
err := resource.Retry(5*time.Minute, func() *resource.RetryError {
raw, err := client.WithEcsClient(func(ecsClient *ecs.Client) (interface{}, error) {
return ecsClient.StartInstance(startRequest)
})
if err != nil {
if errmsgs.IsExpectedErrors(err, []string{"IncorrectInstanceStatus"}) {
time.Sleep(time.Second)
return resource.RetryableError(err)
}
errmsg := ""
if bresponse, ok := raw.(*ecs.StartInstanceResponse); ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(bresponse.BaseResponse)
}
err = errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), startRequest.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)
return resource.NonRetryableError(err)
}
addDebug(startRequest.GetActionName(), raw)
return nil
})
if err != nil {
return err
}
stateConf = &resource.StateChangeConf{
Pending: []string{"Pending", "Starting", "Stopped"},
Target: []string{"Running"},
Refresh: ecsService.InstanceStateRefreshFunc(d.Id(), []string{}),
Timeout: d.Timeout(schema.TimeoutUpdate),
Delay: 5 * time.Second,
MinTimeout: 3 * time.Second,
}
if _, err = stateConf.WaitForState(); err != nil {
return errmsgs.WrapErrorf(err, errmsgs.IdMsg, d.Id())
}
}
if err := modifyInstanceNetworkSpec(d, meta); err != nil {
return errmsgs.WrapError(err)
}
if d.HasChanges("system_disk_tags", "system_disk_id", "image_id", "tags") {
var oraw, nraw map[string]interface{}
system_disks, err := ecsService.DescribeInstanceDisksByType(d.Id(), client.ResourceGroup, "system")
if err != nil {
return errmsgs.WrapError(err)
}
system_disk_tags := getOnlySystemTags(d, system_disks[0].Tags.Tag)
oraw = make(map[string]interface{})
for k, v := range ecsService.tagsToMap(system_disk_tags) {
oraw[k] = v
}
if v, ok := d.GetOk("system_disk_tags"); ok {
nraw = v.(map[string]interface{})
}
err = updateTags(client, []string{system_disks[0].DiskId}, "disk", oraw, nraw)
if err != nil {
return errmsgs.WrapError(err)
}
}
if data_disk_tags, ok := d.GetOk("data_disk_tags"); ok {
disks, err := ecsService.DescribeInstanceDisksByType(d.Id(), client.ResourceGroup, "data")
if err != nil {
return errmsgs.WrapError(err)
}
if len(disks) > 0 {
oraw := make(map[string]interface{})
diskids := make([]string, 0, len(disks))
datadisk_tags := ecsMergeTags(d, data_disk_tags.(map[string]interface{}))
for _, disk := range disks {
diskids = append(diskids, disk.DiskId)
}
err = updateTags(client, diskids, "disk", oraw, datadisk_tags)
if err != nil {
return errmsgs.WrapError(err)
}
}
}
d.Partial(false)
return nil
}