Skip to content

Commit 6db5ade

Browse files
authored
Merge pull request #551 from arduino/autoupdate
Three-card trick for autoupdate on osx
2 parents a23bd53 + fd8b606 commit 6db5ade

File tree

4 files changed

+69
-0
lines changed

4 files changed

+69
-0
lines changed

Diff for: go.sum

+7
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ github.com/codeclysm/extract v2.0.0+incompatible/go.mod h1:2nhFMPHiU9At61hz+12bf
55
github.com/creack/goselect v0.0.0-20180501195510-58854f77ee8d h1:6o8WW5zZ+Ny9sbk69epnAPmBzrBaRnvci+l4+pqleeY=
66
github.com/creack/goselect v0.0.0-20180501195510-58854f77ee8d/go.mod h1:gHrIcH/9UZDn2qgeTUeW5K9eZsVYCH6/60J/FHysWyE=
77
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
8+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
89
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
910
github.com/davidmz/go-pageant v1.0.1/go.mod h1:WWOKE/93DhgsPq15jaipH4fVY+MLKKWH4Yku5Ei92rE=
11+
github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598 h1:MGKhKyiYrvMDZsmLR/+RGffQSXwEkXgfLSA08qDn9AI=
1012
github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598/go.mod h1:0FpDmbrt36utu8jEmeU05dPC9AB5tsLYVVi+ZHfyuwI=
1113
github.com/dimfeld/httptreemux v5.0.1+incompatible h1:Qj3gVcDNoOthBAqftuD596rm4wg/adLLz5xh5CmpiCA=
1214
github.com/dimfeld/httptreemux v5.0.1+incompatible/go.mod h1:rbUlSV+CCpv/SuqUTP/8Bk2O3LyUV436/yaRGkhP6Z0=
@@ -63,13 +65,15 @@ github.com/lxn/walk v0.0.0-20191113135339-bf589de20b3c/go.mod h1:E23UucZGqpuUANJ
6365
github.com/lxn/walk v0.0.0-20191128110447-55ccb3a9f5c1/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ=
6466
github.com/lxn/win v0.0.0-20191106123917-121afc750dd3/go.mod h1:ouWl4wViUNh8tPSIwxTVMuS014WakR1hqvBc2I0bMoA=
6567
github.com/lxn/win v0.0.0-20191128105842-2da648fda5b4/go.mod h1:ouWl4wViUNh8tPSIwxTVMuS014WakR1hqvBc2I0bMoA=
68+
github.com/manveru/faker v0.0.0-20171103152722-9fbc68a78c4d h1:Zj+PHjnhRYWBK6RqCDBcAhLXoi3TzC27Zad/Vn+gnVQ=
6669
github.com/manveru/faker v0.0.0-20171103152722-9fbc68a78c4d/go.mod h1:WZy8Q5coAB1zhY9AOBJP0O6J4BuDfbupUDavKY+I3+s=
6770
github.com/mattn/go-isatty v0.0.2-0.20170307163044-57fdcb988a5c h1:vNDTotKSxm/15mLGhBXjdU6q6Ncrx0HlVEd8ToAsGTw=
6871
github.com/mattn/go-isatty v0.0.2-0.20170307163044-57fdcb988a5c/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
6972
github.com/mattn/go-shellwords v1.0.3 h1:K/VxK7SZ+cvuPgFSLKi5QPI9Vr/ipOf4C1gN+ntueUk=
7073
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
7174
github.com/miekg/dns v1.0.15 h1:9+UupePBQCG6zf1q/bGmTO1vumoG13jsrbWOSX1W6Tw=
7275
github.com/miekg/dns v1.0.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
76+
github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0=
7377
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
7478
github.com/oleksandr/bonjour v0.0.0-20160508152359-5dcf00d8b228 h1:Cvfd2dOlXIPTeEkOT/h8PyK4phBngOM4at9/jlgy7d4=
7579
github.com/oleksandr/bonjour v0.0.0-20160508152359-5dcf00d8b228/go.mod h1:MGuVJ1+5TX1SCoO2Sx0eAnjpdRytYla2uC1YIZfkC9c=
@@ -80,6 +84,7 @@ github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
8084
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
8185
github.com/pkg/sftp v1.8.3 h1:9jSe2SxTM8/3bXZjtqnkgTBW+lA8db0knZJyns7gpBA=
8286
github.com/pkg/sftp v1.8.3/go.mod h1:NxmoDg/QLVWluQDUYG7XBZTLUpKeFa8e3aMf1BfjyHk=
87+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
8388
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
8489
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
8590
github.com/sfreiberg/simplessh v0.0.0-20180301191542-495cbb862a9c h1:7Q+2oF0uBoLEV+j13E3/xUkPkI7f+sFNPZOPo2jmrWk=
@@ -91,11 +96,13 @@ github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c/go.mod h1:s
9196
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
9297
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
9398
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
99+
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
94100
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
95101
github.com/ugorji/go v0.0.0-20170215201144-c88ee250d022 h1:wIYK3i9zY6ZBcWw4GFvoPVwtb45iEm8KyOVmDhSLvsE=
96102
github.com/ugorji/go v0.0.0-20170215201144-c88ee250d022/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
97103
github.com/xrash/smetrics v0.0.0-20170218160415-a3153f7040e9 h1:w8V9v0qVympSF6GjdjIyeqR7+EVhAF9CBQmkmW7Zw0w=
98104
github.com/xrash/smetrics v0.0.0-20170218160415-a3153f7040e9/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
105+
github.com/zach-klippenstein/goregen v0.0.0-20160303162051-795b5e3961ea h1:CyhwejzVGvZ3Q2PSbQ4NRRYn+ZWv5eS1vlaEusT+bAI=
99106
github.com/zach-klippenstein/goregen v0.0.0-20160303162051-795b5e3961ea/go.mod h1:eNr558nEUjP8acGw8FFjTeWvSgU1stO7FAO6eknhHe4=
100107
go.bug.st/downloader v0.0.0-20181116113543-9b8976a44d87 h1:8W/hwyrc25HrXxbtG8Ghiwgq/hDB8KCh7hKMf78gp90=
101108
go.bug.st/downloader v0.0.0-20181116113543-9b8976a44d87/go.mod h1:OUL7bexo6Ir+BRE5E7Cs3qUvO6ZgJL5Hjk/qwiy6Ze0=

