Skip to content
This repository was archived by the owner on Aug 30, 2024. It is now read-only.

Commit bcaac7b

Browse files
committed
internal/cmd/update.go: validate we can exec new binary
1 parent 26984a2 commit bcaac7b

File tree

2 files changed

+42
-9
lines changed

2 files changed

+42
-9
lines changed

internal/cmd/update.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,19 @@ func (u *updater) Run(ctx context.Context, force bool, coderURLArg string, versi
199199
return clog.Fatal("failed to persist updated coder binary to disk", clog.Causef(err.Error()))
200200
}
201201

202+
_ = updatedBin.Close()
203+
204+
// validate that we can execute the new binary before overwriting
205+
updatedVersionOutput, err := u.execF(ctx, updatedCoderBinaryPath, "--version")
206+
if err != nil {
207+
return clog.Fatal("failed to check version of updated coder binary",
208+
clog.BlankLine,
209+
fmt.Sprintf("output: %q", string(updatedVersionOutput)),
210+
clog.Causef(err.Error()))
211+
}
212+
213+
clog.LogInfo(fmt.Sprintf("updated binary reports %s", bytes.TrimSpace(updatedVersionOutput)))
214+
202215
if err = u.fs.Rename(updatedCoderBinaryPath, u.executablePath); err != nil {
203216
return clog.Fatal("failed to update coder binary in-place", clog.Causef(err.Error()))
204217
}

internal/cmd/update_test.go

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,16 @@ import (
2222
)
2323

2424
const (
25-
fakeExePathLinux = "/home/user/bin/coder"
26-
fakeExePathWindows = `C:\Users\user\bin\coder.exe`
27-
fakeCoderURL = "https://my.cdr.dev"
28-
fakeNewVersion = "1.23.4-rc.5+678-gabcdef-12345678"
29-
fakeOldVersion = "1.22.4-rc.5+678-gabcdef-12345678"
30-
fakeReleaseURLLinux = "https://github.com/cdr/coder-cli/releases/download/v1.23.4-rc.5/coder-cli-linux-amd64.tar.gz"
31-
fakeReleaseURLWindows = "https://github.com/cdr/coder-cli/releases/download/v1.23.4-rc.5/coder-cli-windows-amd64.zip"
32-
goosWindows = "windows"
33-
goosLinux = "linux"
25+
fakeExePathLinux = "/home/user/bin/coder"
26+
fakeUpdatedExePathLinux = "/home/user/bin/coder.new"
27+
fakeExePathWindows = `C:\Users\user\bin\coder.exe`
28+
fakeCoderURL = "https://my.cdr.dev"
29+
fakeNewVersion = "1.23.4-rc.5+678-gabcdef-12345678"
30+
fakeOldVersion = "1.22.4-rc.5+678-gabcdef-12345678"
31+
fakeReleaseURLLinux = "https://github.com/cdr/coder-cli/releases/download/v1.23.4-rc.5/coder-cli-linux-amd64.tar.gz"
32+
fakeReleaseURLWindows = "https://github.com/cdr/coder-cli/releases/download/v1.23.4-rc.5/coder-cli-windows-amd64.zip"
33+
goosWindows = "windows"
34+
goosLinux = "linux"
3435
)
3536

