Skip to content

Commit e32d90b

Browse files
authored
Merge 4c8f735 into c12bb49
2 parents c12bb49 + 4c8f735 commit e32d90b

File tree

10 files changed

+100
-149
lines changed

10 files changed

+100
-149
lines changed

internal/command/deploy/machines_launchinput.go

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package deploy
22

33
import (
44
"fmt"
5+
"slices"
56
"strconv"
67
"strings"
78

@@ -297,18 +298,14 @@ func skipLaunch(origMachineRaw *fly.Machine, mConfig *fly.MachineConfig) bool {
297298
}
298299

299300
switch {
300-
case state == fly.MachineStateStarted:
301+
case slices.Contains([]string{fly.MachineStateStarted, "starting", "failed"}, state):
301302
return false
302303
case len(mConfig.Standbys) > 0:
303304
return true
304-
case state == fly.MachineStateStopped, state == fly.MachineStateSuspended:
305-
for _, s := range mConfig.Services {
306-
if (s.Autostop != nil && *s.Autostop != fly.MachineAutostopOff) || (s.Autostart != nil && *s.Autostart) {
307-
return true
308-
}
309-
}
305+
case origMachineRaw == nil:
306+
return false
310307
}
311-
return false
308+
return true
312309
}
313310

314311
// updateContainerImage sets container.Image = mConfig.Image in any container where image == "."

internal/command/deploy/machines_launchinput_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
)
1616

