Skip to content

Commit

Permalink
Add fly machines suspend (#3633)
Browse files Browse the repository at this point in the history
* Add `fly machines suspend`
* `release` must be called even on error
  • Loading branch information
matttpt committed Jun 14, 2024
1 parent 8190283 commit ba27404
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 3 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ require (
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.9.0
github.com/superfly/fly-go v0.1.16
github.com/superfly/fly-go v0.1.17
github.com/superfly/graphql v0.2.4
github.com/superfly/lfsc-go v0.1.1
github.com/superfly/macaroon v0.2.13
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -607,8 +607,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/superfly/fly-go v0.1.16 h1:fXM2ybR86SoZHeybmwwpTAqtm7SJmtTQO1Haguf2mj0=
github.com/superfly/fly-go v0.1.16/go.mod h1:JQke/BwoZqrWurqYkypSlcSo7bIUgCI3eVnqMC6AUj0=
github.com/superfly/fly-go v0.1.17 h1:PxXuZ2fYOUPIOnWBYEXubtl0sMtUf1Iiz1Edh3RxID0=
github.com/superfly/fly-go v0.1.17/go.mod h1:JQke/BwoZqrWurqYkypSlcSo7bIUgCI3eVnqMC6AUj0=
github.com/superfly/graphql v0.2.4 h1:Av8hSk4x8WvKJ6MTnEwrLknSVSGPc7DWpgT3z/kt3PU=
github.com/superfly/graphql v0.2.4/go.mod h1:CVfDl31srm8HnJ9udwLu6hFNUW/P6GUM2dKcG1YQ8jc=
github.com/superfly/lfsc-go v0.1.1 h1:dGjLgt81D09cG+aR9lJZIdmonjZSR5zYCi7s54+ZU2Q=
Expand Down
1 change: 1 addition & 0 deletions internal/command/machine/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Machines REST fly.`
newMachineExec(),
newMachineCordon(),
newMachineUncordon(),
newSuspend(),
)

return cmd
Expand Down
100 changes: 100 additions & 0 deletions internal/command/machine/suspend.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package machine

import (
"context"
"fmt"
"time"

"github.com/spf13/cobra"
"github.com/superfly/fly-go"
"github.com/superfly/flyctl/internal/command"
"github.com/superfly/flyctl/internal/flag"
"github.com/superfly/flyctl/internal/flapsutil"
mach "github.com/superfly/flyctl/internal/machine"
"github.com/superfly/flyctl/iostreams"
)

func newSuspend() *cobra.Command {
const (
short = "Suspend one or more Fly machines"
long = short + "\n"

usage = "suspend [<id>...]"
)

cmd := command.New(usage, short, long, runMachineSuspend,
command.RequireSession,
command.LoadAppNameIfPresent,
)

cmd.Args = cobra.ArbitraryArgs

flag.Add(
cmd,
flag.App(),
flag.AppConfig(),
selectFlag,
flag.Duration{
Name: "wait-timeout",
Shorthand: "w",
Description: "Duration to wait for individual Machines to be suspended.",
Default: 0 * time.Second,
},
)

return cmd
}

func runMachineSuspend(ctx context.Context) (err error) {
var (
io = iostreams.FromContext(ctx)
args = flag.Args(ctx)
waitTimeout = flag.GetDuration(ctx, "wait-timeout")
)

machines, ctx, err := selectManyMachines(ctx, args)
if err != nil {
return err
}

machines, release, err := mach.AcquireLeases(ctx, machines)
defer release()
if err != nil {
return err
}

for _, machine := range machines {
if err = suspend(ctx, machine, waitTimeout); err != nil {
return
}
if waitTimeout != 0 {
fmt.Fprintf(io.Out, "%s has been suspended\n", machine.ID)
} else {
fmt.Fprintf(io.Out, "%s is being suspended\n", machine.ID)
}
}
return
}

func suspend(ctx context.Context, machine *fly.Machine, waitTimeout time.Duration) error {
client := flapsutil.ClientFromContext(ctx)
if err := client.Suspend(ctx, machine.ID, machine.LeaseNonce); err != nil {
if err := rewriteMachineNotFoundErrors(ctx, err, machine.ID); err != nil {
return err
}
return fmt.Errorf("could not suspend Machine %s: %w", machine.ID, err)
}

if waitTimeout != 0 {
machine, err := client.Get(ctx, machine.ID)
if err != nil {
return fmt.Errorf("could not get Machine %s to wait for suspension: %w", machine.ID, err)
}
err = client.Wait(ctx, machine, "suspended", waitTimeout)
if err != nil {
return fmt.Errorf("Machine %s was not suspended within the wait timeout: %w", machine.ID, err)
}
}

return nil
}
1 change: 1 addition & 0 deletions internal/flapsutil/flaps_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type FlapsClient interface {
SetMetadata(ctx context.Context, machineID, key, value string) error
Start(ctx context.Context, machineID string, nonce string) (out *fly.MachineStartResponse, err error)
Stop(ctx context.Context, in fly.StopMachineInput, nonce string) (err error)
Suspend(ctx context.Context, machineID, nonce string) error
Uncordon(ctx context.Context, machineID string, nonce string) (err error)
Update(ctx context.Context, builder fly.LaunchMachineInput, nonce string) (out *fly.Machine, err error)
UpdateVolume(ctx context.Context, volumeId string, req fly.UpdateVolumeRequest) (*fly.Volume, error)
Expand Down
4 changes: 4 additions & 0 deletions internal/inmem/flaps_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ func (m *FlapsClient) Stop(ctx context.Context, in fly.StopMachineInput, nonce s
panic("TODO")
}

func (m *FlapsClient) Suspend(ctx context.Context, machineID, nonce string) (err error) {
panic("TODO")
}

func (m *FlapsClient) Uncordon(ctx context.Context, machineID string, nonce string) (err error) {
panic("TODO")
}
Expand Down
5 changes: 5 additions & 0 deletions internal/mock/flaps_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type FlapsClient struct {
SetMetadataFunc func(ctx context.Context, machineID, key, value string) error
StartFunc func(ctx context.Context, machineID string, nonce string) (out *fly.MachineStartResponse, err error)
StopFunc func(ctx context.Context, in fly.StopMachineInput, nonce string) (err error)
SuspendFunc func(ctx context.Context, machineID, nonce string) (err error)
UncordonFunc func(ctx context.Context, machineID string, nonce string) (err error)
UpdateFunc func(ctx context.Context, builder fly.LaunchMachineInput, nonce string) (out *fly.Machine, err error)
UpdateVolumeFunc func(ctx context.Context, volumeId string, req fly.UpdateVolumeRequest) (*fly.Volume, error)
Expand Down Expand Up @@ -174,6 +175,10 @@ func (m *FlapsClient) Stop(ctx context.Context, in fly.StopMachineInput, nonce s
return m.StopFunc(ctx, in, nonce)
}

func (m *FlapsClient) Suspend(ctx context.Context, machineID, nonce string) (err error) {
return m.SuspendFunc(ctx, machineID, nonce)
}

func (m *FlapsClient) Uncordon(ctx context.Context, machineID string, nonce string) (err error) {
return m.UncordonFunc(ctx, machineID, nonce)
}
Expand Down

0 comments on commit ba27404

Please sign in to comment.