3637
var (
@@ -116,6 +117,7 @@ func Test_updater_run(t *testing.T) {
116117
p.HTTPClient.M[fakeReleaseURLLinux] = newFakeGetterResponse(fakeValidTgzBytes, 200, variadicS(), nil)
117118
p.VersionF = func() string { return fakeOldVersion }
118119
p.ConfirmF = fakeConfirmYes
120+
p.Execer.M[p.ExecutablePath+".new --version"] = fakeExecerResult{[]byte(fakeNewVersion), nil}
119121
u := fromParams(p)
120122
assertFileContent(t, p.Fakefs, fakeExePathLinux, fakeOldVersion)
121123
err := u.Run(p.Ctx, false, fakeCoderURL, fakeNewVersion)
@@ -129,6 +131,7 @@ func Test_updater_run(t *testing.T) {
129131
p.HTTPClient.M[fakeReleaseURLLinux] = newFakeGetterResponse(fakeValidTgzBytes, 200, variadicS(), nil)
130132
p.VersionF = func() string { return fakeOldVersion }
131133
p.ConfirmF = fakeConfirmYes
134+
p.Execer.M[p.ExecutablePath+".new --version"] = fakeExecerResult{[]byte(fakeNewVersion), nil}
132135
u := fromParams(p)
133136
assertFileContent(t, p.Fakefs, fakeExePathLinux, fakeOldVersion)
134137
err := u.Run(p.Ctx, false, fakeCoderURL, "")
@@ -143,6 +146,7 @@ func Test_updater_run(t *testing.T) {
143146
p.HTTPClient.M[fakeReleaseURLLinux] = newFakeGetterResponse(fakeValidTgzBytes, 200, variadicS(), nil)
144147
p.VersionF = func() string { return fakeOldVersion }
145148
p.ConfirmF = fakeConfirmYes
149+
p.Execer.M[p.ExecutablePath+".new --version"] = fakeExecerResult{[]byte(fakeNewVersion), nil}
146150
u := fromParams(p)
147151
assertFileContent(t, p.Fakefs, p.ExecutablePath, fakeOldVersion)
148152
err := u.Run(p.Ctx, false, fakeCoderURL, "")
@@ -158,6 +162,7 @@ func Test_updater_run(t *testing.T) {
158162
p.HTTPClient.M[fakeReleaseURLWindows] = newFakeGetterResponse(fakeValidZipBytes, 200, variadicS(), nil)
159163
p.VersionF = func() string { return fakeOldVersion }
160164
p.ConfirmF = fakeConfirmYes
165+
p.Execer.M[p.ExecutablePath+".new --version"] = fakeExecerResult{[]byte(fakeNewVersion), nil}
161166
u := fromParams(p)
162167
assertFileContent(t, p.Fakefs, fakeExePathWindows, fakeOldVersion)
163168
err := u.Run(p.Ctx, false, fakeCoderURL, "")
@@ -170,6 +175,7 @@ func Test_updater_run(t *testing.T) {
170175
p.HTTPClient.M[apiPrivateVersionURL] = newFakeGetterResponse([]byte(fakeNewVersionJSON), 200, variadicS(), nil)
171176
p.HTTPClient.M[fakeReleaseURLLinux] = newFakeGetterResponse(fakeValidTgzBytes, 200, variadicS(), nil)
172177
p.VersionF = func() string { return fakeOldVersion }
178+
p.Execer.M[p.ExecutablePath+".new --version"] = fakeExecerResult{[]byte(fakeNewVersion), nil}
173179
u := fromParams(p)
174180
assertFileContent(t, p.Fakefs, fakeExePathLinux, fakeOldVersion)
175181
err := u.Run(p.Ctx, true, fakeCoderURL, "")
@@ -304,6 +310,20 @@ func Test_updater_run(t *testing.T) {
304310
assertFileContent(t, p.Fakefs, fakeExePathLinux, fakeOldVersion)
305311
})
306312

313+
run(t, "update coder - cannot exec new binary", func(t *testing.T, p *params) {
314+
fakeFile(t, p.Fakefs, fakeExePathLinux, 0755, fakeOldVersion)
315+
p.HTTPClient.M[apiPrivateVersionURL] = newFakeGetterResponse([]byte(fakeNewVersionJSON), 200, variadicS(), nil)
316+
p.HTTPClient.M[fakeReleaseURLLinux] = newFakeGetterResponse(fakeValidTgzBytes, 200, variadicS(), nil)
317+
p.VersionF = func() string { return fakeOldVersion }
318+
p.ConfirmF = fakeConfirmYes
319+
p.Execer.M[p.ExecutablePath+".new --version"] = fakeExecerResult{nil, fakeError}
320+
u := fromParams(p)
321+
assertFileContent(t, p.Fakefs, fakeExePathLinux, fakeOldVersion)
322+
err := u.Run(p.Ctx, false, fakeCoderURL, "")
323+
assertCLIError(t, "update coder - cannot exec new binary", err, "failed to check version of updated coder binary", "")
324+
assertFileContent(t, p.Fakefs, fakeExePathLinux, fakeOldVersion)
325+
})
326+
307327
if runtime.GOOS == goosWindows {
308328
run(t, "update coder - path blocklist - windows", func(t *testing.T, p *params) {
309329
p.ExecutablePath = `C:\Windows\system32\coder.exe`

0 commit comments

Comments
 (0)