Diff for: main.go

+39
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ package main
66
import (
77
"encoding/json"
88
"flag"
9+
"io/ioutil"
910
"os"
1011
"os/user"
1112
"path/filepath"
13+
"runtime"
1214
"runtime/debug"
1315
"strconv"
1416
"strings"
@@ -17,6 +19,7 @@ import (
1719

1820
"github.com/arduino/arduino-create-agent/systray"
1921
"github.com/arduino/arduino-create-agent/tools"
22+
"github.com/arduino/arduino-create-agent/updater"
2023
"github.com/arduino/arduino-create-agent/utilities"
2124
v2 "github.com/arduino/arduino-create-agent/v2"
2225
"github.com/gin-gonic/gin"
@@ -96,6 +99,9 @@ func launchSelfLater() {
9699
}
97100

98101
func main() {
102+
// prevents bad errors in OSX, such as '[NS...] is only safe to invoke on the main thread'.
103+
runtime.LockOSThread()
104+
99105
// Parse regular flags
100106
flag.Parse()
101107

@@ -118,9 +124,42 @@ func main() {
118124
AdditionalConfig: *additionalConfig,
119125
}
120126

127+
path, err := osext.Executable()
128+
if err != nil {
129+
panic(err)
130+
}
131+
132+
// If the executable is temporary, copy it to the full path, then restart
133+
if strings.Contains(path, "-temp") {
134+
err := copyExe(path, updater.BinPath(path))
135+
if err != nil {
136+
panic(err)
137+
}
138+
139+
Systray.Restart()
140+
} else {
141+
// Otherwise copy to a path with -temp suffix
142+
err := copyExe(path, updater.TempPath(path))
143+
if err != nil {
144+
panic(err)
145+
}
146+
}
147+
121148
Systray.Start()
122149
}
123150

151+
func copyExe(from, to string) error {
152+
data, err := ioutil.ReadFile(from)
153+
if err != nil {
154+
return err
155+
}
156+
err = ioutil.WriteFile(to, data, 0755)
157+
if err != nil {
158+
return err
159+
}
160+
return nil
161+
}
162+
124163
func loop() {
125164
if *hibernate {
126165
return

Diff for: update.go

+2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ func updateHandler(c *gin.Context) {
6060
return
6161
}
6262

63+
path = updater.TempPath(path)
64+
6365
c.JSON(200, gin.H{"success": "Please wait a moment while the agent reboots itself"})
6466
Systray.Update(path)
6567
}

Diff for: updater/updater.go

+21
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"os"
1313
"path/filepath"
1414
"runtime"
15+
"strings"
1516
"time"
1617

1718
"github.com/kr/binarydist"
@@ -56,6 +57,22 @@ const devValidTime = 7 * 24 * time.Hour
5657
var errHashMismatch = errors.New("new file hash mismatch after patch")
5758
var up = update.New()
5859

60+
// TempPath generates a temporary path for the executable
61+
func TempPath(path string) string {
62+
if filepath.Ext(path) == "exe" {
63+
path = strings.Replace(path, ".exe", "-temp.exe", -1)
64+
} else {
65+
path = path + "-temp"
66+
}
67+
68+
return path
69+
}
70+
71+
// TempPath generates the proper path for a temporary executable
72+
func BinPath(path string) string {
73+
return strings.Replace(path, "-temp", "", -1)
74+
}
75+
5976
// Updater is the configuration and runtime data for doing an update.
6077
//
6178
// Note that ApiURL, BinURL and DiffURL should have the same value if all files are available at the same location.
@@ -202,6 +219,9 @@ func (u *Updater) update() error {
202219
if err != nil {
203220
return err
204221
}
222+
223+
path = TempPath(path)
224+
205225
old, err := os.Open(path)
206226
if err != nil {
207227
return err
@@ -241,6 +261,7 @@ func (u *Updater) update() error {
241261
// it can't be renamed if a handle to the file is still open
242262
old.Close()
243263

264+
up.TargetPath = path
244265
err, errRecover := up.FromStream(bytes.NewBuffer(bin))
245266
if errRecover != nil {
246267
log.Errorf("update and recovery errors: %q %q", err, errRecover)

0 commit comments

Comments
 (0)