Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fly volume snapshot create #3087

Merged
merged 1 commit into from
Jan 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/volume_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,5 @@ type VolumeSnapshot struct {
Size int `json:"size"`
Digest string `json:"digest"`
CreatedAt time.Time `json:"created_at"`
Status string `json:"status"`
}
9 changes: 6 additions & 3 deletions flaps/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ const (
volumeCreate
volumetUpdate
volumeGet
volumeSnapshot
volumeSnapshotCreate
volumeSnapshotList
volumeExtend
volumeDelete
)
Expand Down Expand Up @@ -79,8 +80,10 @@ func (a *flapsAction) String() string {
return "volume_list"
case volumetUpdate:
return "volume_update"
case volumeSnapshot:
return "volume_snapshot"
case volumeSnapshotCreate:
return "volume_snapshot_create"
case volumeSnapshotList:
return "volume_snapshot_list"
case volumeExtend:
return "volume_extend"
case volumeDelete:
Expand Down
13 changes: 12 additions & 1 deletion flaps/flaps_volumes.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,24 @@ func (f *Client) GetVolumeSnapshots(ctx context.Context, volumeId string) ([]api

out := make([]api.VolumeSnapshot, 0)

err := f.sendRequestVolumes(ctx, volumeSnapshot, http.MethodGet, getVolumeSnapshotsEndpoint, nil, &out, nil)
err := f.sendRequestVolumes(ctx, volumeSnapshotList, http.MethodGet, getVolumeSnapshotsEndpoint, nil, &out, nil)
if err != nil {
return nil, fmt.Errorf("failed to get volume %s snapshots: %w", volumeId, err)
}
return out, nil
}

func (f *Client) CreateVolumeSnapshot(ctx context.Context, volumeId string) error {
err := f.sendRequestVolumes(
ctx, volumeSnapshotCreate, http.MethodPost, fmt.Sprintf("/%s/snapshots", volumeId),
nil, nil, nil,
)
if err != nil {
return fmt.Errorf("failed to snapshot %s: %w", volumeId, err)
}
return nil
}

type ExtendVolumeRequest struct {
SizeGB int `json:"size_gb"`
}
Expand Down
1 change: 0 additions & 1 deletion internal/command/volumes/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ func newCreate() *cobra.Command {
command.RequireSession,
command.RequireAppName,
)

cmd.Args = cobra.ExactArgs(1)

flag.Add(cmd,
Expand Down
57 changes: 57 additions & 0 deletions internal/command/volumes/snapshots/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package snapshots

import (
"context"
"fmt"

"github.com/spf13/cobra"

"github.com/superfly/flyctl/client"
"github.com/superfly/flyctl/flaps"
"github.com/superfly/flyctl/internal/appconfig"
"github.com/superfly/flyctl/internal/command"
"github.com/superfly/flyctl/internal/flag"
)

func newCreate() *cobra.Command {
const (
short = "Snapshot a volume"
long = "Snapshot a volume\n"
usage = "create <volume-id>"
)

cmd := command.New(usage, short, long, create, command.RequireSession)
cmd.Args = cobra.ExactArgs(1)

flag.Add(cmd, flag.JSONOutput())
return cmd
}

func create(ctx context.Context) error {
var client = client.FromContext(ctx).API()

volumeId := flag.FirstArg(ctx)

appName := appconfig.NameFromContext(ctx)
if appName == "" {
n, err := client.GetAppNameFromVolume(ctx, volumeId)
if err != nil {
return err
}
appName = *n
}

flapsClient, err := flaps.NewFromAppName(ctx, appName)
if err != nil {
return err
}

err = flapsClient.CreateVolumeSnapshot(ctx, volumeId)
if err != nil {
return err
}

fmt.Printf("Scheduled to snapshot volume %s\n", volumeId)

return nil
}
20 changes: 17 additions & 3 deletions internal/command/volumes/snapshots/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"sort"
"strconv"
"time"

"github.com/dustin/go-humanize"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -40,6 +41,13 @@ func newList() *cobra.Command {
return cmd
}

func timeToString(t time.Time) string {
if t.IsZero() {
return ""
}
return humanize.Time(t)
}

func runList(ctx context.Context) error {
var (
io = iostreams.FromContext(ctx)
Expand Down Expand Up @@ -84,12 +92,18 @@ func runList(ctx context.Context) error {

rows := make([][]string, 0, len(snapshots))
for _, snapshot := range snapshots {
id := snapshot.ID
if id == "" {
id = "(pending)"
}

rows = append(rows, []string{
snapshot.ID,
id,
snapshot.Status,
strconv.Itoa(snapshot.Size),
humanize.Time(snapshot.CreatedAt),
timeToString(snapshot.CreatedAt),
})
}

return render.Table(io.Out, "Snapshots", rows, "ID", "Size", "Created At")
return render.Table(io.Out, "Snapshots", rows, "ID", "Status", "Size", "Created At")
}
1 change: 1 addition & 0 deletions internal/command/volumes/snapshots/snapshots.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func New() *cobra.Command {

snapshots.AddCommand(
newList(),
newCreate(),
)

return snapshots
Expand Down