@@ -31,6 +31,53 @@ func StatusCB(status *Status) mqtt.MessageHandler {
3131 }
3232}
3333
34+ type UpdatePayload struct {
35+ URL string `json:"url"`
36+ Signature string `json:"signature"`
37+ Token string `json:"token"`
38+ }
39+
40+ // UpdateCB handles the connector autoupdate
41+ // Any URL must be signed with Arduino private key
42+ func UpdateCB (status * Status ) mqtt.MessageHandler {
43+ return func (client mqtt.Client , msg mqtt.Message ) {
44+ var info UpdatePayload
45+ err := json .Unmarshal (msg .Payload (), & info )
46+ if err != nil {
47+ status .Error ("/update" , errors .Wrapf (err , "unmarshal %s" , msg .Payload ()))
48+ return
49+ }
50+ executablePath , _ := os .Executable ()
51+ name := filepath .Join (os .TempDir (), filepath .Base (executablePath ))
52+ err = downloadFile (name , info .URL , info .Token )
53+ err = downloadFile (name + ".sig" , info .URL + ".sig" , info .Token )
54+ if err != nil {
55+ status .Error ("/update" , errors .Wrap (err , "no signature file " + info .URL + ".sig" ))
56+ return
57+ }
58+ // check the signature
59+ err = checkGPGSig (name , name + ".sig" )
60+ if err != nil {
61+ status .Error ("/update" , errors .Wrap (err , "wrong signature " + info .URL + ".sig" ))
62+ return
63+ }
64+ // chmod it
65+ err = os .Chmod (name , 0744 )
66+ if err != nil {
67+ status .Error ("/update" , errors .Wrapf (err , "chmod 744 %s" , name ))
68+ return
69+ }
70+ // copy it over existing binary
71+ copyFileAndRemoveOriginal (name , executablePath )
72+ if err != nil {
73+ status .Error ("/update" , errors .Wrap (err , "error copying itself from " + name + " to " + executablePath ))
74+ return
75+ }
76+ // leap of faith: kill itself, systemd should respawn the process
77+ os .Exit (0 )
78+ }
79+ }
80+
3481// UploadPayload contains the name and url of the sketch to upload on the device
3582type UploadPayload struct {
3683 ID string `json:"id"`
0 commit comments