/
main.go
114 lines (97 loc) · 2.87 KB
/
main.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
package main
import (
"fmt"
"io/ioutil"
"mime"
"os"
"strings"
"sync"
"golang.org/x/net/context"
"github.com/kelseyhightower/envconfig"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/cloud"
"google.golang.org/cloud/storage"
)
// Config is the envconfig compatible struct to store config values that are input to gcsup
type Config struct {
JWTFileLocation string `required:"true" envconfig:"jwt_file_location"`
ProjectName string `required:"true" envconfig:"project_name"`
BucketName string `required:"true" envconfig:"bucket_name"`
LocalFolder string `required:"true" envconfig:"local_folder"`
}
func main() {
var conf Config
if err := envconfig.Process("gcsup", &conf); err != nil {
fmt.Printf("Error with configuration [%s]", err)
os.Exit(1)
}
data, err := ioutil.ReadFile(conf.JWTFileLocation)
if err != nil {
fmt.Printf("Error reading file [%s]\n", err)
os.Exit(1)
}
jwtConf, err := google.JWTConfigFromJSON(data, storage.ScopeFullControl)
if err != nil {
fmt.Printf("Error creating JWT config [%s]\n", err)
os.Exit(1)
}
fmt.Printf("Uploading %s to gcs://%s/%s\n", conf.LocalFolder, conf.ProjectName, conf.BucketName)
ctx := cloud.NewContext(conf.ProjectName, jwtConf.Client(oauth2.NoContext))
client, err := storage.NewClient(ctx)
if err != nil {
fmt.Printf("Error creating GCS client [%s]\n", err)
os.Exit(1)
}
bucket := client.Bucket(conf.BucketName)
files, err := getAllFiles(conf.LocalFolder)
if err != nil {
fmt.Printf("Error gathering all files [%s]\n", err)
os.Exit(1)
}
var wg sync.WaitGroup
for _, file := range files {
from := file.AbsolutePath
to := strings.TrimPrefix(file.RelativePath, conf.LocalFolder)
fmt.Printf("Uploading %s to %s\n", from, to)
wg.Add(1)
go func(ctx context.Context, bucket *storage.BucketHandle, conf Config, from, to string) {
defer wg.Done()
if err := upload(ctx, client.Bucket(conf.BucketName), conf, from, to); err != nil {
fmt.Printf("Error uploading %s to %s (%s)\n", from, to, err)
}
}(ctx, bucket, conf, from, to)
}
fmt.Println("Waiting for all uploads to finish...")
wg.Wait()
fmt.Println("Done")
}
func upload(ctx context.Context, bucket *storage.BucketHandle, conf Config, from, to string) error {
fileBytes, err := ioutil.ReadFile(from)
if err != nil {
return err
}
obj := bucket.Object(to)
w := obj.NewWriter(ctx)
if _, err := w.Write(fileBytes); err != nil {
return err
}
if err := w.Close(); err != nil {
fmt.Printf("ERROR closing writer for upload %s => %s (%s)\n", from, to, err)
return err
}
extension := from[strings.LastIndex(from, "."):]
attrs := storage.ObjectAttrs{
ACL: []storage.ACLRule{
storage.ACLRule{
Entity: storage.AllUsers,
Role: storage.RoleReader,
},
},
ContentType: mime.TypeByExtension(extension),
}
if _, err := obj.Update(ctx, attrs); err != nil {
return err
}
return nil
}