From ccd6858c1225e39b66d1872641e07f1ef8a1d4e2 Mon Sep 17 00:00:00 2001 From: Julien Vey Date: Wed, 22 Dec 2021 00:34:39 +0100 Subject: [PATCH] feat: Add labels on image build --- builder/docker/builder.go | 29 ++++++++++++++++++++++- dag/image.go | 50 +++++++++++++++++++++++++++++++++++---- types/types.go | 10 ++++++++ 3 files changed, 84 insertions(+), 5 deletions(-) diff --git a/builder/docker/builder.go b/builder/docker/builder.go index 828fc810..8bafe8c0 100644 --- a/builder/docker/builder.go +++ b/builder/docker/builder.go @@ -1,6 +1,9 @@ package docker import ( + "fmt" + "time" + "github.com/radiofrance/dib/exec" "github.com/radiofrance/dib/types" "github.com/sirupsen/logrus" @@ -25,8 +28,32 @@ func (b ImageBuilder) Build(opts types.ImageBuilderOpts) error { logrus.Infof("[DRY-RUN] docker push %s", opts.Tag) return nil } + dockerArgs := []string{ + "build", + "--no-cache", + "--pull", + } + + if opts.CreationTime != nil { + dockerArgs = append(dockerArgs, "--label", fmt.Sprintf("org.opencontainers.image.created=%s", + opts.CreationTime.Format(time.RFC3339))) + } + if opts.Authors != nil { + dockerArgs = append(dockerArgs, "--label", fmt.Sprintf("org.opencontainers.image.authors=%s", + *opts.Authors)) + } + if opts.Source != nil { + dockerArgs = append(dockerArgs, "--label", fmt.Sprintf("org.opencontainers.image.source=%s", + *opts.Source)) + } + if opts.Revision != nil { + dockerArgs = append(dockerArgs, "--label", fmt.Sprintf("org.opencontainers.image.revision=%s", + *opts.Revision)) + } + + dockerArgs = append(dockerArgs, "-t", opts.Tag, opts.Context) - err := b.exec.ExecuteStdout("docker", "build", "--no-cache", "--pull", "-t", opts.Tag, opts.Context) + err := b.exec.ExecuteStdout("docker", dockerArgs...) if err != nil { return err } diff --git a/dag/image.go b/dag/image.go index 5cfb9105..749f4acd 100644 --- a/dag/image.go +++ b/dag/image.go @@ -2,8 +2,10 @@ package dag import ( "fmt" + "os" "strings" "sync" + "time" "github.com/radiofrance/dib/types" @@ -100,10 +102,23 @@ func (img *Image) doRebuild(newTag string) error { return err } - err := img.Builder.Build(types.ImageBuilderOpts{ - Context: img.Dockerfile.ContextPath, - Tag: fmt.Sprintf("%s:%s", img.Name, newTag), - }) + now := time.Now() + opts := types.ImageBuilderOpts{ + Context: img.Dockerfile.ContextPath, + Tag: fmt.Sprintf("%s:%s", img.Name, newTag), + CreationTime: &now, + } + if rev := findRevision(); rev != "" { + opts.Revision = &rev + } + if authors := findAuthors(); authors != "" { + opts.Authors = &authors + } + if source := findSource(); source != "" { + opts.Authors = &source + } + + err := img.Builder.Build(opts) if err != nil { return err } @@ -115,6 +130,33 @@ func (img *Image) doRebuild(newTag string) error { return nil } +func findSource() string { + if url := os.Getenv("CI_PROJECT_URL"); url != "" { // gitlab predefined variable + return url + } else if url := os.Getenv("GITHUB_REPOSITORY"); url != "" { // github predefined variable + return fmt.Sprintf("https://github.com/%s", url) + } + return "" +} + +func findAuthors() string { + if authors := os.Getenv("GITLAB_USER_NAME"); authors != "" { // gitlab predefined variable + return authors + } else if authors := os.Getenv("GITHUB_ACTOR"); authors != "" { // github predefined variable + return authors + } + return "" +} + +func findRevision() string { + if rev := os.Getenv("CI_COMMIT_SHA"); rev != "" { // gitlab predefined variable + return rev + } else if rev := os.Getenv("GITHUB_SHA"); rev != "" { // github predefined variable + return rev + } + return "" +} + // runTests run docker tests for each TestRunner. func (img *Image) runTests(ref, path string) error { rateLimit <- struct{}{} diff --git a/types/types.go b/types/types.go index d6c51ddd..4fc00a57 100644 --- a/types/types.go +++ b/types/types.go @@ -1,5 +1,7 @@ package types +import "time" + // ImageBuilder is the interface for building Docker images. type ImageBuilder interface { Build(opts ImageBuilderOpts) error @@ -11,6 +13,14 @@ type ImageBuilderOpts struct { Context string // Name of the tag to build, same as passed to the '-t' flag of the docker build command. Tag string + // Date and time on which the image was built (string, date-time as defined by RFC 3339). + CreationTime *time.Time + // Contact details of the people or organization responsible for the image (freeform string) + Authors *string + // URL to get source code for building the image (string) + Source *string + // Source control revision identifier for the packaged software. + Revision *string } // TestRunner is an interface for dealing with docker tests, such as dgoss, trivy.