initial commit for 0.5 release
This commit is contained in:
205
plugin.go
Normal file
205
plugin.go
Normal file
@@ -0,0 +1,205 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type (
|
||||
// Daemon defines Docker daemon parameters.
|
||||
Daemon struct {
|
||||
Registry string // Docker registry
|
||||
Mirror string // Docker registry mirror
|
||||
Insecure bool // Docker daemon enable insecure registries
|
||||
StorageDriver string // Docker daemon storage driver
|
||||
StoragePath string // Docker daemon storage path
|
||||
Disabled bool // DOcker daemon is disabled (already running)
|
||||
Debug bool // Docker daemon started in debug mode
|
||||
Bip string // Docker daemon network bridge IP address
|
||||
DNS []string // Docker daemon dns server
|
||||
}
|
||||
|
||||
// Login defines Docker login parameters.
|
||||
Login struct {
|
||||
Registry string // Docker registry address
|
||||
Username string // Docker registry username
|
||||
Password string // Docker registry password
|
||||
Email string // Docker registry email
|
||||
}
|
||||
|
||||
// Build defines Docker build parameters.
|
||||
Build struct {
|
||||
Name string // Docker build using default named tag
|
||||
Dockerfile string // Docker build Dockerfile
|
||||
Context string // Docker build context
|
||||
Tags []string // Docker build tags
|
||||
Args []string // Docker build args
|
||||
Repo string // Docker build repository
|
||||
Force bool // Docker build forces image tag creation
|
||||
}
|
||||
|
||||
// Plugin defines the Docker plugin parameters.
|
||||
Plugin struct {
|
||||
Login Login // Docker login configuration
|
||||
Build Build // Docker build configuration
|
||||
Daemon Daemon // Docker daemon configuration
|
||||
Dryrun bool // Docker push is skipped
|
||||
}
|
||||
)
|
||||
|
||||
// Exec executes the plugin step
|
||||
func (p Plugin) Exec() error {
|
||||
|
||||
// start the Docker daemon server
|
||||
if !p.Daemon.Disabled {
|
||||
cmd := commandDaemon(p.Daemon)
|
||||
if p.Daemon.Debug {
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
} else {
|
||||
cmd.Stdout = ioutil.Discard
|
||||
cmd.Stderr = ioutil.Discard
|
||||
}
|
||||
go func() {
|
||||
trace(cmd)
|
||||
cmd.Run()
|
||||
}()
|
||||
}
|
||||
|
||||
// poll the docker daemon until it is started. This ensures the daemon is
|
||||
// ready to accept connections before we proceed.
|
||||
for i := 0; i < 15; i++ {
|
||||
cmd := commandInfo()
|
||||
err := cmd.Run()
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
time.Sleep(time.Second * 1)
|
||||
}
|
||||
|
||||
// login to the Docker registry
|
||||
if p.Login.Password != "" {
|
||||
cmd := commandLogin(p.Login)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error authenticating: %s", err)
|
||||
}
|
||||
} else {
|
||||
fmt.Println("Registry credentials not provided. Guest mode enabled.")
|
||||
}
|
||||
|
||||
var cmds []*exec.Cmd
|
||||
cmds = append(cmds, commandVersion()) // docker version
|
||||
cmds = append(cmds, commandInfo()) // docker info
|
||||
cmds = append(cmds, commandBuild(p.Build)) // docker build
|
||||
|
||||
for _, tag := range p.Build.Tags {
|
||||
cmds = append(cmds, commandTag(p.Build, tag)) // docker tag
|
||||
|
||||
if p.Dryrun == false {
|
||||
cmds = append(cmds, commandPush(tag)) // docker push
|
||||
}
|
||||
}
|
||||
|
||||
// execute all commands in batch mode.
|
||||
for _, cmd := range cmds {
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
trace(cmd)
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// helper function to create the docker login command.
|
||||
func commandLogin(login Login) *exec.Cmd {
|
||||
return exec.Command(
|
||||
"/usr/bin/docker", "login",
|
||||
"-u", login.Username,
|
||||
"-p", login.Password,
|
||||
"-e", login.Email,
|
||||
login.Registry,
|
||||
)
|
||||
}
|
||||
|
||||
// helper function to create the docker info command.
|
||||
func commandVersion() *exec.Cmd {
|
||||
return exec.Command("/usr/bin/docker", "version")
|
||||
}
|
||||
|
||||
// helper function to create the docker info command.
|
||||
func commandInfo() *exec.Cmd {
|
||||
return exec.Command("/usr/bin/docker", "info")
|
||||
}
|
||||
|
||||
// helper function to create the docker build command.
|
||||
func commandBuild(build Build) *exec.Cmd {
|
||||
cmd := exec.Command(
|
||||
"/usr/bin/docker", "build",
|
||||
"--pull=true",
|
||||
"--rm=true",
|
||||
"-f", build.Dockerfile,
|
||||
"-t", build.Name,
|
||||
)
|
||||
for _, arg := range build.Args {
|
||||
cmd.Args = append(cmd.Args, "--build-arg", arg)
|
||||
}
|
||||
cmd.Args = append(cmd.Args, build.Context)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// helper function to create the docker tag command.
|
||||
func commandTag(build Build, tag string) *exec.Cmd {
|
||||
var (
|
||||
force = fmt.Sprintf("--force=%v", build.Force)
|
||||
from = build.Name
|
||||
to = fmt.Sprintf("%s:%s", build.Repo, tag)
|
||||
)
|
||||
return exec.Command(
|
||||
"/usr/bin/docker", "tag",
|
||||
force,
|
||||
from, to,
|
||||
)
|
||||
}
|
||||
|
||||
// helper function to create the docker push command.
|
||||
func commandPush(tag string) *exec.Cmd {
|
||||
return exec.Command("/usr/bin/docker", "push", tag)
|
||||
}
|
||||
|
||||
// helper function to create the docker daemon command.
|
||||
func commandDaemon(daemon Daemon) *exec.Cmd {
|
||||
args := []string{"daemon", "-g", daemon.StoragePath}
|
||||
|
||||
if daemon.StorageDriver != "" {
|
||||
args = append(args, "-s", daemon.StorageDriver)
|
||||
}
|
||||
if daemon.Insecure && daemon.Registry != "" {
|
||||
args = append(args, "--insecure-registry", daemon.Registry)
|
||||
}
|
||||
if len(daemon.Mirror) != 0 {
|
||||
args = append(args, "--registry-mirror", daemon.Mirror)
|
||||
}
|
||||
if len(daemon.Bip) != 0 {
|
||||
args = append(args, "--bip", daemon.Bip)
|
||||
}
|
||||
for _, dns := range daemon.DNS {
|
||||
args = append(args, "--dns", dns)
|
||||
}
|
||||
return exec.Command("/usr/bin/docker", args...)
|
||||
}
|
||||
|
||||
// trace writes each command to stdout with the command wrapped in an xml
|
||||
// tag so that it can be extracted and displayed in the logs.
|
||||
func trace(cmd *exec.Cmd) {
|
||||
fmt.Fprintf(os.Stdout, "<command>%s</command>", strings.Join(cmd.Args, " "))
|
||||
}
|
||||
Reference in New Issue
Block a user