Skip to content

Commit c73f6ff

Browse files
authored
Merge pull request scaleway#55 from terraform-providers/use-task-api
replace waiting on server results with task api
2 parents 492a5f3 + 8c44821 commit c73f6ff

File tree

3 files changed

+111
-155
lines changed

3 files changed

+111
-155
lines changed

scaleway/helpers.go

+45-33
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func validateVolumeType(v interface{}, k string) (ws []string, errors []error) {
4747

4848
// deleteRunningServer terminates the server and waits until it is removed.
4949
func deleteRunningServer(scaleway *api.API, server *api.Server) error {
50-
_, err := scaleway.PostServerAction(server.Identifier, "terminate")
50+
task, err := scaleway.PostServerAction(server.Identifier, "terminate")
5151

5252
if err != nil {
5353
if serr, ok := err.(api.APIError); ok {
@@ -59,7 +59,7 @@ func deleteRunningServer(scaleway *api.API, server *api.Server) error {
5959
return err
6060
}
6161

62-
return waitForServerShutdown(scaleway, server.Identifier)
62+
return waitForTaskCompletion(scaleway, task.Identifier)
6363
}
6464

6565
// deleteStoppedServer needs to cleanup attached root volumes. this is not done
@@ -77,40 +77,16 @@ func deleteStoppedServer(scaleway *api.API, server *api.Server) error {
7777
return nil
7878
}
7979

80-
// NOTE copied from github.com/scaleway/scaleway-cli/pkg/api/helpers.go
81-
// the helpers.go file pulls in quite a lot dependencies, and they're just convenience wrappers anyway
82-
83-
var allStates = []string{"starting", "running", "stopping", "stopped"}
84-
85-
func waitForServerStartup(scaleway *api.API, serverID string) error {
86-
return waitForServerState(scaleway, serverID, "running", []string{"running", "starting"})
87-
}
88-
89-
func waitForServerShutdown(scaleway *api.API, serverID string) error {
90-
return waitForServerState(scaleway, serverID, "stopped", []string{"stopped", "stopping"})
91-
}
92-
93-
func waitForServerState(scaleway *api.API, serverID, targetState string, pendingStates []string) error {
80+
func waitForTaskCompletion(scaleway *api.API, taskID string) error {
9481
stateConf := &resource.StateChangeConf{
95-
Pending: pendingStates,
96-
Target: []string{targetState},
82+
Pending: []string{"pending", "started"},
83+
Target: []string{"success"},
9784
Refresh: func() (interface{}, string, error) {
98-
s, err := scaleway.GetServer(serverID)
99-
100-
if err == nil {
101-
return 42, s.State, nil
102-
}
103-
104-
if serr, ok := err.(api.APIError); ok {
105-
if serr.StatusCode == 404 {
106-
return 42, "stopped", nil
107-
}
85+
task, err := scaleway.GetTask(taskID)
86+
if err != nil {
87+
return 42, "error", err
10888
}
109-
110-
if s != nil {
111-
return 42, s.State, err
112-
}
113-
return 42, "error", err
89+
return 42, task.Status, nil
11490
},
11591
Timeout: 60 * time.Minute,
11692
MinTimeout: 10 * time.Second,
@@ -119,3 +95,39 @@ func waitForServerState(scaleway *api.API, serverID, targetState string, pending
11995
_, err := stateConf.WaitForState()
12096
return err
12197
}
98+
99+
func withStoppedServer(scaleway *api.API, serverID string, run func(*api.Server) error) error {
100+
server, err := scaleway.GetServer(serverID)
101+
if err != nil {
102+
return err
103+
}
104+
105+
var startServerAgain = false
106+
107+
if server.State != "stopped" {
108+
startServerAgain = true
109+
110+
task, err := scaleway.PostServerAction(server.Identifier, "poweroff")
111+
if err != nil {
112+
return err
113+
}
114+
if err := waitForTaskCompletion(scaleway, task.Identifier); err != nil {
115+
return err
116+
}
117+
}
118+
119+
if err := run(server); err != nil {
120+
return err
121+
}
122+
123+
if startServerAgain {
124+
task, err := scaleway.PostServerAction(serverID, "poweron")
125+
if err != nil {
126+
return err
127+
}
128+
if err := waitForTaskCompletion(scaleway, task.Identifier); err != nil {
129+
return err
130+
}
131+
}
132+
return nil
133+
}

scaleway/resource_server.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -203,12 +203,12 @@ func resourceScalewayServerCreate(d *schema.ResourceData, m interface{}) error {
203203

204204
d.SetId(server.Identifier)
205205
if d.Get("state").(string) != "stopped" {
206-
_, err = scaleway.PostServerAction(server.Identifier, "poweron")
206+
task, err := scaleway.PostServerAction(server.Identifier, "poweron")
207207
if err != nil {
208208
return err
209209
}
210210

211-
err = waitForServerStartup(scaleway, server.Identifier)
211+
err = waitForTaskCompletion(scaleway, task.Identifier)
212212

213213
if v, ok := d.GetOk("public_ip"); ok {
214214
if err := attachIP(scaleway, d.Id(), v.(string)); err != nil {

scaleway/resource_volume_attachment.go

+64-120
Original file line numberDiff line numberDiff line change
@@ -49,81 +49,52 @@ func resourceScalewayVolumeAttachmentCreate(d *schema.ResourceData, m interface{
4949
return errVolumeAlreadyAttached
5050
}
5151

52-
serverID := d.Get("server").(string)
53-
54-
server, err := scaleway.GetServer(serverID)
55-
if err != nil {
56-
fmt.Printf("Failed getting server: %q", err)
57-
return err
58-
}
59-
60-
var startServerAgain = false
61-
// volumes can only be modified when the server is powered off
62-
if server.State != "stopped" {
63-
startServerAgain = true
64-
65-
if _, err := scaleway.PostServerAction(server.Identifier, "poweroff"); err != nil {
66-
return err
52+
if err := withStoppedServer(scaleway, d.Get("server").(string), func(server *api.Server) error {
53+
volumes := make(map[string]api.Volume)
54+
for i, volume := range server.Volumes {
55+
volumes[i] = volume
6756
}
68-
}
6957

70-
if err := waitForServerShutdown(scaleway, server.Identifier); err != nil {
71-
return err
72-
}
73-
74-
volumes := make(map[string]api.Volume)
75-
for i, volume := range server.Volumes {
76-
volumes[i] = volume
77-
}
58+
volumes[fmt.Sprintf("%d", len(volumes)+1)] = *vol
7859

79-
volumes[fmt.Sprintf("%d", len(volumes)+1)] = *vol
80-
81-
// the API request requires most volume attributes to be unset to succeed
82-
for k, v := range volumes {
83-
v.Size = 0
84-
v.CreationDate = ""
85-
v.Organization = ""
86-
v.ModificationDate = ""
87-
v.VolumeType = ""
88-
v.Server = nil
89-
v.ExportURI = ""
90-
91-
volumes[k] = v
92-
}
60+
// the API request requires most volume attributes to be unset to succeed
61+
for k, v := range volumes {
62+
v.Size = 0
63+
v.CreationDate = ""
64+
v.Organization = ""
65+
v.ModificationDate = ""
66+
v.VolumeType = ""
67+
v.Server = nil
68+
v.ExportURI = ""
9369

94-
if err := resource.Retry(serverWaitTimeout, func() *resource.RetryError {
95-
var req = api.ServerPatchDefinition{
96-
Volumes: &volumes,
70+
volumes[k] = v
9771
}
98-
err := scaleway.PatchServer(serverID, req)
9972

100-
if err == nil {
101-
return nil
102-
}
73+
return resource.Retry(serverWaitTimeout, func() *resource.RetryError {
74+
var req = api.ServerPatchDefinition{
75+
Volumes: &volumes,
76+
}
77+
err := scaleway.PatchServer(server.Identifier, req)
10378

104-
if serr, ok := err.(api.APIError); ok {
105-
log.Printf("[DEBUG] Error patching server: %q\n", serr.APIMessage)
79+
if err == nil {
80+
return nil
81+
}
82+
83+
if serr, ok := err.(api.APIError); ok {
84+
log.Printf("[DEBUG] Error patching server: %q\n", serr.APIMessage)
10685

107-
if serr.StatusCode == 400 {
108-
return resource.RetryableError(fmt.Errorf("Waiting for server update to succeed: %q", serr.APIMessage))
86+
if serr.StatusCode == 400 {
87+
return resource.RetryableError(fmt.Errorf("Waiting for server update to succeed: %q", serr.APIMessage))
88+
}
10989
}
110-
}
11190

112-
return resource.NonRetryableError(err)
91+
return resource.NonRetryableError(err)
92+
})
11393
}); err != nil {
11494
return err
11595
}
11696

117-
if startServerAgain {
118-
if _, err := scaleway.PostServerAction(serverID, "poweron"); err != nil {
119-
return err
120-
}
121-
if err := waitForServerStartup(scaleway, serverID); err != nil {
122-
return err
123-
}
124-
}
125-
126-
d.SetId(fmt.Sprintf("scaleway-server:%s/volume/%s", serverID, d.Get("volume").(string)))
97+
d.SetId(fmt.Sprintf("scaleway-server:%s/volume/%s", d.Get("server").(string), d.Get("volume").(string)))
12798

12899
return resourceScalewayVolumeAttachmentRead(d, m)
129100
}
@@ -175,78 +146,51 @@ func resourceScalewayVolumeAttachmentDelete(d *schema.ResourceData, m interface{
175146

176147
scaleway := m.(*Client).scaleway
177148

178-
var startServerAgain = false
179-
180-
serverID := d.Get("server").(string)
181-
182-
server, err := scaleway.GetServer(serverID)
183-
if err != nil {
184-
return err
185-
}
186-
187-
// volumes can only be modified when the server is powered off
188-
if server.State != "stopped" {
189-
startServerAgain = true
190-
if _, err := scaleway.PostServerAction(server.Identifier, "poweroff"); err != nil {
191-
return err
192-
}
193-
}
194-
if err := waitForServerShutdown(scaleway, server.Identifier); err != nil {
195-
return err
196-
}
197-
198-
volumes := make(map[string]api.Volume)
199-
for _, volume := range server.Volumes {
200-
if volume.Identifier != d.Get("volume").(string) {
201-
volumes[fmt.Sprintf("%d", len(volumes))] = volume
149+
if err := withStoppedServer(scaleway, d.Get("server").(string), func(server *api.Server) error {
150+
volumes := make(map[string]api.Volume)
151+
for _, volume := range server.Volumes {
152+
if volume.Identifier != d.Get("volume").(string) {
153+
volumes[fmt.Sprintf("%d", len(volumes))] = volume
154+
}
202155
}
203-
}
204156

205-
// the API request requires most volume attributes to be unset to succeed
206-
for k, v := range volumes {
207-
v.Size = 0
208-
v.CreationDate = ""
209-
v.Organization = ""
210-
v.ModificationDate = ""
211-
v.VolumeType = ""
212-
v.Server = nil
213-
v.ExportURI = ""
214-
215-
volumes[k] = v
216-
}
157+
// the API request requires most volume attributes to be unset to succeed
158+
for k, v := range volumes {
159+
v.Size = 0
160+
v.CreationDate = ""
161+
v.Organization = ""
162+
v.ModificationDate = ""
163+
v.VolumeType = ""
164+
v.Server = nil
165+
v.ExportURI = ""
217166

218-
if err := resource.Retry(serverWaitTimeout, func() *resource.RetryError {
219-
var req = api.ServerPatchDefinition{
220-
Volumes: &volumes,
167+
volumes[k] = v
221168
}
222-
err := scaleway.PatchServer(serverID, req)
223169

224-
if err == nil {
225-
return nil
226-
}
170+
return resource.Retry(serverWaitTimeout, func() *resource.RetryError {
171+
var req = api.ServerPatchDefinition{
172+
Volumes: &volumes,
173+
}
174+
err := scaleway.PatchServer(server.Identifier, req)
227175

228-
if serr, ok := err.(api.APIError); ok {
229-
log.Printf("[DEBUG] Error patching server: %q\n", serr.APIMessage)
176+
if err == nil {
177+
return nil
178+
}
230179

231-
if serr.StatusCode == 400 {
232-
return resource.RetryableError(fmt.Errorf("Waiting for server update to succeed: %q", serr.APIMessage))
180+
if serr, ok := err.(api.APIError); ok {
181+
log.Printf("[DEBUG] Error patching server: %q\n", serr.APIMessage)
182+
183+
if serr.StatusCode == 400 {
184+
return resource.RetryableError(fmt.Errorf("Waiting for server update to succeed: %q", serr.APIMessage))
185+
}
233186
}
234-
}
235187

236-
return resource.NonRetryableError(err)
188+
return resource.NonRetryableError(err)
189+
})
237190
}); err != nil {
238191
return err
239192
}
240193

241-
if startServerAgain {
242-
if _, err := scaleway.PostServerAction(serverID, "poweron"); err != nil {
243-
return err
244-
}
245-
if err := waitForServerStartup(scaleway, serverID); err != nil {
246-
return err
247-
}
248-
}
249-
250194
d.SetId("")
251195

252196
return nil

0 commit comments

Comments
 (0)