diff --git a/cmd/drone-acr/main.go b/cmd/drone-acr/main.go index 6a7f097..68c553c 100644 --- a/cmd/drone-acr/main.go +++ b/cmd/drone-acr/main.go @@ -41,6 +41,7 @@ func main() { os.Setenv("PLUGIN_REGISTRY", registry) os.Setenv("DOCKER_USERNAME", username) os.Setenv("DOCKER_PASSWORD", password) + os.Setenv("PLUGIN_REGISTRY_TYPE", "ACR") // invoke the base docker plugin binary cmd := exec.Command(docker.GetDroneDockerExecCmd()) diff --git a/cmd/drone-docker/main.go b/cmd/drone-docker/main.go index 679b24d..bd1ace4 100644 --- a/cmd/drone-docker/main.go +++ b/cmd/drone-docker/main.go @@ -9,6 +9,7 @@ import ( "github.com/urfave/cli" docker "github.com/drone-plugins/drone-docker" + "github.com/drone-plugins/drone-plugin-lib/drone" ) var ( @@ -279,6 +280,16 @@ func main() { Usage: "ssh agent key to use", EnvVar: "PLUGIN_SSH_AGENT_KEY", }, + cli.StringFlag{ + Name: "artifact-file", + Usage: "Artifact file location that will be generated by the plugin. This file will include information of docker images that are uploaded by the plugin.", + EnvVar: "PLUGIN_ARTIFACT_FILE", + }, + cli.StringFlag{ + Name: "registry-type", + Usage: "registry type", + EnvVar: "PLUGIN_REGISTRY_TYPE", + }, } if err := app.Run(os.Args); err != nil { @@ -287,6 +298,11 @@ func main() { } func run(c *cli.Context) error { + registryType := drone.Docker + if c.String("registry-type") != "" { + registryType = drone.RegistryType(c.String("registry-type")) + } + plugin := docker.Plugin{ Dryrun: c.Bool("dry-run"), Cleanup: c.BoolT("docker.purge"), @@ -297,7 +313,8 @@ func run(c *cli.Context) error { Email: c.String("docker.email"), Config: c.String("docker.config"), }, - CardPath: c.String("drone-card-path"), + CardPath: c.String("drone-card-path"), + ArtifactFile: c.String("artifact-file"), Build: docker.Build{ Remote: c.String("remote.url"), Name: c.String("commit.sha"), @@ -339,6 +356,7 @@ func run(c *cli.Context) error { DNSSearch: c.StringSlice("daemon.dns-search"), MTU: c.String("daemon.mtu"), Experimental: c.Bool("daemon.experimental"), + RegistryType: registryType, }, } diff --git a/cmd/drone-ecr/main.go b/cmd/drone-ecr/main.go index f91e4b5..ca08cfd 100644 --- a/cmd/drone-ecr/main.go +++ b/cmd/drone-ecr/main.go @@ -111,6 +111,7 @@ func main() { os.Setenv("PLUGIN_REGISTRY", registry) os.Setenv("DOCKER_USERNAME", username) os.Setenv("DOCKER_PASSWORD", password) + os.Setenv("PLUGIN_REGISTRY_TYPE", "ECR") // invoke the base docker plugin binary cmd := exec.Command(docker.GetDroneDockerExecCmd()) diff --git a/cmd/drone-gcr/main.go b/cmd/drone-gcr/main.go index 92ecd9c..27e96c1 100644 --- a/cmd/drone-gcr/main.go +++ b/cmd/drone-gcr/main.go @@ -55,6 +55,7 @@ func main() { os.Setenv("PLUGIN_REGISTRY", registry) os.Setenv("DOCKER_USERNAME", username) os.Setenv("DOCKER_PASSWORD", password) + os.Setenv("PLUGIN_REGISTRY_TYPE", "GCR") // invoke the base docker plugin binary cmd := exec.Command(docker.GetDroneDockerExecCmd()) diff --git a/docker.go b/docker.go index 828b9dc..508545d 100644 --- a/docker.go +++ b/docker.go @@ -1,6 +1,7 @@ package docker import ( + "errors" "fmt" "os" "os/exec" @@ -8,24 +9,27 @@ import ( "runtime" "strings" "time" + + "github.com/drone-plugins/drone-plugin-lib/drone" ) 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 + 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 + RegistryType drone.RegistryType // Docker registry type } // Login defines Docker login parameters. @@ -69,12 +73,13 @@ type ( // 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 + 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 + ArtifactFile string // Artifact path to write file to } Card []struct { @@ -223,6 +228,16 @@ func (p Plugin) Exec() error { fmt.Printf("Could not create adaptive card. %s\n", err) } + if p.ArtifactFile != "" { + if digest, err := getDigest(p.Build.Name); err == nil { + if err = drone.WritePluginArtifactFile(p.Daemon.RegistryType, p.ArtifactFile, p.Daemon.Registry, p.Build.Repo, digest, p.Build.Tags); err != nil { + fmt.Printf("failed to write plugin artifact file at path: %s with error: %s\n", p.ArtifactFile, err) + } + } else { + fmt.Printf("Could not fetch the digest. %s\n", err) + } + } + // execute cleanup routines in batch mode if p.Cleanup { // clear the slice @@ -551,3 +566,19 @@ func GetDroneDockerExecCmd() string { return "drone-docker" } + +func getDigest(buildName string) (string, error) { + cmd := exec.Command("docker", "inspect", "--format='{{index .RepoDigests 0}}'", buildName) + output, err := cmd.Output() + if err != nil { + return "", err + } + + // Parse the output to extract the repo digest. + digest := strings.Trim(string(output), "'\n") + parts := strings.Split(digest, "@") + if len(parts) > 1 { + return parts[1], nil + } + return "", errors.New("unable to fetch digest") +} diff --git a/go.mod b/go.mod index 95a4720..0e09484 100644 --- a/go.mod +++ b/go.mod @@ -3,22 +3,21 @@ module github.com/drone-plugins/drone-docker require ( github.com/aws/aws-sdk-go v1.26.7 github.com/coreos/go-semver v0.3.0 + github.com/drone-plugins/drone-plugin-lib v0.4.1 github.com/drone/drone-go v1.7.1 github.com/inhies/go-bytesize v0.0.0-20210819104631-275770b98743 github.com/joho/godotenv v1.3.0 - github.com/sirupsen/logrus v1.3.0 + github.com/sirupsen/logrus v1.9.0 github.com/urfave/cli v1.22.2 ) require ( - github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect - github.com/konsorten/go-windows-terminal-sequences v1.0.1 // indirect - github.com/russross/blackfriday/v2 v2.0.1 // indirect - github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect - golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 // indirect - golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + golang.org/x/sys v0.0.0-20220731174439-a90be440212d // indirect gopkg.in/yaml.v2 v2.2.8 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) go 1.17 diff --git a/go.sum b/go.sum index 795ef38..bbbe072 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,18 @@ github.com/99designs/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e/go.mod h1:Xa6lInWHNQnuWoF0YPSsx+INFA9qk7/7pTjwb3PInkY= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/aws/aws-sdk-go v1.26.7 h1:ObjEnmzvSdYy8KVd3me7v/UMyCn81inLy2SyoIPoBkg= github.com/aws/aws-sdk-go v1.26.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/drone-plugins/drone-plugin-lib v0.4.1 h1:47rZlmcMpr1hSp+6Gl+1Z4t+efi/gMQU3lxukC1Yg64= +github.com/drone-plugins/drone-plugin-lib v0.4.1/go.mod h1:KwCu92jFjHV3xv2hu5Qg/8zBNvGwbhoJDQw/EwnTvoM= github.com/drone/drone-go v1.7.1 h1:ZX+3Rs8YHUSUQ5mkuMLmm1zr1ttiiE2YGNxF3AnyDKw= github.com/drone/drone-go v1.7.1/go.mod h1:fxCf9jAnXDZV1yDr0ckTuWd1intvcQwfJmTRpTZ1mXg= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= @@ -18,26 +23,28 @@ github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5i github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.3.0 h1:hI/7Q+DtNZ2kINb6qt/lS+IyXnHQe9e90POfeewL/ME= -github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +github.com/urfave/cli/v2 v2.23.6/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220731174439-a90be440212d h1:Sv5ogFZatcgIMMtBSTTAgMYsicp25MXBubjXNDKwm80= +golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=