11package docker
22
33import (
4+ "encoding/json"
45 "fmt"
56 "os"
67 "os/exec"
78 "path/filepath"
89 "strings"
910 "time"
11+
12+ "github.com/drone-plugins/drone-plugin-lib/drone"
1013)
1114
1215type (
1316 // Daemon defines Docker daemon parameters.
1417 Daemon struct {
15- Registry string // Docker registry
16- Mirror string // Docker registry mirror
17- Insecure bool // Docker daemon enable insecure registries
18- StorageDriver string // Docker daemon storage driver
19- StoragePath string // Docker daemon storage path
20- Disabled bool // DOcker daemon is disabled (already running)
21- Debug bool // Docker daemon started in debug mode
22- Bip string // Docker daemon network bridge IP address
23- DNS []string // Docker daemon dns server
24- DNSSearch []string // Docker daemon dns search domain
25- MTU string // Docker daemon mtu setting
26- IPv6 bool // Docker daemon IPv6 networking
18+ Registry string // Docker registry
19+ Mirror string // Docker registry mirror
20+ Insecure bool // Docker daemon enable insecure registries
21+ StorageDriver string // Docker daemon storage driver
22+ StoragePath string // Docker daemon storage path
23+ Disabled bool // DOcker daemon is disabled (already running)
24+ Debug bool // Docker daemon started in debug mode
25+ Bip string // Docker daemon network bridge IP address
26+ DNS []string // Docker daemon dns server
27+ DNSSearch []string // Docker daemon dns search domain
28+ MTU string // Docker daemon mtu setting
29+ IPv6 bool // Docker daemon IPv6 networking
30+ RegistryType drone.RegistryType // Docker registry type
2731 }
2832
2933 Builder struct {
@@ -76,13 +80,15 @@ type (
7680
7781 // Plugin defines the Docker plugin parameters.
7882 Plugin struct {
79- Login Login // Docker login configuration
80- Build Build // Docker build configuration
81- Builder Builder // Docker Buildx builder configuration
82- Daemon Daemon // Docker daemon configuration
83- Dryrun bool // Docker push is skipped
84- Cleanup bool // Docker purge is enabled
85- CardPath string // Card path to write file to
83+ Login Login // Docker login configuration
84+ Build Build // Docker build configuration
85+ Builder Builder // Docker Buildx builder configuration
86+ Daemon Daemon // Docker daemon configuration
87+ Dryrun bool // Docker push is skipped
88+ Cleanup bool // Docker purge is enabled
89+ CardPath string // Card path to write file to
90+ MetadataFile string // Location to write the metadata file
91+ ArtifactFile string // Artifact path to write file to
8692 }
8793
8894 Card []struct {
@@ -204,7 +210,7 @@ func (p Plugin) Exec() error {
204210 cmds = append (cmds , commandInfo ()) // docker info
205211
206212 // Command to build, tag and push
207- cmds = append (cmds , commandBuildx (p .Build , p .Builder , p .Dryrun )) // docker build
213+ cmds = append (cmds , commandBuildx (p .Build , p .Builder , p .Dryrun , p . MetadataFile )) // docker build
208214
209215 // execute all commands in batch mode.
210216 for _ , cmd := range cmds {
@@ -223,8 +229,21 @@ func (p Plugin) Exec() error {
223229 }
224230
225231 // output the adaptive card
226- if err := p .writeCard (); err != nil {
227- fmt .Printf ("Could not create adaptive card. %s\n " , err )
232+ if p .Builder .Driver == defaultDriver {
233+ if err := p .writeCard (); err != nil {
234+ fmt .Printf ("Could not create adaptive card. %s\n " , err )
235+ }
236+ }
237+
238+ // write to artifact file
239+ if p .ArtifactFile != "" {
240+ if digest , err := getDigest (p .MetadataFile ); err == nil {
241+ if err = drone .WritePluginArtifactFile (p .Daemon .RegistryType , p .ArtifactFile , p .Daemon .Registry , p .Build .Repo , digest , p .Build .Tags ); err != nil {
242+ fmt .Printf ("Failed to write plugin artifact file at path: %s with error: %s\n " , p .ArtifactFile , err )
243+ }
244+ } else {
245+ fmt .Printf ("Could not fetch the digest. %s\n " , err )
246+ }
228247 }
229248
230249 // execute cleanup routines in batch mode
@@ -245,6 +264,27 @@ func (p Plugin) Exec() error {
245264 return nil
246265}
247266
267+ func getDigest (metadataFile string ) (string , error ) {
268+ file , err := os .Open (metadataFile )
269+ if err != nil {
270+ return "" , fmt .Errorf ("unable to open the metadata file %s with error: %s" , metadataFile , err )
271+ }
272+ defer file .Close ()
273+
274+ var metadata map [string ]interface {}
275+ if err = json .NewDecoder (file ).Decode (& metadata ); err != nil {
276+ return "" , fmt .Errorf ("unable to decode the metadata with error: %s" , err )
277+ }
278+
279+ if d , found := metadata ["containerimage.digest" ]; found {
280+ if digest , ok := d .(string ); ok {
281+ return digest , nil
282+ }
283+ return "" , fmt .Errorf ("unable to parse containerimage.digest from metadata json" )
284+ }
285+ return "" , fmt .Errorf ("containerimage.digest not found in metadata json" )
286+ }
287+
248288// helper function to create the docker login command.
249289func commandLogin (login Login ) * exec.Cmd {
250290 if login .Email != "" {
@@ -288,7 +328,7 @@ func commandInfo() *exec.Cmd {
288328}
289329
290330// helper function to create the docker buildx command.
291- func commandBuildx (build Build , builder Builder , dryrun bool ) * exec.Cmd {
331+ func commandBuildx (build Build , builder Builder , dryrun bool , metadataFile string ) * exec.Cmd {
292332 args := []string {
293333 "buildx" ,
294334 "build" ,
@@ -310,6 +350,9 @@ func commandBuildx(build Build, builder Builder, dryrun bool) *exec.Cmd {
310350 args = append (args , "--push" )
311351 }
312352 args = append (args , build .Context )
353+ if metadataFile != "" {
354+ args = append (args , "--metadata-file" , metadataFile )
355+ }
313356 if build .Squash {
314357 args = append (args , "--squash" )
315358 }
0 commit comments