-
Notifications
You must be signed in to change notification settings - Fork 220
/
set_platform_version.go
142 lines (123 loc) · 3.71 KB
/
set_platform_version.go
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package apps
import (
"context"
"errors"
"fmt"
"github.com/spf13/cobra"
"github.com/superfly/flyctl/client"
"github.com/superfly/flyctl/flaps"
"github.com/superfly/flyctl/gql"
"github.com/superfly/flyctl/internal/appconfig"
"github.com/superfly/flyctl/internal/command"
"github.com/superfly/flyctl/internal/flag"
"github.com/superfly/flyctl/internal/prompt"
"github.com/superfly/flyctl/iostreams"
)
func newSetPlatformVersion() *cobra.Command {
const (
long = `The APPS SET-PLATFORM-VERSION command directly sets the platform version for an application.
Please use caution when using this command.`
short = "Directly set the platform version"
usage = "set-platform-version <nomad|detached|machines>"
)
cmd := command.New(usage, short, long, runSetPlatformVersion,
command.RequireSession,
command.RequireAppName,
)
cmd.Args = cobra.ExactArgs(1)
cmd.Hidden = true
flag.Add(cmd,
flag.App(),
flag.AppConfig(),
)
cmd.ValidArgs = []string{"nomad", "detached", "machines"}
return cmd
}
func runSetPlatformVersion(ctx context.Context) error {
var (
appName = appconfig.NameFromContext(ctx)
client = client.FromContext(ctx).API()
io = iostreams.FromContext(ctx)
)
app, err := client.GetAppCompact(ctx, appName)
if err != nil {
return err
}
if app.IsPostgresApp() {
return fmt.Errorf("postgres apps should use `fly migrate-to-v2` instead")
}
currentVersion := app.PlatformVersion
desiredVersion := flag.FirstArg(ctx)
if currentVersion == desiredVersion {
fmt.Fprintf(io.Out, "App %s is already on platform version %s", appName, desiredVersion)
return nil
}
if desiredVersion == "machines" {
// Validate that there are no nomad allocs, and that autoscaling is disabled
allocs, err := client.GetAllocations(ctx, appName, false)
if err != nil {
return err
}
if len(allocs) > 0 {
return errors.New("cannot migrate to machines platform version with existing nomad allocations")
}
}
if currentVersion == "nomad" {
autoscaleConfig, err := client.AppAutoscalingConfig(ctx, appName)
if err != nil {
return err
}
if autoscaleConfig.Enabled {
return fmt.Errorf("cannot migrate to %s platform version with autoscaling enabled", desiredVersion)
}
}
if desiredVersion == "nomad" {
// Validate that there are no machines
flapsClient, err := flaps.New(ctx, app)
if err != nil {
return fmt.Errorf("list of machines could not be retrieved: %w", err)
}
machines, err := flapsClient.List(ctx, "")
if err != nil {
return fmt.Errorf("machines could not be retrieved")
}
if len(machines) > 0 {
return errors.New("cannot migrate to nomad platform version with existing machines")
}
}
switch confirmed, err := prompt.Confirmf(ctx, "Are you sure you want to change the platform version of %s from %s to %s?", appName, currentVersion, desiredVersion); {
case err == nil:
if !confirmed {
return nil
}
case prompt.IsNonInteractive(err):
return prompt.NonInteractiveError("flyctl apps set-platform-version can only be run interactively")
default:
return err
}
err = UpdateAppPlatformVersion(ctx, appName, desiredVersion)
if err != nil {
return err
}
fmt.Fprintf(io.Out, "App %s is now on platform version %s\n", appName, desiredVersion)
return nil
}
func UpdateAppPlatformVersion(ctx context.Context, appName string, platform string) error {
_ = `# @genqlient
mutation SelfServiceSetPlatformVersion($input:SetPlatformVersionInput!) {
setPlatformVersion(input:$input) {
app { id }
}
}
`
client := client.FromContext(ctx).API()
input := gql.SetPlatformVersionInput{
AppId: appName,
PlatformVersion: platform,
}
_, err := gql.SelfServiceSetPlatformVersion(ctx, client.GenqClient, input)
if err != nil {
return err
}
return nil
}