surtur
1850fd64c2
rebased on master + applied the previous changes commit b96d5245e363b8e465c95fde3dd7d3a00078da07 Author: surtur <a_mirre@utb.cz> Date: Fri Oct 22 14:28:24 2021 +0200 chore: bump dind to 20.10.9 commit ca9cfe9733edef3df9ecae19d51976ea6371baf5 Author: surtur <a_mirre@utb.cz> Date: Tue Jun 8 22:32:45 2021 +0200 chore: bump docker to 20.10.7-dind commit 5dc2b561ae0cc0e75cf7f8ec78daeb0f1b2eafcd Author: surtur <a_mirre@utb.cz> Date: Tue Apr 13 10:00:07 2021 +0200 chore: bump docker to 20.10.6-dind commit 6dc63b2b1d7ec133ae2b4a210f625364faa973b1 Author: surtur <a_mirre@utb.cz> Date: Wed Mar 17 02:35:29 2021 +0100 chore: bump docker to 20.10.5-dind commit 1ae4536a1e38d54e3d29812b70e52fabd25530b7 Author: surtur <a_mirre@utb.cz> Date: Wed Mar 17 01:11:36 2021 +0100 docker: add multiple different image tags rolling: * latest * edge-dind fixed to a commit: * ${DRONE_COMMIT_SHA:0:8} * ${DRONE_COMMIT_SHA:0:8}-edge-dind * ${DRONE_COMMIT_SHA:0:8}-linux-amd64 commit 6b86978633e0b5ba039bb5139a4f9d83ce5b0e35 Author: surtur <a_mirre@utb.cz> Date: Wed Mar 17 02:22:36 2021 +0100 ci: use plugins/docker:linux-amd64 * bump from :18 * add repo tag for dry_run commit 2a52c7ee365d4e05d6657fe0481af4c073c59d62 Author: surtur <a_mirre@utb.cz> Date: Tue Mar 16 22:26:30 2021 +0100 chore: bump docker to 19.03.15-dind commit e5693c332a0e81366085ce9508590242f5e79f5a Author: surtur <a_mirre@utb.cz> Date: Tue Mar 16 21:53:51 2021 +0100 ci: dry-run on push+publish to immawanderer commit 07c40b46a61421b1c3a6aa6bc4edaf089631c360 Author: surtur <a_mirre@utb.cz> Date: Tue Mar 16 19:59:34 2021 +0100 jsonnet: thow out {arm,gcr,acr,heroku} stuff commit f0056159bf98e9130d1af882f08fdde2e382629c Author: surtur <a_mirre@utb.cz> Date: Tue Mar 16 19:26:12 2021 +0100 ci: edit .drone.yml to only build for linux-amd64 * rm windows pipelines as I don't have any windows runners * rm arm/arm64 pipelines as I don't have any arm runners * rm {ecr,acr,whatever} publish steps as we're not publishing anything just yet * tag the image under immawanderer, not the official plugins repo * run as a dry_run (cause we're not really publishing, right?) commit 6ec5e7141117e1489faa378b1c00e459d789642d Merge: 88f8bf1 0911e6a Author: TP Honey <tp@harness.io> Date: Wed Oct 13 17:19:30 2021 +0100 Merge pull request #338 from tphoney/bump-go-1.13 (maint) bump git to 1.13 for build and test commit 0911e6a922663d52e1d9e4dfdee51a383d2b95fa Author: TP Honey <tp@harness.io> Date: Wed Oct 13 14:49:29 2021 +0100 (maint) bump git to 1.13 for build and test commit 88f8bf1cb0c41297dbe8f5bb5ff1006b51a9f718 Merge: 607b04a 2d70a1f Author: TP Honey <tp@harness.io> Date: Wed Oct 13 14:32:03 2021 +0100 Merge pull request #337 from tphoney/prep_v19.03.9 (maint) v19.03.9 release prep commit 2d70a1fa7cb4a8f2afe38cad3a1984804f1df464 Author: TP Honey <tp@harness.io> Date: Wed Oct 13 14:24:58 2021 +0100 (maint) v19.03.9 release prep commit 607b04a8719332e8bbef6ff76ac26e30715df060 Merge: 72ef7b1 e44c2d4 Author: Eoin McAfee <83226740+eoinmcafee00@users.noreply.github.com> Date: Thu Sep 23 15:52:24 2021 +0100 Merge pull request #333 from jimsheldon/ecr-externalid adding support for externalId commit e44c2d46eafd5f223ac246eb003bc6b3427b3374 Author: Jim Sheldon <jim.sheldon@meltwater.com> Date: Fri Sep 17 15:33:05 2021 -0400 adding support for externalId commit 72ef7b1f3fa6c47c58f33ca312bdc8c484b6c5a4 Author: Brad Rydzewski <bradley.rydzewski@harness.io> Date: Mon Aug 2 22:15:39 2021 -0400 log available credentials before login commit fbbeec5a2e5845e488100da3885dc630fa3468fe Author: Brad Rydzewski <bradley.rydzewski@harness.io> Date: Mon Aug 2 21:42:22 2021 -0400 use Replace instead of ReplaceAll commit b1d8698d1c5eb834b0703939e1001d23152300d2 Author: Brad Rydzewski <bradley.rydzewski@harness.io> Date: Mon Aug 2 21:28:37 2021 -0400 print login failure reason to output commit d4cf9f20f175ae550b11e0eeb44604c6d71bee20 Author: Brad Rydzewski <brad.rydzewski@gmail.com> Date: Sun Jul 11 15:50:43 2021 -0400 remove pull always commit f75380013d16585f4e4038483d6b948f0c025ff4 Merge: dd359df c10d367 Author: Brad Rydzewski <brad.rydzewski@gmail.com> Date: Sun Jul 11 15:39:35 2021 -0400 Merge pull request #325 from drone-plugins/revert-322-update-seccomp Revert "Update seccomp to 20.10 docker" commit c10d36754ccf53341f462a2e9f703315cc31f0cf Author: Brad Rydzewski <brad.rydzewski@gmail.com> Date: Sun Jul 11 15:38:04 2021 -0400 Revert "Update seccomp to 20.10 docker (#322)" This reverts commit dd359dfc7242b257f0f2078f1ef9027391d0bd0a. commit dd359dfc7242b257f0f2078f1ef9027391d0bd0a Author: techknowlogick <matti@mdranta.net> Date: Wed Jul 7 15:03:54 2021 -0400 Update seccomp to 20.10 docker (#322) * Update seccomp to 20.10 docker commit 729aa5d300a4085cfa6e0e8776368710a7fa96be Merge: f08821b db5c216 Author: TP Honey <tp@harness.io> Date: Wed Jul 7 19:52:19 2021 +0100 Merge pull request #323 from tphoney/docker_rate_limit (maint) CI, remove the dry run steps, due to rate limiting commit db5c2161febe6292386d9dc7dd8e20047219d15e Author: TP Honey <tp@harness.io> Date: Wed Jul 7 19:37:30 2021 +0100 (maint) CI, remove the dry run steps, due to rate limiting commit f08821b02496bfa8814d688523e170156050128f Merge: 0f6bd8a 5760e7b Author: Brad Rydzewski <brad.rydzewski@gmail.com> Date: Tue Apr 6 15:55:56 2021 -0400 Merge pull request #300 from rvoitenko/ecr_scan_on_push ECR: adding setting to enable image scanning while repo creation commit 5760e7b4e821a89805454f614cf2635f7ff7dc96 Merge: 3501d9a 7ade37a Author: Roman Voitenko <r00mka@gmail.com> Date: Sat Feb 20 13:32:16 2021 +0100 Merge branch 'master' into ecr_scan_on_push commit 3501d9a65d0f773b01cf2c1a50d13a7726bca166 Author: Roman Voitenko <roman.voitenko@konsult.atg.se> Date: Thu Oct 1 10:43:25 2020 +0200 add possibility to turn on/off image scanning not only during repo creation, but when repo already created commit d8b6b48fa34561c16680cc5787ab97b3f18b2141 Author: Roman Voitenko <roman.voitenko@konsult.atg.se> Date: Wed Sep 30 23:32:23 2020 +0200 add possibility to turn on ECR image scanning for repos created by ecr plugin
479 lines
13 KiB
Go
479 lines
13 KiB
Go
package docker
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"runtime"
|
|
"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
|
|
DNSSearch []string // Docker daemon dns search domain
|
|
MTU string // Docker daemon mtu setting
|
|
IPv6 bool // Docker daemon IPv6 networking
|
|
Experimental bool // Docker daemon enable experimental mode
|
|
}
|
|
|
|
// 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
|
|
Config string // Docker Auth Config
|
|
}
|
|
|
|
// Build defines Docker build parameters.
|
|
Build struct {
|
|
Remote string // Git remote URL
|
|
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
|
|
ArgsEnv []string // Docker build args from env
|
|
Target string // Docker build target
|
|
Squash bool // Docker build squash
|
|
Pull bool // Docker build pull
|
|
CacheFrom []string // Docker build cache-from
|
|
Compress bool // Docker build compress
|
|
Repo string // Docker build repository
|
|
LabelSchema []string // label-schema Label map
|
|
AutoLabel bool // auto-label bool
|
|
Labels []string // Label map
|
|
Link string // Git repo link
|
|
NoCache bool // Docker build no-cache
|
|
Secret string // secret keypair
|
|
AddHost []string // Docker build add-host
|
|
Quiet bool // Docker build quiet
|
|
}
|
|
|
|
// 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
|
|
Cleanup bool // Docker purge is enabled
|
|
CardPath string // Card path to write file to
|
|
}
|
|
|
|
Card []struct {
|
|
ID string `json:"Id"`
|
|
RepoTags []string `json:"RepoTags"`
|
|
ParsedRepoTags []TagStruct `json:"ParsedRepoTags"`
|
|
RepoDigests []interface{} `json:"RepoDigests"`
|
|
Parent string `json:"Parent"`
|
|
Comment string `json:"Comment"`
|
|
Created time.Time `json:"Created"`
|
|
Container string `json:"Container"`
|
|
DockerVersion string `json:"DockerVersion"`
|
|
Author string `json:"Author"`
|
|
Architecture string `json:"Architecture"`
|
|
Os string `json:"Os"`
|
|
Size int `json:"Size"`
|
|
VirtualSize int `json:"VirtualSize"`
|
|
Metadata struct {
|
|
LastTagTime time.Time `json:"LastTagTime"`
|
|
} `json:"Metadata"`
|
|
SizeString string
|
|
VirtualSizeString string
|
|
Time string
|
|
URL string `json:"URL"`
|
|
}
|
|
TagStruct struct {
|
|
Tag string `json:"Tag"`
|
|
}
|
|
)
|
|
|
|
// Exec executes the plugin step
|
|
func (p Plugin) Exec() error {
|
|
// start the Docker daemon server
|
|
if !p.Daemon.Disabled {
|
|
p.startDaemon()
|
|
}
|
|
|
|
// poll the docker daemon until it is started. This ensures the daemon is
|
|
// ready to accept connections before we proceed.
|
|
for i := 0; ; i++ {
|
|
cmd := commandInfo()
|
|
err := cmd.Run()
|
|
if err == nil {
|
|
break
|
|
}
|
|
if i == 15 {
|
|
fmt.Println("Unable to reach Docker Daemon after 15 attempts.")
|
|
break
|
|
}
|
|
time.Sleep(time.Second * 1)
|
|
}
|
|
|
|
// for debugging purposes, log the type of authentication
|
|
// credentials that have been provided.
|
|
switch {
|
|
case p.Login.Password != "" && p.Login.Config != "":
|
|
fmt.Println("Detected registry credentials and registry credentials file")
|
|
case p.Login.Password != "":
|
|
fmt.Println("Detected registry credentials")
|
|
case p.Login.Config != "":
|
|
fmt.Println("Detected registry credentials file")
|
|
default:
|
|
fmt.Println("Registry credentials or Docker config not provided. Guest mode enabled.")
|
|
}
|
|
|
|
// create Auth Config File
|
|
if p.Login.Config != "" {
|
|
os.MkdirAll(dockerHome, 0o600)
|
|
|
|
path := filepath.Join(dockerHome, "config.json")
|
|
err := ioutil.WriteFile(path, []byte(p.Login.Config), 0o600)
|
|
if err != nil {
|
|
return fmt.Errorf("Error writing config.json: %s", err)
|
|
}
|
|
}
|
|
|
|
// login to the Docker registry
|
|
if p.Login.Password != "" {
|
|
cmd := commandLogin(p.Login)
|
|
raw, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
out := string(raw)
|
|
out = strings.Replace(out, "WARNING! Using --password via the CLI is insecure. Use --password-stdin.", "", -1)
|
|
fmt.Println(out)
|
|
return fmt.Errorf("Error authenticating: exit status 1")
|
|
}
|
|
}
|
|
|
|
if p.Build.Squash && !p.Daemon.Experimental {
|
|
fmt.Println("Squash build flag is only available when Docker deamon is started with experimental flag. Ignoring...")
|
|
p.Build.Squash = false
|
|
}
|
|
|
|
// add proxy build args
|
|
addProxyBuildArgs(&p.Build)
|
|
|
|
var cmds []*exec.Cmd
|
|
cmds = append(cmds, commandVersion()) // docker version
|
|
cmds = append(cmds, commandInfo()) // docker info
|
|
|
|
// pre-pull cache images
|
|
for _, img := range p.Build.CacheFrom {
|
|
cmds = append(cmds, commandPull(img))
|
|
}
|
|
|
|
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 {
|
|
cmds = append(cmds, commandPush(p.Build, 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 && isCommandPull(cmd.Args) {
|
|
fmt.Printf("Could not pull cache-from image %s. Ignoring...\n", cmd.Args[2])
|
|
} else if err != nil && isCommandPrune(cmd.Args) {
|
|
fmt.Printf("Could not prune system containers. Ignoring...\n")
|
|
} else if err != nil && isCommandRmi(cmd.Args) {
|
|
fmt.Printf("Could not remove image %s. Ignoring...\n", cmd.Args[2])
|
|
} else if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// output the adaptive card
|
|
if err := p.writeCard(); err != nil {
|
|
fmt.Printf("Could not create adaptive card. %s\n", err)
|
|
}
|
|
|
|
// execute cleanup routines in batch mode
|
|
if p.Cleanup {
|
|
// clear the slice
|
|
cmds = nil
|
|
|
|
cmds = append(cmds, commandRmi(p.Build.Name)) // docker rmi
|
|
cmds = append(cmds, commandPrune()) // docker system prune -f
|
|
|
|
for _, cmd := range cmds {
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
trace(cmd)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// helper function to create the docker login command.
|
|
func commandLogin(login Login) *exec.Cmd {
|
|
if login.Email != "" {
|
|
return commandLoginEmail(login)
|
|
}
|
|
return exec.Command(
|
|
dockerExe, "login",
|
|
"-u", login.Username,
|
|
"-p", login.Password,
|
|
login.Registry,
|
|
)
|
|
}
|
|
|
|
// helper to check if args match "docker pull <image>"
|
|
func isCommandPull(args []string) bool {
|
|
return len(args) > 2 && args[1] == "pull"
|
|
}
|
|
|
|
func commandPull(repo string) *exec.Cmd {
|
|
return exec.Command(dockerExe, "pull", repo)
|
|
}
|
|
|
|
func commandLoginEmail(login Login) *exec.Cmd {
|
|
return exec.Command(
|
|
dockerExe, "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(dockerExe, "version")
|
|
}
|
|
|
|
// helper function to create the docker info command.
|
|
func commandInfo() *exec.Cmd {
|
|
return exec.Command(dockerExe, "info")
|
|
}
|
|
|
|
// helper function to create the docker build command.
|
|
func commandBuild(build Build) *exec.Cmd {
|
|
args := []string{
|
|
"build",
|
|
"--rm=true",
|
|
"-f", build.Dockerfile,
|
|
"-t", build.Name,
|
|
}
|
|
|
|
args = append(args, build.Context)
|
|
if build.Squash {
|
|
args = append(args, "--squash")
|
|
}
|
|
if build.Compress {
|
|
args = append(args, "--compress")
|
|
}
|
|
if build.Pull {
|
|
args = append(args, "--pull=true")
|
|
}
|
|
if build.NoCache {
|
|
args = append(args, "--no-cache")
|
|
}
|
|
for _, arg := range build.CacheFrom {
|
|
args = append(args, "--cache-from", arg)
|
|
}
|
|
for _, arg := range build.ArgsEnv {
|
|
addProxyValue(&build, arg)
|
|
}
|
|
for _, arg := range build.Args {
|
|
args = append(args, "--build-arg", arg)
|
|
}
|
|
for _, host := range build.AddHost {
|
|
args = append(args, "--add-host", host)
|
|
}
|
|
if build.Secret != "" {
|
|
args = append(args, "--secret", build.Secret)
|
|
}
|
|
if build.Target != "" {
|
|
args = append(args, "--target", build.Target)
|
|
}
|
|
if build.Quiet {
|
|
args = append(args, "--quiet")
|
|
}
|
|
|
|
if build.AutoLabel {
|
|
labelSchema := []string{
|
|
fmt.Sprintf("created=%s", time.Now().Format(time.RFC3339)),
|
|
fmt.Sprintf("revision=%s", build.Name),
|
|
fmt.Sprintf("source=%s", build.Remote),
|
|
fmt.Sprintf("url=%s", build.Link),
|
|
}
|
|
labelPrefix := "org.opencontainers.image"
|
|
|
|
if len(build.LabelSchema) > 0 {
|
|
labelSchema = append(labelSchema, build.LabelSchema...)
|
|
}
|
|
|
|
for _, label := range labelSchema {
|
|
args = append(args, "--label", fmt.Sprintf("%s.%s", labelPrefix, label))
|
|
}
|
|
}
|
|
|
|
if len(build.Labels) > 0 {
|
|
for _, label := range build.Labels {
|
|
args = append(args, "--label", label)
|
|
}
|
|
}
|
|
|
|
// we need to enable buildkit, for secret support
|
|
if build.Secret != "" {
|
|
os.Setenv("DOCKER_BUILDKIT", "1")
|
|
}
|
|
return exec.Command(dockerExe, args...)
|
|
}
|
|
|
|
// helper function to add proxy values from the environment
|
|
func addProxyBuildArgs(build *Build) {
|
|
addProxyValue(build, "http_proxy")
|
|
addProxyValue(build, "https_proxy")
|
|
addProxyValue(build, "no_proxy")
|
|
}
|
|
|
|
// helper function to add the upper and lower case version of a proxy value.
|
|
func addProxyValue(build *Build, key string) {
|
|
value := getProxyValue(key)
|
|
|
|
if len(value) > 0 && !hasProxyBuildArg(build, key) {
|
|
build.Args = append(build.Args, fmt.Sprintf("%s=%s", key, value))
|
|
build.Args = append(build.Args, fmt.Sprintf("%s=%s", strings.ToUpper(key), value))
|
|
}
|
|
}
|
|
|
|
// helper function to get a proxy value from the environment.
|
|
//
|
|
// assumes that the upper and lower case versions of are the same.
|
|
func getProxyValue(key string) string {
|
|
value := os.Getenv(key)
|
|
|
|
if len(value) > 0 {
|
|
return value
|
|
}
|
|
|
|
return os.Getenv(strings.ToUpper(key))
|
|
}
|
|
|
|
// helper function that looks to see if a proxy value was set in the build args.
|
|
func hasProxyBuildArg(build *Build, key string) bool {
|
|
keyUpper := strings.ToUpper(key)
|
|
|
|
for _, s := range build.Args {
|
|
if strings.HasPrefix(s, key) || strings.HasPrefix(s, keyUpper) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// helper function to create the docker tag command.
|
|
func commandTag(build Build, tag string) *exec.Cmd {
|
|
var (
|
|
source = build.Name
|
|
target = fmt.Sprintf("%s:%s", build.Repo, tag)
|
|
)
|
|
return exec.Command(
|
|
dockerExe, "tag", source, target,
|
|
)
|
|
}
|
|
|
|
// helper function to create the docker push command.
|
|
func commandPush(build Build, tag string) *exec.Cmd {
|
|
target := fmt.Sprintf("%s:%s", build.Repo, tag)
|
|
return exec.Command(dockerExe, "push", target)
|
|
}
|
|
|
|
// helper function to create the docker daemon command.
|
|
func commandDaemon(daemon Daemon) *exec.Cmd {
|
|
args := []string{
|
|
"--data-root", daemon.StoragePath,
|
|
"--host=unix:///var/run/docker.sock",
|
|
}
|
|
|
|
if _, err := os.Stat("/etc/docker/default.json"); err == nil {
|
|
args = append(args, "--seccomp-profile=/etc/docker/default.json")
|
|
}
|
|
|
|
if daemon.StorageDriver != "" {
|
|
args = append(args, "-s", daemon.StorageDriver)
|
|
}
|
|
if daemon.Insecure && daemon.Registry != "" {
|
|
args = append(args, "--insecure-registry", daemon.Registry)
|
|
}
|
|
if daemon.IPv6 {
|
|
args = append(args, "--ipv6")
|
|
}
|
|
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)
|
|
}
|
|
for _, dnsSearch := range daemon.DNSSearch {
|
|
args = append(args, "--dns-search", dnsSearch)
|
|
}
|
|
if len(daemon.MTU) != 0 {
|
|
args = append(args, "--mtu", daemon.MTU)
|
|
}
|
|
if daemon.Experimental {
|
|
args = append(args, "--experimental")
|
|
}
|
|
return exec.Command(dockerdExe, args...)
|
|
}
|
|
|
|
// helper to check if args match "docker prune"
|
|
func isCommandPrune(args []string) bool {
|
|
return len(args) > 3 && args[2] == "prune"
|
|
}
|
|
|
|
func commandPrune() *exec.Cmd {
|
|
return exec.Command(dockerExe, "system", "prune", "-f")
|
|
}
|
|
|
|
// helper to check if args match "docker rmi"
|
|
func isCommandRmi(args []string) bool {
|
|
return len(args) > 2 && args[1] == "rmi"
|
|
}
|
|
|
|
func commandRmi(tag string) *exec.Cmd {
|
|
return exec.Command(dockerExe, "rmi", tag)
|
|
}
|
|
|
|
// 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, "+ %s\n", strings.Join(cmd.Args, " "))
|
|
}
|
|
|
|
func GetDroneDockerExecCmd() string {
|
|
if runtime.GOOS == "windows" {
|
|
return "C:/bin/drone-docker.exe"
|
|
}
|
|
|
|
return "drone-docker"
|
|
}
|