forked from docker-archive/docker-bb
/
s3_utils.go
127 lines (108 loc) · 3.07 KB
/
s3_utils.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
118
119
120
121
122
123
124
125
126
127
package main
import (
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"strings"
"time"
log "github.com/Sirupsen/logrus"
"github.com/crowdmob/goamz/aws"
"github.com/crowdmob/goamz/s3"
"github.com/rakyll/magicmime"
)
func pushToS3(bundlesPath string) error {
if _, err := os.Stat(bundlesPath); os.IsNotExist(err) {
return fmt.Errorf("This is awkward, the bundles path DNE: %s", bundlesPath)
}
// use env variables to connect to s3
auth, err := aws.EnvAuth()
if err != nil {
return fmt.Errorf("AWS Auth failed: %v", err)
}
// connect to s3 bucket
s := s3.New(auth, aws.GetRegion(region))
bucketname, bucketpath := bucketParts(bucket)
bucket := s.Bucket(bucketname)
//walk the bundles directory
var html string
walkFn := func(fpath string, info os.FileInfo, err error) error {
stat, err := os.Stat(fpath)
if err != nil {
return err
}
relFilePath, err := filepath.Rel(bundlesPath, fpath)
if err != nil || (fpath == bundlesPath && stat.IsDir()) {
// Error getting relative path OR we are looking
// at the root path. Skip in both situations.
return nil
}
if stat.IsDir() {
return nil
}
if err = uploadFileToS3(bucket, fpath, path.Join(bucketpath, relFilePath)); err != nil {
log.Warnf("Uploading %s to s3 failed: %v", fpath, err)
return err
}
// add to html
image := "default"
if strings.HasSuffix(relFilePath, ".sha256") || strings.HasSuffix(relFilePath, ".md5") {
image = "text"
}
html += fmt.Sprintf(`<tr>
<td valign="top"><a href="%s"><img src="/static/%s.png" alt="[ICO]"/></a></td>
<td><a href="%s">%s</a></td>
<td>%s</td>
<td>%s</td>
</tr>`, relFilePath, image, relFilePath, relFilePath, humanSize(stat.Size()), stat.ModTime().Format(time.RFC3339))
return nil
}
// walk the filepath
if err := filepath.Walk(bundlesPath, walkFn); err != nil {
return err
}
// add html to template
if err := createIndexFile(bucket, bucketpath, html); err != nil {
return err
}
return nil
}
func uploadFileToS3(bucket *s3.Bucket, fpath, s3path string) error {
// try to get the mime type
mimetype := ""
err := magicmime.Open(magicmime.MAGIC_MIME_TYPE | magicmime.MAGIC_SYMLINK | magicmime.MAGIC_ERROR)
if err != nil {
log.Debugf("Magic meme failed for: %v", err)
} else {
mimetype, err = magicmime.TypeByFile(fpath)
if err != nil {
log.Debugf("Mime type detection for %s failed: %v", fpath, err)
}
}
contents, err := ioutil.ReadFile(fpath)
if err != nil {
log.Warnf("Reading %q failed: %v", fpath, err)
}
// push the file to s3
log.Debugf("Pushing %s to s3", s3path)
if err := bucket.Put(s3path, contents, mimetype, "public-read", s3.Options{CacheControl: "no-cache"}); err != nil {
return err
}
log.Infof("Sucessfully pushed %s to s3", s3path)
return nil
}
// parse for the parts of the bucket name
func bucketParts(bucket string) (bucketname, path string) {
s3Prefix := "s3://"
if strings.HasPrefix(bucket, s3Prefix) {
bucket = strings.Replace(bucket, s3Prefix, "", 1)
}
parts := strings.SplitN(bucket, "/", 2)
if len(parts) <= 1 {
path = ""
} else {
path = parts[1]
}
return parts[0], path
}