diff --git a/cmd/vela-kaniko/main.go b/cmd/vela-kaniko/main.go index 033f6d7..85da1b3 100644 --- a/cmd/vela-kaniko/main.go +++ b/cmd/vela-kaniko/main.go @@ -319,6 +319,21 @@ func main() { Name: "label.url", Usage: "direct url of the repository", }, + &cli.StringFlag{ + EnvVars: []string{"VELA_BUILD_LINK"}, + Name: "label.build_link", + Usage: "direct Vela link to the build", + }, + &cli.StringFlag{ + EnvVars: []string{"VELA_BUILD_HOST"}, + Name: "label.host", + Usage: "host that the image is built on", + }, + &cli.StringFlag{ + EnvVars: []string{"VELA_BUILD_CUSTOM_LABELS", "PARAMETER_CUSTOM_LABELS"}, + Name: "label.custom", + Usage: "custom labels to add to the image in the form LABEL_NAME=ENV_KEY", + }, &cli.StringSliceFlag{ EnvVars: []string{"VELA_REPO_TOPICS"}, Name: "label.topics", @@ -381,6 +396,27 @@ func run(c *cli.Context) error { } } + // target type for custom labels + var customLabels []string + + labelsStr := c.String("label.custom") + if len(labelsStr) > 0 { + customLabelsMap := make(map[string]string) + + // attempt to unmarshal to map + err := json.Unmarshal([]byte(labelsStr), &customLabelsMap) + if err != nil { + // fall back on splitting the string + customLabels = strings.Split(labelsStr, ",") + } else { + // iterate through the custom labels map + for key, value := range customLabelsMap { + // add the custom label to the custom labels + customLabels = append(customLabels, fmt.Sprintf("%s=%s", key, value)) + } + } + } + // create the plugin p := &Plugin{ // build configuration @@ -436,6 +472,9 @@ func run(c *cli.Context) error { Number: c.Int("label.number"), Topics: c.StringSlice("label.topics"), URL: c.String("label.url"), + BuildURL: c.String("label.build_link"), + Host: c.String("label.host"), + CustomSet: customLabels, }, Labels: c.StringSlice("repo.labels"), }, diff --git a/cmd/vela-kaniko/plugin.go b/cmd/vela-kaniko/plugin.go index b9200ab..889e813 100644 --- a/cmd/vela-kaniko/plugin.go +++ b/cmd/vela-kaniko/plugin.go @@ -122,15 +122,6 @@ func (p *Plugin) Command() *exec.Cmd { flags = append(flags, fmt.Sprintf("--destination=%s:%s", p.Repo.Name, tag)) } - // add predefined labels to user provided labels - p.Repo.Labels = append(p.Repo.Labels, p.Repo.AddLabels()...) - - // iterate through all repo labels - for _, label := range p.Repo.Labels { - // add flag for tag from provided repo tag - flags = append(flags, "--label", label) - } - // add flag for dockerfile from provided image dockerfile flags = append(flags, fmt.Sprintf("--dockerfile=%s", p.Image.Dockerfile)) @@ -188,6 +179,15 @@ func (p *Plugin) Command() *exec.Cmd { // add flag for logging verbosity flags = append(flags, fmt.Sprintf("--verbosity=%s", logrus.GetLevel())) + // add predefined labels to user provided labels + p.Repo.Labels = append(p.Repo.Labels, p.Repo.AddLabels()...) + + // iterate through all repo labels + for _, label := range p.Repo.Labels { + // add flag for tag from provided repo tag + flags = append(flags, fmt.Sprintf("--label=%s", label)) + } + return exec.Command(kanikoBin, flags...) } diff --git a/cmd/vela-kaniko/plugin_test.go b/cmd/vela-kaniko/plugin_test.go index 42914a5..0ebc654 100644 --- a/cmd/vela-kaniko/plugin_test.go +++ b/cmd/vela-kaniko/plugin_test.go @@ -4,6 +4,7 @@ package main import ( "os/exec" + "sort" "strings" "testing" @@ -136,15 +137,17 @@ func TestDocker_Plugin_Command(t *testing.T) { "--cache-repo=index.docker.io/target/vela-kaniko", "--context=.", "--destination=index.docker.io/target/vela-kaniko:latest", - "--label org.opencontainers.image.created=now", - "--label org.opencontainers.image.url=git.example.com", - "--label org.opencontainers.image.revision=deadbeef", - "--label io.vela.build.author=octocat@example.com", - "--label io.vela.build.number=1", - "--label io.vela.build.repo=octocat/scripts", - "--label io.vela.build.commit=deadbeef", - "--label io.vela.build.url=git.example.com", - "--label io.vela.build.topics=id123", + "--label=org.opencontainers.image.created=now", + "--label=org.opencontainers.image.url=git.example.com", + "--label=org.opencontainers.image.revision=deadbeef", + "--label=io.vela.build.author=octocat@example.com", + "--label=io.vela.build.number=1", + "--label=io.vela.build.repo=octocat/scripts", + "--label=io.vela.build.commit=deadbeef", + "--label=io.vela.build.url=git.example.com", + "--label=io.vela.build.link=https://vela.example.com/velaOrg/velaRepo/1", + "--label=io.vela.build.host=vela-worker", + "--label=io.vela.build.topics=id123", "--dockerfile=Dockerfile", "--no-push", "--push-retry=1", @@ -159,7 +162,7 @@ func TestDocker_Plugin_Command(t *testing.T) { // run test got := p.Command() - if !strings.EqualFold(got.String(), want.String()) { + if !strings.EqualFold(sortCmdArgs(got).String(), sortCmdArgs(want).String()) { t.Errorf("Command is %v, want %v", got, want) } } @@ -212,15 +215,6 @@ func TestDocker_Plugin_Command_AutoTag_TagBuild(t *testing.T) { "--context=.", "--destination=index.docker.io/target/vela-kaniko:latest", "--destination=index.docker.io/target/vela-kaniko:v0.0.0", - "--label org.opencontainers.image.created=now", - "--label org.opencontainers.image.url=git.example.com", - "--label org.opencontainers.image.revision=deadbeef", - "--label io.vela.build.author=octocat@example.com", - "--label io.vela.build.number=1", - "--label io.vela.build.repo=octocat/scripts", - "--label io.vela.build.commit=deadbeef", - "--label io.vela.build.url=git.example.com", - "--label io.vela.build.topics=id123", "--dockerfile=Dockerfile", "--no-push", "--push-retry=1", @@ -230,12 +224,23 @@ func TestDocker_Plugin_Command_AutoTag_TagBuild(t *testing.T) { "--insecure-pull", "--insecure", "--verbosity=info", + "--label=org.opencontainers.image.created=now", + "--label=org.opencontainers.image.url=git.example.com", + "--label=org.opencontainers.image.revision=deadbeef", + "--label=io.vela.build.author=octocat@example.com", + "--label=io.vela.build.number=1", + "--label=io.vela.build.repo=octocat/scripts", + "--label=io.vela.build.commit=deadbeef", + "--label=io.vela.build.url=git.example.com", + "--label=io.vela.build.link=https://vela.example.com/velaOrg/velaRepo/1", + "--label=io.vela.build.host=vela-worker", + "--label=io.vela.build.topics=id123", ) // run test got := p.Command() - if !strings.EqualFold(got.String(), want.String()) { + if !strings.EqualFold(sortCmdArgs(got).String(), sortCmdArgs(want).String()) { t.Errorf("Command is %v, want %v", got, want) } } @@ -288,15 +293,17 @@ func TestDocker_Plugin_Command_AutoTag_PushBuild(t *testing.T) { "--context=.", "--destination=index.docker.io/target/vela-kaniko:latest", "--destination=index.docker.io/target/vela-kaniko:7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", - "--label org.opencontainers.image.created=now", - "--label org.opencontainers.image.url=git.example.com", - "--label org.opencontainers.image.revision=deadbeef", - "--label io.vela.build.author=octocat@example.com", - "--label io.vela.build.number=1", - "--label io.vela.build.repo=octocat/scripts", - "--label io.vela.build.commit=deadbeef", - "--label io.vela.build.url=git.example.com", - "--label io.vela.build.topics=id123", + "--label=org.opencontainers.image.created=now", + "--label=org.opencontainers.image.url=git.example.com", + "--label=org.opencontainers.image.revision=deadbeef", + "--label=io.vela.build.author=octocat@example.com", + "--label=io.vela.build.number=1", + "--label=io.vela.build.repo=octocat/scripts", + "--label=io.vela.build.commit=deadbeef", + "--label=io.vela.build.url=git.example.com", + "--label=io.vela.build.link=https://vela.example.com/velaOrg/velaRepo/1", + "--label=io.vela.build.host=vela-worker", + "--label=io.vela.build.topics=id123", "--dockerfile=Dockerfile", "--no-push", "--push-retry=1", @@ -311,7 +318,7 @@ func TestDocker_Plugin_Command_AutoTag_PushBuild(t *testing.T) { // run test got := p.Command() - if !strings.EqualFold(got.String(), want.String()) { + if !strings.EqualFold(sortCmdArgs(got).String(), sortCmdArgs(want).String()) { t.Errorf("Command is %v, want %v", got, want) } } @@ -357,16 +364,18 @@ func TestDocker_Plugin_Command_With_Labels(t *testing.T) { "--cache-repo=index.docker.io/target/vela-kaniko", "--context=.", "--destination=index.docker.io/target/vela-kaniko:latest", - "--label key1=tag1", - "--label org.opencontainers.image.created=now", - "--label org.opencontainers.image.url=git.example.com", - "--label org.opencontainers.image.revision=deadbeef", - "--label io.vela.build.author=octocat@example.com", - "--label io.vela.build.number=1", - "--label io.vela.build.repo=octocat/scripts", - "--label io.vela.build.commit=deadbeef", - "--label io.vela.build.url=git.example.com", - "--label io.vela.build.topics=id123", + "--label=key1=tag1", + "--label=org.opencontainers.image.created=now", + "--label=org.opencontainers.image.url=git.example.com", + "--label=org.opencontainers.image.revision=deadbeef", + "--label=io.vela.build.author=octocat@example.com", + "--label=io.vela.build.number=1", + "--label=io.vela.build.repo=octocat/scripts", + "--label=io.vela.build.commit=deadbeef", + "--label=io.vela.build.url=git.example.com", + "--label=io.vela.build.link=https://vela.example.com/velaOrg/velaRepo/1", + "--label=io.vela.build.host=vela-worker", + "--label=io.vela.build.topics=id123", "--dockerfile=Dockerfile", "--no-push", "--push-retry=1", @@ -376,7 +385,7 @@ func TestDocker_Plugin_Command_With_Labels(t *testing.T) { // run test got := p.Command() - if !strings.EqualFold(got.String(), want.String()) { + if !strings.EqualFold(sortCmdArgs(got).String(), sortCmdArgs(want).String()) { t.Errorf("Command is %v, want %v", got, want) } } @@ -424,15 +433,17 @@ func TestDocker_Plugin_Command_With_MultipleTopics(t *testing.T) { "--cache-repo=index.docker.io/target/vela-kaniko", "--context=.", "--destination=index.docker.io/target/vela-kaniko:latest", - "--label org.opencontainers.image.created=now", - "--label org.opencontainers.image.url=git.example.com", - "--label org.opencontainers.image.revision=deadbeef", - "--label io.vela.build.author=octocat@example.com", - "--label io.vela.build.number=1", - "--label io.vela.build.repo=octocat/scripts", - "--label io.vela.build.commit=deadbeef", - "--label io.vela.build.url=git.example.com", - "--label io.vela.build.topics=foo,bar", + "--label=org.opencontainers.image.created=now", + "--label=org.opencontainers.image.url=git.example.com", + "--label=org.opencontainers.image.revision=deadbeef", + "--label=io.vela.build.author=octocat@example.com", + "--label=io.vela.build.number=1", + "--label=io.vela.build.repo=octocat/scripts", + "--label=io.vela.build.commit=deadbeef", + "--label=io.vela.build.url=git.example.com", + "--label=io.vela.build.link=https://vela.example.com/velaOrg/velaRepo/1", + "--label=io.vela.build.host=vela-worker", + "--label=io.vela.build.topics=foo,bar", "--dockerfile=Dockerfile", "--no-push", "--push-retry=1", @@ -442,7 +453,7 @@ func TestDocker_Plugin_Command_With_MultipleTopics(t *testing.T) { // run test got := p.Command() - if !strings.EqualFold(got.String(), want.String()) { + if !strings.EqualFold(sortCmdArgs(got).String(), sortCmdArgs(want).String()) { t.Errorf("Command is %v, want %v", got, want) } } @@ -491,15 +502,17 @@ func TestDocker_Plugin_Command_With_MultipleTopicsWithFilter(t *testing.T) { "--cache-repo=index.docker.io/target/vela-kaniko", "--context=.", "--destination=index.docker.io/target/vela-kaniko:latest", - "--label org.opencontainers.image.created=now", - "--label org.opencontainers.image.url=git.example.com", - "--label org.opencontainers.image.revision=deadbeef", - "--label io.vela.build.author=octocat@example.com", - "--label io.vela.build.number=1", - "--label io.vela.build.repo=octocat/scripts", - "--label io.vela.build.commit=deadbeef", - "--label io.vela.build.url=git.example.com", - "--label io.vela.build.topics=id123", + "--label=org.opencontainers.image.created=now", + "--label=org.opencontainers.image.url=git.example.com", + "--label=org.opencontainers.image.revision=deadbeef", + "--label=io.vela.build.author=octocat@example.com", + "--label=io.vela.build.number=1", + "--label=io.vela.build.repo=octocat/scripts", + "--label=io.vela.build.commit=deadbeef", + "--label=io.vela.build.url=git.example.com", + "--label=io.vela.build.link=https://vela.example.com/velaOrg/velaRepo/1", + "--label=io.vela.build.host=vela-worker", + "--label=io.vela.build.topics=id123", "--dockerfile=Dockerfile", "--no-push", "--push-retry=1", @@ -509,7 +522,7 @@ func TestDocker_Plugin_Command_With_MultipleTopicsWithFilter(t *testing.T) { // run test got := p.Command() - if !strings.EqualFold(got.String(), want.String()) { + if !strings.EqualFold(sortCmdArgs(got).String(), sortCmdArgs(want).String()) { t.Errorf("Command is %v, want %v", got, want) } } @@ -557,14 +570,16 @@ func TestDocker_Plugin_Command_With_MultipleTopicsNoTopics(t *testing.T) { "--cache-repo=index.docker.io/target/vela-kaniko", "--context=.", "--destination=index.docker.io/target/vela-kaniko:latest", - "--label org.opencontainers.image.created=now", - "--label org.opencontainers.image.url=git.example.com", - "--label org.opencontainers.image.revision=deadbeef", - "--label io.vela.build.author=octocat@example.com", - "--label io.vela.build.number=1", - "--label io.vela.build.repo=octocat/scripts", - "--label io.vela.build.commit=deadbeef", - "--label io.vela.build.url=git.example.com", + "--label=org.opencontainers.image.created=now", + "--label=org.opencontainers.image.url=git.example.com", + "--label=org.opencontainers.image.revision=deadbeef", + "--label=io.vela.build.author=octocat@example.com", + "--label=io.vela.build.number=1", + "--label=io.vela.build.repo=octocat/scripts", + "--label=io.vela.build.commit=deadbeef", + "--label=io.vela.build.url=git.example.com", + "--label=io.vela.build.link=https://vela.example.com/velaOrg/velaRepo/1", + "--label=io.vela.build.host=vela-worker", "--dockerfile=Dockerfile", "--no-push", "--push-retry=1", @@ -574,7 +589,90 @@ func TestDocker_Plugin_Command_With_MultipleTopicsNoTopics(t *testing.T) { // run test got := p.Command() - if !strings.EqualFold(got.String(), want.String()) { + if !strings.EqualFold(sortCmdArgs(got).String(), sortCmdArgs(want).String()) { + t.Errorf("Command is %v, want %v", got, want) + } +} + +func TestDocker_Plugin_Command_With_CustomLabels(t *testing.T) { + // setup types + p := &Plugin{ + Build: &Build{ + Event: "tag", + Sha: "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", + Tag: "v0.0.0", + IgnoreVarRun: true, + IgnorePath: []string{"/tmp", ".git"}, + LogTimestamp: true, + }, + Image: &Image{ + Args: []string{"foo=bar"}, + Context: ".", + Dockerfile: "Dockerfile", + Target: "foo", + }, + Registry: &Registry{ + Name: "index.docker.io", + Username: "octocat", + Password: "superSecretPassword", + DryRun: true, + PushRetry: 1, + InsecureRegistries: []string{"insecure.docker.local", "docker.local"}, + InsecurePull: true, + InsecurePush: true, + }, + Repo: &Repo{ + Cache: true, + CacheName: "index.docker.io/target/vela-kaniko", + Name: "index.docker.io/target/vela-kaniko", + Tags: []string{"latest"}, + AutoTag: true, + Label: testLabel(), + CompressedCaching: true, + }, + } + + p.Repo.Label.CustomSet = []string{"label1=foo", "label2=bar"} + + want := exec.Command( + kanikoBin, + "--ignore-var-run=true", + "--ignore-path=/tmp", + "--ignore-path=.git", + "--log-timestamp", + "--build-arg=foo=bar", + "--cache", + "--cache-repo=index.docker.io/target/vela-kaniko", + "--context=.", + "--destination=index.docker.io/target/vela-kaniko:latest", + "--label=org.opencontainers.image.created=now", + "--label=org.opencontainers.image.url=git.example.com", + "--label=org.opencontainers.image.revision=deadbeef", + "--label=io.vela.build.author=octocat@example.com", + "--label=io.vela.build.number=1", + "--label=io.vela.build.repo=octocat/scripts", + "--label=io.vela.build.commit=deadbeef", + "--label=io.vela.build.url=git.example.com", + "--label=io.vela.build.link=https://vela.example.com/velaOrg/velaRepo/1", + "--label=io.vela.build.host=vela-worker", + "--label=io.vela.build.topics=id123", + "--label=label1=foo", + "--label=label2=bar", + "--dockerfile=Dockerfile", + "--no-push", + "--push-retry=1", + "--target=foo", + "--insecure-registry=insecure.docker.local", + "--insecure-registry=docker.local", + "--insecure-pull", + "--insecure", + "--verbosity=info", + ) + + // run test + got := p.Command() + + if !strings.EqualFold(sortCmdArgs(got).String(), sortCmdArgs(want).String()) { t.Errorf("Command is %v, want %v", got, want) } } @@ -622,15 +720,17 @@ func TestDocker_Plugin_Command_With_SnapshotMode(t *testing.T) { "--cache-repo=index.docker.io/target/vela-kaniko", "--context=.", "--destination=index.docker.io/target/vela-kaniko:latest", - "--label org.opencontainers.image.created=now", - "--label org.opencontainers.image.url=git.example.com", - "--label org.opencontainers.image.revision=deadbeef", - "--label io.vela.build.author=octocat@example.com", - "--label io.vela.build.number=1", - "--label io.vela.build.repo=octocat/scripts", - "--label io.vela.build.commit=deadbeef", - "--label io.vela.build.url=git.example.com", - "--label io.vela.build.topics=id123", + "--label=org.opencontainers.image.created=now", + "--label=org.opencontainers.image.url=git.example.com", + "--label=org.opencontainers.image.revision=deadbeef", + "--label=io.vela.build.author=octocat@example.com", + "--label=io.vela.build.number=1", + "--label=io.vela.build.repo=octocat/scripts", + "--label=io.vela.build.commit=deadbeef", + "--label=io.vela.build.url=git.example.com", + "--label=io.vela.build.link=https://vela.example.com/velaOrg/velaRepo/1", + "--label=io.vela.build.host=vela-worker", + "--label=io.vela.build.topics=id123", "--dockerfile=Dockerfile", "--no-push", "--push-retry=1", @@ -641,7 +741,7 @@ func TestDocker_Plugin_Command_With_SnapshotMode(t *testing.T) { // run test got := p.Command() - if !strings.EqualFold(got.String(), want.String()) { + if !strings.EqualFold(sortCmdArgs(got).String(), sortCmdArgs(want).String()) { t.Errorf("Command is %v, want %v", got, want) } } @@ -689,15 +789,17 @@ func TestDocker_Plugin_Command_With_UseNewRun(t *testing.T) { "--cache-repo=index.docker.io/target/vela-kaniko", "--context=.", "--destination=index.docker.io/target/vela-kaniko:latest", - "--label org.opencontainers.image.created=now", - "--label org.opencontainers.image.url=git.example.com", - "--label org.opencontainers.image.revision=deadbeef", - "--label io.vela.build.author=octocat@example.com", - "--label io.vela.build.number=1", - "--label io.vela.build.repo=octocat/scripts", - "--label io.vela.build.commit=deadbeef", - "--label io.vela.build.url=git.example.com", - "--label io.vela.build.topics=id123", + "--label=org.opencontainers.image.created=now", + "--label=org.opencontainers.image.url=git.example.com", + "--label=org.opencontainers.image.revision=deadbeef", + "--label=io.vela.build.author=octocat@example.com", + "--label=io.vela.build.number=1", + "--label=io.vela.build.repo=octocat/scripts", + "--label=io.vela.build.commit=deadbeef", + "--label=io.vela.build.url=git.example.com", + "--label=io.vela.build.link=https://vela.example.com/velaOrg/velaRepo/1", + "--label=io.vela.build.host=vela-worker", + "--label=io.vela.build.topics=id123", "--dockerfile=Dockerfile", "--no-push", "--push-retry=1", @@ -708,7 +810,7 @@ func TestDocker_Plugin_Command_With_UseNewRun(t *testing.T) { // run test got := p.Command() - if !strings.EqualFold(got.String(), want.String()) { + if !strings.EqualFold(sortCmdArgs(got).String(), sortCmdArgs(want).String()) { t.Errorf("Command is %v, want %v", got, want) } } @@ -756,15 +858,17 @@ func TestDocker_Plugin_Command_With_TarPath(t *testing.T) { "--cache-repo=index.docker.io/target/vela-kaniko", "--context=.", "--destination=index.docker.io/target/vela-kaniko:latest", - "--label org.opencontainers.image.created=now", - "--label org.opencontainers.image.url=git.example.com", - "--label org.opencontainers.image.revision=deadbeef", - "--label io.vela.build.author=octocat@example.com", - "--label io.vela.build.number=1", - "--label io.vela.build.repo=octocat/scripts", - "--label io.vela.build.commit=deadbeef", - "--label io.vela.build.url=git.example.com", - "--label io.vela.build.topics=id123", + "--label=org.opencontainers.image.created=now", + "--label=org.opencontainers.image.url=git.example.com", + "--label=org.opencontainers.image.revision=deadbeef", + "--label=io.vela.build.author=octocat@example.com", + "--label=io.vela.build.number=1", + "--label=io.vela.build.repo=octocat/scripts", + "--label=io.vela.build.commit=deadbeef", + "--label=io.vela.build.url=git.example.com", + "--label=io.vela.build.link=https://vela.example.com/velaOrg/velaRepo/1", + "--label=io.vela.build.host=vela-worker", + "--label=io.vela.build.topics=id123", "--dockerfile=Dockerfile", "--no-push", "--push-retry=1", @@ -775,7 +879,7 @@ func TestDocker_Plugin_Command_With_TarPath(t *testing.T) { // run test got := p.Command() - if !strings.EqualFold(got.String(), want.String()) { + if !strings.EqualFold(sortCmdArgs(got).String(), sortCmdArgs(want).String()) { t.Errorf("Command is %v, want %v", got, want) } } @@ -823,15 +927,17 @@ func TestDocker_Plugin_Command_With_UseSingleSnapshot(t *testing.T) { "--cache-repo=index.docker.io/target/vela-kaniko", "--context=.", "--destination=index.docker.io/target/vela-kaniko:latest", - "--label org.opencontainers.image.created=now", - "--label org.opencontainers.image.url=git.example.com", - "--label org.opencontainers.image.revision=deadbeef", - "--label io.vela.build.author=octocat@example.com", - "--label io.vela.build.number=1", - "--label io.vela.build.repo=octocat/scripts", - "--label io.vela.build.commit=deadbeef", - "--label io.vela.build.url=git.example.com", - "--label io.vela.build.topics=id123", + "--label=org.opencontainers.image.created=now", + "--label=org.opencontainers.image.url=git.example.com", + "--label=org.opencontainers.image.revision=deadbeef", + "--label=io.vela.build.author=octocat@example.com", + "--label=io.vela.build.number=1", + "--label=io.vela.build.repo=octocat/scripts", + "--label=io.vela.build.commit=deadbeef", + "--label=io.vela.build.url=git.example.com", + "--label=io.vela.build.link=https://vela.example.com/velaOrg/velaRepo/1", + "--label=io.vela.build.host=vela-worker", + "--label=io.vela.build.topics=id123", "--dockerfile=Dockerfile", "--no-push", "--push-retry=1", @@ -842,7 +948,7 @@ func TestDocker_Plugin_Command_With_UseSingleSnapshot(t *testing.T) { // run test got := p.Command() - if !strings.EqualFold(got.String(), want.String()) { + if !strings.EqualFold(sortCmdArgs(got).String(), sortCmdArgs(want).String()) { t.Errorf("Command is %v, want %v", got, want) } } @@ -888,15 +994,17 @@ func TestDocker_Plugin_Command_With_UseIgnoreVarRunFalse(t *testing.T) { "--cache-repo=index.docker.io/target/vela-kaniko", "--context=.", "--destination=index.docker.io/target/vela-kaniko:latest", - "--label org.opencontainers.image.created=now", - "--label org.opencontainers.image.url=git.example.com", - "--label org.opencontainers.image.revision=deadbeef", - "--label io.vela.build.author=octocat@example.com", - "--label io.vela.build.number=1", - "--label io.vela.build.repo=octocat/scripts", - "--label io.vela.build.commit=deadbeef", - "--label io.vela.build.url=git.example.com", - "--label io.vela.build.topics=id123", + "--label=org.opencontainers.image.created=now", + "--label=org.opencontainers.image.url=git.example.com", + "--label=org.opencontainers.image.revision=deadbeef", + "--label=io.vela.build.author=octocat@example.com", + "--label=io.vela.build.number=1", + "--label=io.vela.build.repo=octocat/scripts", + "--label=io.vela.build.commit=deadbeef", + "--label=io.vela.build.url=git.example.com", + "--label=io.vela.build.link=https://vela.example.com/velaOrg/velaRepo/1", + "--label=io.vela.build.host=vela-worker", + "--label=io.vela.build.topics=id123", "--dockerfile=Dockerfile", "--no-push", "--push-retry=1", @@ -907,7 +1015,7 @@ func TestDocker_Plugin_Command_With_UseIgnoreVarRunFalse(t *testing.T) { // run test got := p.Command() - if !strings.EqualFold(got.String(), want.String()) { + if !strings.EqualFold(sortCmdArgs(got).String(), sortCmdArgs(want).String()) { t.Errorf("Command is %v, want %v", got, want) } } @@ -953,15 +1061,17 @@ func TestDocker_Plugin_Command_With_UseIgnoreVarRunTrue(t *testing.T) { "--cache-repo=index.docker.io/target/vela-kaniko", "--context=.", "--destination=index.docker.io/target/vela-kaniko:latest", - "--label org.opencontainers.image.created=now", - "--label org.opencontainers.image.url=git.example.com", - "--label org.opencontainers.image.revision=deadbeef", - "--label io.vela.build.author=octocat@example.com", - "--label io.vela.build.number=1", - "--label io.vela.build.repo=octocat/scripts", - "--label io.vela.build.commit=deadbeef", - "--label io.vela.build.url=git.example.com", - "--label io.vela.build.topics=id123", + "--label=org.opencontainers.image.created=now", + "--label=org.opencontainers.image.url=git.example.com", + "--label=org.opencontainers.image.revision=deadbeef", + "--label=io.vela.build.author=octocat@example.com", + "--label=io.vela.build.number=1", + "--label=io.vela.build.repo=octocat/scripts", + "--label=io.vela.build.commit=deadbeef", + "--label=io.vela.build.url=git.example.com", + "--label=io.vela.build.link=https://vela.example.com/velaOrg/velaRepo/1", + "--label=io.vela.build.host=vela-worker", + "--label=io.vela.build.topics=id123", "--dockerfile=Dockerfile", "--no-push", "--push-retry=1", @@ -972,7 +1082,7 @@ func TestDocker_Plugin_Command_With_UseIgnoreVarRunTrue(t *testing.T) { // run test got := p.Command() - if !strings.EqualFold(got.String(), want.String()) { + if !strings.EqualFold(sortCmdArgs(got).String(), sortCmdArgs(want).String()) { t.Errorf("Command is %v, want %v", got, want) } } @@ -1019,15 +1129,17 @@ func TestDocker_Plugin_Command_With_ForceBuildMetaData(t *testing.T) { "--cache-repo=index.docker.io/target/vela-kaniko", "--context=.", "--destination=index.docker.io/target/vela-kaniko:latest", - "--label org.opencontainers.image.created=now", - "--label org.opencontainers.image.url=git.example.com", - "--label org.opencontainers.image.revision=deadbeef", - "--label io.vela.build.author=octocat@example.com", - "--label io.vela.build.number=1", - "--label io.vela.build.repo=octocat/scripts", - "--label io.vela.build.commit=deadbeef", - "--label io.vela.build.url=git.example.com", - "--label io.vela.build.topics=id123", + "--label=org.opencontainers.image.created=now", + "--label=org.opencontainers.image.url=git.example.com", + "--label=org.opencontainers.image.revision=deadbeef", + "--label=io.vela.build.author=octocat@example.com", + "--label=io.vela.build.number=1", + "--label=io.vela.build.repo=octocat/scripts", + "--label=io.vela.build.commit=deadbeef", + "--label=io.vela.build.url=git.example.com", + "--label=io.vela.build.link=https://vela.example.com/velaOrg/velaRepo/1", + "--label=io.vela.build.host=vela-worker", + "--label=io.vela.build.topics=id123", "--dockerfile=Dockerfile", "--no-push", "--push-retry=1", @@ -1039,7 +1151,7 @@ func TestDocker_Plugin_Command_With_ForceBuildMetaData(t *testing.T) { // run test got := p.Command() - if !strings.EqualFold(got.String(), want.String()) { + if !strings.EqualFold(sortCmdArgs(got).String(), sortCmdArgs(want).String()) { t.Errorf("Command is %v, want %v", got, want) } } @@ -1086,15 +1198,17 @@ func TestDocker_Plugin_Command_With_Mirror(t *testing.T) { "--cache-repo=index.docker.io/target/vela-kaniko", "--context=.", "--destination=index.docker.io/target/vela-kaniko:latest", - "--label org.opencontainers.image.created=now", - "--label org.opencontainers.image.url=git.example.com", - "--label org.opencontainers.image.revision=deadbeef", - "--label io.vela.build.author=octocat@example.com", - "--label io.vela.build.number=1", - "--label io.vela.build.repo=octocat/scripts", - "--label io.vela.build.commit=deadbeef", - "--label io.vela.build.url=git.example.com", - "--label io.vela.build.topics=id123", + "--label=org.opencontainers.image.created=now", + "--label=org.opencontainers.image.url=git.example.com", + "--label=org.opencontainers.image.revision=deadbeef", + "--label=io.vela.build.author=octocat@example.com", + "--label=io.vela.build.number=1", + "--label=io.vela.build.repo=octocat/scripts", + "--label=io.vela.build.commit=deadbeef", + "--label=io.vela.build.url=git.example.com", + "--label=io.vela.build.link=https://vela.example.com/velaOrg/velaRepo/1", + "--label=io.vela.build.host=vela-worker", + "--label=io.vela.build.topics=id123", "--dockerfile=Dockerfile", "--no-push", "--registry-mirror=company.mirror.io", @@ -1106,7 +1220,7 @@ func TestDocker_Plugin_Command_With_Mirror(t *testing.T) { // run test got := p.Command() - if !strings.EqualFold(got.String(), want.String()) { + if !strings.EqualFold(sortCmdArgs(got).String(), sortCmdArgs(want).String()) { t.Errorf("Command is %v, want %v", got, want) } } @@ -1156,15 +1270,17 @@ func TestDocker_Plugin_Command_With_Compression(t *testing.T) { "--compression-level=3", "--context=.", "--destination=index.docker.io/target/vela-kaniko:latest", - "--label org.opencontainers.image.created=now", - "--label org.opencontainers.image.url=git.example.com", - "--label org.opencontainers.image.revision=deadbeef", - "--label io.vela.build.author=octocat@example.com", - "--label io.vela.build.number=1", - "--label io.vela.build.repo=octocat/scripts", - "--label io.vela.build.commit=deadbeef", - "--label io.vela.build.url=git.example.com", - "--label io.vela.build.topics=id123", + "--label=org.opencontainers.image.created=now", + "--label=org.opencontainers.image.url=git.example.com", + "--label=org.opencontainers.image.revision=deadbeef", + "--label=io.vela.build.author=octocat@example.com", + "--label=io.vela.build.number=1", + "--label=io.vela.build.repo=octocat/scripts", + "--label=io.vela.build.commit=deadbeef", + "--label=io.vela.build.url=git.example.com", + "--label=io.vela.build.link=https://vela.example.com/velaOrg/velaRepo/1", + "--label=io.vela.build.host=vela-worker", + "--label=io.vela.build.topics=id123", "--dockerfile=Dockerfile", "--no-push", "--push-retry=1", @@ -1175,7 +1291,7 @@ func TestDocker_Plugin_Command_With_Compression(t *testing.T) { // run test got := p.Command() - if !strings.EqualFold(got.String(), want.String()) { + if !strings.EqualFold(sortCmdArgs(got).String(), sortCmdArgs(want).String()) { t.Errorf("Command is %v, want %v", got, want) } } @@ -1220,15 +1336,17 @@ func TestDocker_Plugin_Command_NoCacheRepo(t *testing.T) { "--cache-repo=index.docker.io/target/vela-kaniko", "--context=.", "--destination=index.docker.io/target/vela-kaniko:latest", - "--label org.opencontainers.image.created=now", - "--label org.opencontainers.image.url=git.example.com", - "--label org.opencontainers.image.revision=deadbeef", - "--label io.vela.build.author=octocat@example.com", - "--label io.vela.build.number=1", - "--label io.vela.build.repo=octocat/scripts", - "--label io.vela.build.commit=deadbeef", - "--label io.vela.build.url=git.example.com", - "--label io.vela.build.topics=id123", + "--label=org.opencontainers.image.created=now", + "--label=org.opencontainers.image.url=git.example.com", + "--label=org.opencontainers.image.revision=deadbeef", + "--label=io.vela.build.author=octocat@example.com", + "--label=io.vela.build.number=1", + "--label=io.vela.build.repo=octocat/scripts", + "--label=io.vela.build.commit=deadbeef", + "--label=io.vela.build.url=git.example.com", + "--label=io.vela.build.link=https://vela.example.com/velaOrg/velaRepo/1", + "--label=io.vela.build.host=vela-worker", + "--label=io.vela.build.topics=id123", "--dockerfile=Dockerfile", "--no-push", "--push-retry=1", @@ -1238,7 +1356,7 @@ func TestDocker_Plugin_Command_NoCacheRepo(t *testing.T) { // run test got := p.Command() - if !strings.EqualFold(got.String(), want.String()) { + if !strings.EqualFold(sortCmdArgs(got).String(), sortCmdArgs(want).String()) { t.Errorf("Command is %v, want %v", got, want) } } @@ -1284,15 +1402,17 @@ func TestDocker_Plugin_Command_NoDryRun(t *testing.T) { "--cache-repo=index.docker.io/target/vela-kaniko", "--context=.", "--destination=index.docker.io/target/vela-kaniko:latest", - "--label org.opencontainers.image.created=now", - "--label org.opencontainers.image.url=git.example.com", - "--label org.opencontainers.image.revision=deadbeef", - "--label io.vela.build.author=octocat@example.com", - "--label io.vela.build.number=1", - "--label io.vela.build.repo=octocat/scripts", - "--label io.vela.build.commit=deadbeef", - "--label io.vela.build.url=git.example.com", - "--label io.vela.build.topics=id123", + "--label=org.opencontainers.image.created=now", + "--label=org.opencontainers.image.url=git.example.com", + "--label=org.opencontainers.image.revision=deadbeef", + "--label=io.vela.build.author=octocat@example.com", + "--label=io.vela.build.number=1", + "--label=io.vela.build.repo=octocat/scripts", + "--label=io.vela.build.commit=deadbeef", + "--label=io.vela.build.url=git.example.com", + "--label=io.vela.build.link=https://vela.example.com/velaOrg/velaRepo/1", + "--label=io.vela.build.host=vela-worker", + "--label=io.vela.build.topics=id123", "--dockerfile=Dockerfile", "--push-retry=1", "--verbosity=info", @@ -1301,7 +1421,7 @@ func TestDocker_Plugin_Command_NoDryRun(t *testing.T) { // run test got := p.Command() - if !strings.EqualFold(got.String(), want.String()) { + if !strings.EqualFold(sortCmdArgs(got).String(), sortCmdArgs(want).String()) { t.Errorf("Command is %v, want %v", got, want) } } @@ -1351,15 +1471,17 @@ func TestDocker_Plugin_Command_CustomPlatform(t *testing.T) { "--cache-repo=index.docker.io/target/vela-kaniko", "--context=.", "--destination=index.docker.io/target/vela-kaniko:latest", - "--label org.opencontainers.image.created=now", - "--label org.opencontainers.image.url=git.example.com", - "--label org.opencontainers.image.revision=deadbeef", - "--label io.vela.build.author=octocat@example.com", - "--label io.vela.build.number=1", - "--label io.vela.build.repo=octocat/scripts", - "--label io.vela.build.commit=deadbeef", - "--label io.vela.build.url=git.example.com", - "--label io.vela.build.topics=id123", + "--label=org.opencontainers.image.created=now", + "--label=org.opencontainers.image.url=git.example.com", + "--label=org.opencontainers.image.revision=deadbeef", + "--label=io.vela.build.author=octocat@example.com", + "--label=io.vela.build.number=1", + "--label=io.vela.build.repo=octocat/scripts", + "--label=io.vela.build.commit=deadbeef", + "--label=io.vela.build.url=git.example.com", + "--label=io.vela.build.link=https://vela.example.com/velaOrg/velaRepo/1", + "--label=io.vela.build.host=vela-worker", + "--label=io.vela.build.topics=id123", "--dockerfile=Dockerfile", "--no-push", "--push-retry=1", @@ -1375,7 +1497,7 @@ func TestDocker_Plugin_Command_CustomPlatform(t *testing.T) { // run test got := p.Command() - if !strings.EqualFold(got.String(), want.String()) { + if !strings.EqualFold(sortCmdArgs(got).String(), sortCmdArgs(want).String()) { t.Errorf("Command is %v, want %v", got, want) } } @@ -1595,5 +1717,26 @@ func testLabel() *Label { Number: 1, Topics: []string{"id123"}, URL: "git.example.com", + BuildURL: "https://vela.example.com/velaOrg/velaRepo/1", + Host: "vela-worker", } } + +func sortCmdArgs(cmd *exec.Cmd) *exec.Cmd { + labels := []string{} + otherArgs := []string{} + + for _, arg := range cmd.Args { + if strings.HasPrefix(arg, "--label") { + labels = append(labels, arg) + } else { + otherArgs = append(otherArgs, arg) + } + } + + sort.Strings(labels) + + cmd.Args = append(otherArgs, labels...) + + return cmd +} diff --git a/cmd/vela-kaniko/repo.go b/cmd/vela-kaniko/repo.go index 40070aa..cf347ad 100644 --- a/cmd/vela-kaniko/repo.go +++ b/cmd/vela-kaniko/repo.go @@ -54,6 +54,12 @@ type ( Topics []string // direct url of the repository URL string + // direct url of the build + BuildURL string + // host that the image is built on + Host string + // custom set of labels that the user can provide + CustomSet []string } ) @@ -61,21 +67,6 @@ type ( func (r *Repo) AddLabels() []string { // store all the topics topics := r.Label.Topics - // labels we will return - labels := []string{} - - // append the standard set of labels - labels = append( - labels, - fmt.Sprintf("org.opencontainers.image.created=%s", r.Label.Created), - fmt.Sprintf("org.opencontainers.image.url=%s", r.Label.URL), - fmt.Sprintf("org.opencontainers.image.revision=%s", r.Label.Commit), - fmt.Sprintf("io.vela.build.author=%s", r.Label.AuthorEmail), - fmt.Sprintf("io.vela.build.number=%d", r.Label.Number), - fmt.Sprintf("io.vela.build.repo=%s", r.Label.FullName), - fmt.Sprintf("io.vela.build.commit=%s", r.Label.Commit), - fmt.Sprintf("io.vela.build.url=%s", r.Label.URL), - ) // if a filter is defined, use it to only // include those that match the filter @@ -92,11 +83,41 @@ func (r *Repo) AddLabels() []string { } } - // only append topics if we have any, since the possibility of - // it being empty is much higher than any of the other fields - // that are derived from standard Vela build variables + labelMap := map[string]string{ + "org.opencontainers.image.created": r.Label.Created, + "org.opencontainers.image.url": r.Label.URL, + "org.opencontainers.image.revision": r.Label.Commit, + "io.vela.build.author": r.Label.AuthorEmail, + "io.vela.build.number": fmt.Sprintf("%d", r.Label.Number), + "io.vela.build.repo": r.Label.FullName, + "io.vela.build.commit": r.Label.Commit, + "io.vela.build.url": r.Label.URL, + "io.vela.build.link": r.Label.BuildURL, + "io.vela.build.host": r.Label.Host, + } + if len(topics) > 0 { - labels = append(labels, fmt.Sprintf("io.vela.build.topics=%s", strings.Join(topics, ","))) + labelMap["io.vela.build.topics"] = strings.Join(topics, ",") + } + + // labels we will return + labels := []string{} + + // append the standard set of labels + for k, v := range labelMap { + labels = append(labels, fmt.Sprintf("%s=%s", k, v)) + } + + // append the custom set of labels + for _, label := range r.Label.CustomSet { + parsed := strings.Split(label, "=") + + // do not let user overwrite predefined labels + if _, exists := labelMap[parsed[0]]; exists { + logrus.Fatalf("custom label %s already exists in predefined labels", parsed[0]) + } + + labels = append(labels, label) } return labels @@ -172,5 +193,15 @@ func (r *Repo) Validate() error { } } + if len(r.Label.CustomSet) > 0 { + for _, label := range r.Label.CustomSet { + split := strings.Split(label, "=") + + if len(split) != 2 { + return fmt.Errorf("custom label %s is not in the format key=value", label) + } + } + } + return nil }