forked from drone-plugins/drone-docker
/
main.go
156 lines (138 loc) · 3.29 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
package main
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"strings"
"time"
"github.com/drone/drone-plugin-go/plugin"
)
type Docker struct {
Storage string `json:"storage_driver"`
Registry string `json:"registry"`
Username string `json:"username"`
Password string `json:"password"`
Email string `json:"email"`
Auth string `json:"auth"`
Repo string `json:"repo"`
Tag string `json:"tag"`
File string `json:"file"`
}
func main() {
clone := plugin.Clone{}
vargs := Docker{}
plugin.Param("clone", &clone)
plugin.Param("vargs", &vargs)
if err := plugin.Parse(); err != nil {
println(err.Error())
os.Exit(1)
}
// Set the storage driver
if len(vargs.Storage) == 0 {
vargs.Storage = "aufs"
}
stop := func() {
cmd := exec.Command("start-stop-daemon", "--stop", "--pidfile", "/var/run/docker.pid")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
trace(cmd)
cmd.Run()
}
defer stop()
// Starts the Docker daemon
go func() {
cmd := exec.Command("/bin/bash", "/bin/wrapdocker")
cmd.Stdout = ioutil.Discard
cmd.Stderr = ioutil.Discard
cmd.Run()
cmd = exec.Command("docker", "-d", "-s", vargs.Storage)
cmd.Stdout = ioutil.Discard
cmd.Stderr = ioutil.Discard
trace(cmd)
cmd.Run()
}()
// Sleep for a few seconds
time.Sleep(5 * time.Second)
// Set the Registry value
if len(vargs.Registry) == 0 {
vargs.Registry = "https://index.docker.io/v1/"
}
// Set the Dockerfile path
if len(vargs.File) == 0 {
vargs.File = "."
}
// Set the Tag value
switch vargs.Tag {
case "$DRONE_BRANCH":
vargs.Tag = clone.Branch
case "$DRONE_COMMIT":
vargs.Tag = clone.Sha
case "":
vargs.Tag = "latest"
}
vargs.Repo = fmt.Sprintf("%s:%s", vargs.Repo, vargs.Tag)
// Login to Docker
cmd := exec.Command("docker", "login", "-u", vargs.Username, "-p", vargs.Password, "-e", vargs.Email, vargs.Registry)
cmd.Dir = clone.Dir
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
stop()
os.Exit(1)
}
// Docker environment info
cmd = exec.Command("docker", "version")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
trace(cmd)
cmd.Run()
cmd = exec.Command("docker", "info")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
trace(cmd)
cmd.Run()
// Build the container
cmd = exec.Command("docker", "build", "--pull=true", "--rm=true", "-t", vargs.Repo, vargs.File)
cmd.Dir = clone.Dir
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
trace(cmd)
err = cmd.Run()
if err != nil {
stop()
os.Exit(1)
}
// Push the container
cmd = exec.Command("docker", "push", vargs.Repo)
cmd.Dir = clone.Dir
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
trace(cmd)
err = cmd.Run()
if err != nil {
stop()
os.Exit(1)
}
}
// Trace writes each command to standard error (preceded by a ‘$ ’) before it
// is executed. Used for debugging your build.
func trace(cmd *exec.Cmd) {
fmt.Println("$", strings.Join(cmd.Args, " "))
}
// authorize is a helper function that authorizes the Docker client
// by manually creating the Docker authentication file.
func authorize(d *Docker) error {
var path = "/root/.dockercfg" // TODO should probably use user.Home() for good measure
var data = fmt.Sprintf(dockerconf, d.Registry, d.Auth, d.Email)
return ioutil.WriteFile(path, []byte(data), 0644)
}
var dockerconf = `
{
"%s": {
"auth": "%s",
"email": "%s"
}
}
`