aboutsummaryrefslogtreecommitdiff
path: root/web/fly/flymachines/volumes.go
blob: a1db912603c12d4294c2fb368dce7f3a5a761ba9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package flymachines

import (
	"context"
	"fmt"
	"net/http"
	"time"
)

type Volume struct {
	ID                string    `json:"id"`
	Name              string    `json:"name"`
	State             string    `json:"state"`
	SizeGB            int       `json:"size_gb"`
	Region            string    `json:"region"`
	Zone              string    `json:"zone"`
	Encrypted         bool      `json:"encrypted"`
	AttachedAllocID   string    `json:"attached_alloc_id"`
	AttachedMachineID string    `json:"attached_machine_id"`
	CreatedAt         time.Time `json:"created_at"`
	Blocks            int       `json:"blocks"`
	BlockSize         int       `json:"block_size"`
	BlocksAvail       int       `json:"blocks_avail"`
	BlocksFree        int       `json:"blocks_free"`
	FSType            string    `json:"fs_type"`
	SnapshotRetention int       `json:"snapshot_retention"`
	HostDedicationKey string    `json:"host_dedication_key,omitempty"`
}

func (c *Client) GetVolumes(ctx context.Context, appName string) ([]Volume, error) {
	return doJSON[[]Volume](ctx, c, http.MethodGet, "/v1/apps/"+appName+"/volumes", http.StatusOK)
}

func (c *Client) GetVolume(ctx context.Context, appName, volumeID string) (*Volume, error) {
	result, err := doJSON[Volume](ctx, c, http.MethodGet, "/v1/apps/"+appName+"/volumes/"+volumeID, http.StatusOK)
	if err != nil {
		return nil, fmt.Errorf("flymachines: can't decode GetVolume response: %w", err)
	}

	return &result, nil
}

type CreateVolume struct {
	Compute           *MachineGuest `json:"compute,omitempty"`
	Encrypted         bool          `json:"encrypted,omitempty"`
	FSType            string        `json:"fs_type,omitempty"`
	MachinesOnly      bool          `json:"machines_only,omitempty"`
	Name              string        `json:"name,omitempty"`
	Region            string        `json:"region,omitempty"`
	RequireUniqueZone bool          `json:"require_unique_zone"`
	SizeGB            int           `json:"size_gb,omitempty"`
	SnapshotID        string        `json:"snapshot_id,omitempty"`
	SnapshotRetention int           `json:"snapshot_retention"`
	SourceVolumeID    string        `json:"source_volume_id,omitempty"`
}

func (cv CreateVolume) Fork(vol *Volume) CreateVolume {
	cv.SourceVolumeID = vol.ID
	cv.SnapshotRetention = vol.SnapshotRetention
	cv.FSType = vol.FSType
	return cv
}

func (c *Client) CreateVolume(ctx context.Context, appName string, cv CreateVolume) (*Volume, error) {
	result, err := doJSONBody[CreateVolume, Volume](ctx, c, http.MethodPost, "/v1/apps/"+appName+"/volumes", cv, http.StatusOK)
	if err != nil {
		return nil, fmt.Errorf("flymachines: can't decode CreateVolume response: %w", err)
	}

	return &result, nil
}

func (c *Client) DeleteVolume(ctx context.Context, appName, volumeID string) error {
	err := c.doRequestNoResponse(ctx, http.MethodDelete, "/v1/apps/"+appName+"/volumes/"+volumeID)
	if err != nil {
		return err
	}

	return nil
}

type ExtendVolumeResponse struct {
	NeedsRestart bool   `json:"needs_restart"`
	Volume       Volume `json:"volume"`
}

func (c *Client) ExtendVolume(ctx context.Context, appName, voluleID string, sizeGB int) (*ExtendVolumeResponse, error) {
	type req struct {
		SizeGB int `json:"size_gb"`
	}

	result, err := doJSONBody[req, ExtendVolumeResponse](ctx, c, http.MethodPost, "/v1/apps/"+appName+"/volumes/"+voluleID+"/extend", req{sizeGB}, http.StatusOK)
	if err != nil {
		return nil, fmt.Errorf("flymachines: can't decode ExtendVolume response: %w", err)
	}

	return &result, nil
}

type Snapshot struct {
	CreatedAt time.Time `json:"created_at"`
	Digest    string    `json:"digest"`
	ID        string    `json:"id"`
	Size      int       `json:"size"`
}

func (c *Client) ListVolumeSnapshots(ctx context.Context, appName, volumeID string) ([]Snapshot, error) {
	return doJSON[[]Snapshot](ctx, c, http.MethodGet, "/v1/apps/"+appName+"/volumes/"+volumeID+"/snapshots", http.StatusOK)
}