-
Notifications
You must be signed in to change notification settings - Fork 15
/
glidergun.go
117 lines (109 loc) · 2.29 KB
/
glidergun.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package main
import (
"archive/tar"
"bytes"
"compress/gzip"
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"encoding/hex"
"fmt"
"hash"
"io"
"io/ioutil"
"net/http"
"os"
"github.com/progrium/go-basher"
"gopkg.in/inconshreveable/go-update.v0"
)
const (
LatestDownloadUrl = "https://dl.gliderlabs.com/glidergun/latest/%s.tgz"
)
var Version string
func fatal(msg string) {
println("!!", msg)
os.Exit(2)
}
func Selfupdate(args []string) {
up := update.New()
err := up.CanUpdate()
if err != nil {
fatal("Can't update because: '" + err.Error() + "'. Try as root?")
}
checksumExpected, err := hex.DecodeString(args[1])
if err != nil {
fatal(err.Error())
}
url := fmt.Sprintf(LatestDownloadUrl, args[0])
fmt.Printf("Downloading %v ...\n", url)
resp, err := http.Get(url)
if err != nil {
fatal(err.Error())
}
defer resp.Body.Close()
buf := new(bytes.Buffer)
data, err := ioutil.ReadAll(io.TeeReader(resp.Body, buf))
if err != nil {
fatal(err.Error())
}
checksum := sha256.New().Sum(data)
if bytes.Equal(checksum, checksumExpected) {
fatal("Checksum failed. Got: " + fmt.Sprintf("%x", checksum))
}
z, err := gzip.NewReader(buf)
if err != nil {
fatal(err.Error())
}
defer z.Close()
t := tar.NewReader(z)
hdr, err := t.Next()
if err != nil {
fatal(err.Error())
}
if hdr.Name != "gun" {
fatal("glidergun binary not found in downloaded tarball")
}
err, errRecover := up.FromStream(t)
if err != nil {
fmt.Printf("Update failed: %v\n", err)
if errRecover != nil {
fmt.Printf("Failed to recover bad update: %v!\n", errRecover)
fmt.Printf("Program exectuable may be missing!\n")
}
os.Exit(2)
}
fmt.Println("Updated.")
}
func Checksum(args []string) {
if len(args) < 1 {
fatal("No algorithm specified")
}
var h hash.Hash
switch args[0] {
case "md5":
h = md5.New()
case "sha1":
h = sha1.New()
case "sha256":
h = sha256.New()
default:
fatal("Algorithm '" + args[0] + "' is unsupported")
}
io.Copy(h, os.Stdin)
fmt.Printf("%x\n", h.Sum(nil))
}
func main() {
os.Setenv("GUN_VERSION", Version)
basher.Application(map[string]func([]string){
"checksum": Checksum,
"selfupdate": Selfupdate,
}, []string{
"src/fn.bash",
"src/cmd.bash",
"src/env.bash",
"src/gun.bash",
"src/module.bash",
"src/deps.bash",
"src/color.bash",
}, Asset, true)
}