implemented manual check and update (with signature verification)
Henry committed
Oct 20, 2014 at 15:33 UTC
7ddf3836d07665938c202a4c8f27daeec0571242
4 files changed
+79
-9
cmd/ipfs/equinox.yaml
new
+6
@@ -0,0 +1,6 @@
1
+---
2
+equinox-account: CHANGEME
3
+equinox-secret: CHANGEME
4
+equinox-app: CHANGEME
5
+channel: stable
6
+private-key: equinox-priv
core/commands/update.go
+46
-3
@@ -2,21 +2,64 @@ package commands
2
3
import (
4
"errors"
5
+ "fmt"
6
"io"
7
+ "os"
8
9
"github.com/jbenet/go-ipfs/core"
10
+ "github.com/jbenet/go-ipfs/updates"
11
)
12
13
// UpdateApply applys an update of the ipfs binary and shuts down the node if successful
14
func UpdateApply(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
12
- return errors.New("TODOUpdateApply")
15
+ fmt.Fprintln(out, "Current Version:", updates.Version)
16
+ u, err := updates.CheckForUpdate()
17
+ if err != nil {
18
+ return err
19
+ }
20
+
21
+ if u == nil {
22
+ fmt.Fprintln(out, "No update available")
23
+ return nil
24
+ }
25
+ fmt.Fprintln(out, "New Version:", u.Version)
26
+
27
+ if err = updates.AbleToApply(); err != nil {
28
+ return fmt.Errorf("Can't apply update: %v", err)
29
+ }
30
+
31
+ if err, errRecover := u.Update(); err != nil {
32
+ err = fmt.Errorf("Update failed: %v\n", err)
33
+ if errRecover != nil {
34
+ err = fmt.Errorf("%s\nRecovery failed! Cause: %v\nYou may need to recover manually", err, errRecover)
35
+ }
36
+ fmt.Fprint(out, err.Error())
37
+ return err
38
+ }
39
+
40
+ fmt.Fprintln(out, "Updated applied! Shutting down.")
41
+ os.Exit(0)
42
+ return nil
43
}
44
45
// UpdateCheck checks wether there is an update available
46
func UpdateCheck(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
17
- return errors.New("TODOUpdateCheck")
47
+ fmt.Fprintln(out, "Current Version:", updates.Version)
48
+ u, err := updates.CheckForUpdate()
49
+ if err != nil {
50
+ return err
51
+ }
52
+
53
+ if u == nil {
54
+ fmt.Fprintln(out, "No update available")
55
+ return nil
56
+ }
57
+
58
+ fmt.Fprintln(out, "New Version:", u.Version)
59
+ return nil
60
}
61
62
+// UpdateLog lists the version available online
63
func UpdateLog(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
21
- return errors.New("TODOUpdateLog")
64
+ return errors.New("Not yet implemented")
65
}
daemon/daemon.go
+2
@@ -141,6 +141,8 @@ func (dl *DaemonListener) handleConnection(conn manet.Conn) {
141
err = commands.Log(dl.node, command.Args, command.Opts, conn)
142
case "unpin":
143
err = commands.Unpin(dl.node, command.Args, command.Opts, conn)
144
+ case "updateApply":
145
+ err = commands.UpdateApply(dl.node, command.Args, command.Opts, conn)
146
default:
147
err = fmt.Errorf("Invalid Command: '%s'", command.Command)
148
}
updates/updates.go
+25
-6
@@ -1,18 +1,26 @@
1
package updates
2
3
import (
4
+ "fmt"
5
"os"
6
7
+ u "github.com/jbenet/go-ipfs/util"
8
+
9
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/coreos/go-semver/semver"
10
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/inconshreveable/go-update"
11
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/inconshreveable/go-update/check"
9
- u "github.com/jbenet/go-ipfs/util"
12
)
13
14
const (
13
- Version = "0.1.0" // actual current application's version literal
14
- UpdateEndpointURL = "https://api.equinox.io/1/Updates"
15
- UpdateAppID = "ap_ywkPmAR40q4EfdikN9Jh2hgIHi"
15
+ // Version is the current application's version literal
16
+ Version = "0.1.1"
17
+
18
+ updateEndpointURL = "https://api.equinox.io/1/Updates"
19
+ updateAppID = "CHANGEME"
20
+
21
+ updatePubKey = `-----BEGIN RSA PUBLIC KEY-----
22
+CHANGEME
23
+-----END RSA PUBLIC KEY-----`
24
)
25
26
var log = u.Logger("updates")
@@ -32,12 +40,23 @@ func parseVersion() (*semver.Version, error) {
40
return semver.NewVersion(Version)
41
}
42
43
+// CheckForUpdate checks the equinox.io api if there is an update available
44
func CheckForUpdate() (*check.Result, error) {
45
param := check.Params{
46
AppVersion: Version,
38
- AppId: UpdateAppID,
47
+ AppId: updateAppID,
48
Channel: "stable",
49
}
50
42
- return param.CheckForUpdate(UpdateEndpointURL, update.New())
51
+ up, err := update.New().VerifySignatureWithPEM([]byte(updatePubKey))
52
+ if err != nil {
53
+ return nil, fmt.Errorf("Failed to parse public key: %v", err)
54
+ }
55
+
56
+ return param.CheckForUpdate(updateEndpointURL, up)
57
+}
58
+
59
+// AbleToApply cheks if the running process is able to update itself
60
+func AbleToApply() error {
61
+ return update.New().CanUpdate()
62
}