Skip to content

Commit

Permalink
fix: wait server firewall actions to settle (#209)
Browse files Browse the repository at this point in the history
Closes #205

Prevents a server `locked` error from the API, when trying to change the
type of the server, while `firewall_apply` are still running in the
backend.

The `firewall_apply` actions are triggered by label selectors.
  • Loading branch information
jooola authored Jul 9, 2024
1 parent de02717 commit 2d58893
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
32 changes: 32 additions & 0 deletions builder/hcloud/step_create_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"fmt"
"net/netip"
"os"
"slices"
"sort"
"strings"

Expand Down Expand Up @@ -142,6 +143,16 @@ func (s *stepCreateServer) Run(ctx context.Context, state multistep.StateBag) mu
}
state.Put(StateServerIP, serverIP)

// Wait that the server to settle before continuing. Prevents possible `locked`
// error when changing the server type.
actions, err := getServerRunningActions(ctx, client, server)
if err != nil {
return errorHandler(state, ui, "Could not fetch server running actions", err)
}
if err := client.Action.WaitFor(ctx, actions...); err != nil {
return errorHandler(state, ui, "Could not wait for server running actions", err)
}

if c.UpgradeServerType != "" {
ui.Say("Upgrading server type...")
serverChangeTypeAction, _, err := client.Server.ChangeType(ctx, server, hcloud.ServerChangeTypeOpts{
Expand Down Expand Up @@ -302,3 +313,24 @@ func firstAvailableIP(server *hcloud.Server) string {
}
return ""
}

func getServerRunningActions(ctx context.Context, client *hcloud.Client, server *hcloud.Server) ([]*hcloud.Action, error) {
actions, err := client.Firewall.Action.All(ctx,
hcloud.ActionListOpts{
Status: []hcloud.ActionStatus{
hcloud.ActionStatusRunning,
},
},
)
if err != nil {
return nil, err
}

actions = slices.DeleteFunc(actions, func(action *hcloud.Action) bool {
return !slices.ContainsFunc(action.Resources, func(resource *hcloud.ActionResource) bool {
return resource.Type == hcloud.ActionResourceTypeServer && resource.ID == server.ID
})
})

return actions, nil
}
28 changes: 28 additions & 0 deletions builder/hcloud/step_create_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ func TestStepCreateServer(t *testing.T) {
"meta": { "pagination": { "page": 1 }}
}`,
},
{Method: "GET", Path: "/firewalls/actions?page=1&status=running",
Status: 200,
JSONRaw: `{
"actions": [],
"meta": { "pagination": { "page": 1 }}
}`,
},
},
WantStepAction: multistep.ActionContinue,
WantStateFunc: func(t *testing.T, state multistep.StateBag) {
Expand Down Expand Up @@ -126,6 +133,13 @@ func TestStepCreateServer(t *testing.T) {
"meta": { "pagination": { "page": 1 }}
}`,
},
{Method: "GET", Path: "/firewalls/actions?page=1&status=running",
Status: 200,
JSONRaw: `{
"actions": [],
"meta": { "pagination": { "page": 1 }}
}`,
},
},

WantStepAction: multistep.ActionContinue,
Expand Down Expand Up @@ -220,6 +234,13 @@ func TestStepCreateServer(t *testing.T) {
"meta": { "pagination": { "page": 1 }}
}`,
},
{Method: "GET", Path: "/firewalls/actions?page=1&status=running",
Status: 200,
JSONRaw: `{
"actions": [],
"meta": { "pagination": { "page": 1 }}
}`,
},
},
WantStepAction: multistep.ActionContinue,
WantStateFunc: func(t *testing.T, state multistep.StateBag) {
Expand Down Expand Up @@ -319,6 +340,13 @@ func TestStepCreateServer(t *testing.T) {
"meta": { "pagination": { "page": 1 }}
}`,
},
{Method: "GET", Path: "/firewalls/actions?page=1&status=running",
Status: 200,
JSONRaw: `{
"actions": [],
"meta": { "pagination": { "page": 1 }}
}`,
},
},
WantStepAction: multistep.ActionContinue,
WantStateFunc: func(t *testing.T, state multistep.StateBag) {
Expand Down

0 comments on commit 2d58893

Please sign in to comment.