1717
func makeTerminalLoggerQuiet(tb testing.TB) {
18-
var originalLogger = terminal.DefaultLogger
18+
originalLogger := terminal.DefaultLogger
1919
terminal.DefaultLogger = logger.New(os.Stdout, logger.Error, true)
2020

2121
tb.Cleanup(func() {
@@ -85,6 +85,7 @@ func testLaunchInputForBasic(t *testing.T) {
8585
Region: li.Region,
8686
Config: helpers.Clone(li.Config),
8787
HostStatus: fly.HostStatusOk,
88+
State: fly.MachineStateStarted,
8889
}
8990
// also must preserve any user's added metadata except for known fly metadata keys
9091
origMachineRaw.Config.Metadata["user-added-me"] = "keep it"
@@ -104,6 +105,7 @@ func testLaunchInputForBasic(t *testing.T) {
104105
Region: li.Region,
105106
Config: helpers.Clone(li.Config),
106107
HostStatus: fly.HostStatusOk,
108+
State: fly.MachineStateStarted,
107109
}
108110
want.Config.Image = "super/globe"
109111
want.Config.Env["NOT_SET_ON_RESTART_ONLY"] = "true"
@@ -253,7 +255,6 @@ func testLaunchInputForOnMounts(t *testing.T) {
253255
assert.Equal(t, "ab1234567890", li.ID)
254256
assert.True(t, li.RequiresReplacement)
255257
assert.Empty(t, li.Config.Mounts)
256-
257258
}
258259

259260
// test mounts with auto volume resize

internal/command/deploy/machines_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ func Test_resolveUpdatedMachineConfig_Mounts(t *testing.T) {
279279
}, li)
280280

281281
origMachine := &fly.Machine{
282+
State: fly.MachineStateStarted,
282283
HostStatus: fly.HostStatusOk,
283284
Config: &fly.MachineConfig{
284285
Mounts: []fly.MachineMount{{
@@ -329,6 +330,7 @@ func Test_resolveUpdatedMachineConfig_restartOnly(t *testing.T) {
329330
md.img = "SHOULD-NOT-USE-THIS-TAG"
330331

331332
origMachine := &fly.Machine{
333+
State: fly.MachineStateStarted,
332334
HostStatus: fly.HostStatusOk,
333335
ID: "OrigID",
334336
Config: &fly.MachineConfig{
@@ -371,6 +373,7 @@ func Test_resolveUpdatedMachineConfig_restartOnlyProcessGroup(t *testing.T) {
371373
md.img = "SHOULD-NOT-USE-THIS-TAG"
372374

373375
origMachine := &fly.Machine{
376+
State: fly.MachineStateStarted,
374377
HostStatus: fly.HostStatusOk,
375378
ID: "OrigID",
376379
Config: &fly.MachineConfig{

internal/command/machine/update.go

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import (
1616
"github.com/superfly/flyctl/internal/flag"
1717
"github.com/superfly/flyctl/internal/flyerr"
1818
mach "github.com/superfly/flyctl/internal/machine"
19-
"github.com/superfly/flyctl/internal/watch"
2019
)
2120

2221
func newUpdate() *cobra.Command {
@@ -79,9 +78,7 @@ func newUpdate() *cobra.Command {
7978

8079
func runUpdate(ctx context.Context) (err error) {
8180
var (
82-
io = iostreams.FromContext(ctx)
83-
colorize = io.ColorScheme()
84-
81+
io = iostreams.FromContext(ctx)
8582
autoConfirm = flag.GetBool(ctx, "yes")
8683
skipHealthChecks = flag.GetBool(ctx, "skip-health-checks")
8784
skipStart = flag.GetBool(ctx, "skip-start")
@@ -169,20 +166,10 @@ func runUpdate(ctx context.Context) (err error) {
169166
Descript: timeoutErr.Description(),
170167
Suggest: "Try increasing the --wait-timeout",
171168
}
172-
173169
}
174170
return err
175171
}
176172

177-
if !(input.SkipLaunch || flag.GetDetach(ctx)) {
178-
fmt.Fprintln(io.Out, colorize.Green("==> "+"Monitoring health checks"))
179-
180-
if err := watch.MachinesChecks(ctx, appName, []*fly.Machine{machine}); err != nil {
181-
return err
182-
}
183-
fmt.Fprintln(io.Out)
184-
}
185-
186173
fmt.Fprintf(io.Out, "\nMonitor machine status here:\nhttps://fly.io/apps/%s/machines/%s\n", appName, machine.ID)
187174

188175
return nil

internal/machine/update.go

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,25 @@ func Update(ctx context.Context, appName string, m *fly.Machine, input *fly.Laun
8585
return fmt.Errorf("could not update machine %s: %w", m.ID, err)
8686
}
8787

88-
waitForAction := "start"
89-
if input.SkipLaunch || m.Config.Schedule != "" || m.State != fly.MachineStateStarted {
88+
waitForAction := "none"
89+
switch m.State {
90+
case fly.MachineStateStarted, "failed", "starting":
91+
waitForAction = "start"
92+
case fly.MachineStateStopped, fly.MachineStateSuspended, "stopping", "suspending":
93+
waitForAction = "stop"
94+
default:
95+
// look for past machine events
96+
for _, ev := range m.Events {
97+
if ev.Type == "start" || ev.Status == "started" || ev.Status == "starting" {
98+
waitForAction = "start"
99+
break
100+
} else if ev.Status == "stopped" || ev.Status == "stopping" || ev.Status == "suspended" || ev.Status == "suspending" {
101+
waitForAction = "stop"
102+
break
103+
}
104+
}
105+
}
106+
if input.SkipLaunch {
90107
waitForAction = "stop"
91108
}
92109

@@ -99,11 +116,9 @@ func Update(ctx context.Context, appName string, m *fly.Machine, input *fly.Laun
99116
return err
100117
}
101118

102-
if !input.SkipLaunch {
103-
if !input.SkipHealthChecks {
104-
if err := watch.MachinesChecks(ctx, appName, []*fly.Machine{updatedMachine}); err != nil {
105-
return fmt.Errorf("failed to wait for health checks to pass: %w", err)
106-
}
119+
if waitForAction == "start" && !input.SkipHealthChecks {
120+
if err := watch.MachinesChecks(ctx, appName, []*fly.Machine{updatedMachine}); err != nil {
121+
return fmt.Errorf("failed to wait for health checks to pass: %w", err)
107122
}
108123
}
109124

internal/machine/wait.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ func WaitForStartOrStop(ctx context.Context, appName string, machine *fly.Machin
2727
waitOnAction = "started"
2828
case "stop":
2929
waitOnAction = "stopped"
30+
case "none":
31+
return nil
3032
default:
3133
return invalidAction
3234
}

test/preflight/apps_v2_integration_test.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func TestAppsV2Example(t *testing.T) {
8484
ENV BUILT_BY_DOCKERFILE=true
8585
`
8686
dockerfilePath := filepath.Join(f.WorkDir(), "Dockerfile")
87-
err := os.WriteFile(dockerfilePath, []byte(dockerfileContent), 0644)
87+
err := os.WriteFile(dockerfilePath, []byte(dockerfileContent), 0o644)
8888
if err != nil {
8989
f.Fatalf("failed to write dockerfile at %s error: %v", dockerfilePath, err)
9090
}
@@ -109,7 +109,7 @@ func TestAppsV2ConfigChanges(t *testing.T) {
109109
newConfigFile := strings.Replace(string(configFileBytes), `FOO = 'BAR'`, `BAR = "QUX"`, 1)
110110
require.Contains(f, newConfigFile, `BAR = "QUX"`)
111111

112-
err = os.WriteFile(configFilePath, []byte(newConfigFile), 0666)
112+
err = os.WriteFile(configFilePath, []byte(newConfigFile), 0o666)
113113
require.NoError(t, err)
114114

115115
f.Fly("deploy --buildkit --remote-only --detach")
@@ -177,7 +177,7 @@ func TestAppsV2Config_ParseExperimental(t *testing.T) {
177177
auto_rollback = true
178178
`
179179

180-
err := os.WriteFile(configFilePath, []byte(config), 0644)
180+
err := os.WriteFile(configFilePath, []byte(config), 0o644)
181181
require.NoError(t, err, "error trying to write %s", configFilePath)
182182

183183
result := f.Fly("launch --no-deploy --ha=false --name %s --region ord --copy-config --org %s", appName, f.OrgSlug())
@@ -208,7 +208,7 @@ func TestAppsV2Config_ProcessGroups(t *testing.T) {
208208

209209
deployToml := func(toml string) *testlib.FlyctlResult {
210210
toml = "app = \"" + appName + "\"\n" + toml
211-
err := os.WriteFile(configFilePath, []byte(toml), 0666)
211+
err := os.WriteFile(configFilePath, []byte(toml), 0o666)
212212
require.NoError(t, err, "error trying to write %s", configFilePath)
213213
cmd := f.Fly("deploy --buildkit --remote-only --detach --now --image nginx --ha=false")
214214
cmd.AssertSuccessfulExit()
@@ -252,10 +252,8 @@ func TestAppsV2Config_ProcessGroups(t *testing.T) {
252252

253253
deployOut := deployToml(`
254254
[[services]]
255-
http_checks = []
256255
internal_port = 8080
257256
protocol = "tcp"
258-
script_checks = []
259257
260258
[[services.ports]]
261259
port = 80
@@ -279,10 +277,8 @@ bar_web = "bash -c 'while true; do sleep 10; done'"
279277
280278
[[services]]
281279
processes = ["web"] # this service only applies to the web process
282-
http_checks = []
283280
internal_port = 8080
284281
protocol = "tcp"
285-
script_checks = []
286282
287283
[[services.ports]]
288284
port = 80
@@ -320,6 +316,7 @@ bar_web = "bash -c 'while true; do sleep 10; done'"
320316
if len(f.OtherRegions()) > 0 {
321317
secondaryRegion = f.OtherRegions()[0]
322318
}
319+
323320
f.Fly("m clone %s --region %s", barWebMachId, secondaryRegion)
324321
f.Fly("machine update %s -m ABCD=EFGH -y", webMachId).AssertSuccessfulExit()
325322

@@ -349,6 +346,13 @@ web = "nginx -g 'daemon off;'"
349346

350347
// Step 5: Set secrets, to ensure that machine data is kept during a 'restartOnly' deploy.
351348
f.Fly("machine update %s -m CUSTOM=META -y", webMachId).AssertSuccessfulExit()
349+
// XXX: this sucks but until update waits for the machine to reach a terminal state
350+
// before returning, we have to wait an arbitrary amount of time here to ensure
351+
// that the machine is ready for another update.
352+
// TODO: Replace with an eventually loop
353+
time.Sleep(10 * time.Second)
354+
355+
f.Logf("machines before update: %s", f.Fly("m status -d -a %s %s", appName, webMachId).StdOutString())
352356
f.Fly("secrets set 'SOME=MY_SECRET_TEST_STRING' -a %s", appName).AssertSuccessfulExit()
353357

354358
machines = f.MachinesList(appName)
@@ -512,7 +516,7 @@ func TestImageLabel(t *testing.T) {
512516
ENV BUILT_BY_DOCKERFILE=true
513517
`
514518
dockerfilePath := filepath.Join(f.WorkDir(), "Dockerfile")
515-
err := os.WriteFile(dockerfilePath, []byte(dockerfileContent), 0644)
519+
err := os.WriteFile(dockerfilePath, []byte(dockerfileContent), 0o644)
516520
if err != nil {
517521
f.Fatalf("failed to write dockerfile at %s error: %v", dockerfilePath, err)
518522
}

0 commit comments

Comments
 (0)