-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
169 lines (140 loc) · 4.73 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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
package main
import (
"fmt"
"path/filepath"
"strings"
"github.com/docopt/docopt-go"
"github.com/mitchellh/go-homedir"
)
var (
HOME, _ = homedir.Dir()
ENVIRONMENTS_FILE = filepath.Join(HOME, ".gs3pload", "envs.json")
VERSION = "0.0.1"
)
func setBucket(name string, environmentType string, environmentName string) string {
var path, root string
pathSplit := strings.SplitN(name, "/", 2)
name = pathSplit[0]
switch name {
case "packages":
root = fmt.Sprintf("%s.%s", name, environmentName)
case "certs", "images", "stacks":
root = fmt.Sprintf("%s.%s", environmentName, name)
default:
root = name
}
if len(pathSplit) > 1 {
path = fmt.Sprintf("%s/%s", root, pathSplit[1])
} else {
path = root
}
if environmentType == "swift" {
return path
}
return fmt.Sprintf("%s://%s/", environmentType, path)
}
// Copy files to a given bucket and environment
func Copy(config string, bucket string, files []string, recursive bool, environment Environment) error {
command := NewCommand(environment.getBackend())
command.Copy(bucket, files, recursive)
if err := environment.Prepare(config); err != nil {
return err
}
return command.Execute()
}
// Public set public-read permissions for the given files
func Public(config string, bucket string, files []string, environment Environment) error {
command := NewCommand(environment.getBackend())
command.Public(bucket, files)
if err := environment.Prepare(config); err != nil {
return err
}
return command.Execute()
}
// DaisyChain copy an object from one path to another, where these
// can belong to different buckets or environments
func DaisyChain(config string, originPath, destPath string, recursive bool, environment Environment) error {
command := NewCommand(environment.getBackend())
command.DaisyChain(originPath, destPath, recursive)
if err := environment.Prepare(config); err != nil {
return err
}
return command.Execute()
}
// Backup given files within the same bucket with a .bak extension
func Backup(config string, files []string, bucket string, recursive bool, environment Environment) {
fmt.Printf("---> Creating backups on %s...\n", bucket)
for _, file := range files {
filePath := fmt.Sprintf("%s%s", bucket, file)
backupPath := fmt.Sprintf("%s%s%s", bucket, file, ".bak")
if err := DaisyChain(config, filePath, backupPath, recursive, environment); err != nil {
fmt.Printf("Skipping backup of %s (Did it exist before?). \n", filePath)
continue
}
}
}
// Push given files to multiple environments
func Push(environments Environments, envName string, bucketName string, files []string, recursive, public, backup bool) error {
for _, environment := range environments {
if envName == "" || envName == environment.Name {
fmt.Printf("---> Pushing to %s environment...\n", environment.Name)
bucket := setBucket(bucketName, environment.Type, environment.Name)
config := fmt.Sprintf("%s.boto", filepath.Join(HOME, ".gs3pload", environment.Name))
if backup {
Backup(config, files, bucket, recursive, environment)
}
if err := Copy(config, bucket, files, recursive, environment); err != nil {
fmt.Printf("Push failed on %s. %s\n", environment.Name, err)
continue
}
if public {
if err := Public(config, bucket, files, environment); err != nil {
fmt.Printf("Set as public failed on %s. %s\n", environment.Name, err)
continue
}
}
}
}
return nil
}
func main() {
usage := `gs3pload. Upload files to multiple S3 or Google Storage
buckets at once.
Bucket names "packages", "stacks", "certs" and "images" are reserved and resolved
by environment domain.
Usage:
gs3pload push [--envs <file>] [--env <name>] <bucket> <name>... [-r | --recursive] [-p | --public] [-b | --backup]
gs3pload -h | --help
gs3pload -v | --version
Options:
-h --help Show help.
--envs <file> Use a custom environments configuration.
-e --env <name> Environment name [default: ].
-p --public Set files as public.
-r --recursive Do a recursive copy.
-b --backup Create backup of pushed files if they exist.
-v --version Show version.
`
arguments, _ := docopt.Parse(usage, nil, true, fmt.Sprintf("gs3pload %s", VERSION), false)
push := arguments["push"].(bool)
bucketName := arguments["<bucket>"].(string)
fileNames := arguments["<name>"].([]string)
envs := arguments["--envs"]
envName := arguments["--env"].(string)
recursive := arguments["--recursive"].(bool)
public := arguments["--public"].(bool)
backup := arguments["--backup"].(bool)
environments := Environments{}
err := environments.Fetch(envs)
if err != nil {
fmt.Println(err)
return
}
if push {
err = Push(environments, envName, bucketName, fileNames, recursive, public, backup)
if err != nil {
fmt.Println(err)
return
}
}
}