diff --git a/buildx/build.go b/buildx/build.go index d458ef5..4affbf9 100644 --- a/buildx/build.go +++ b/buildx/build.go @@ -6,12 +6,12 @@ import ( "git.tek.govt.hu/dowerx/buildx-manager/config" ) -func RepoToCommands(repo *Repository) ([]Command, error) { +func RepoToCommands(repo *Repository, registries []string) ([]Command, []Command, error) { cfg := config.GetConfig() workdir, err := filepath.Abs(repo.Path) if err != nil { - return nil, err + return nil, nil, err } globalArgs := make([]string, 0) @@ -19,13 +19,11 @@ func RepoToCommands(repo *Repository) ([]Command, error) { globalArgs = append(globalArgs, "--build-arg", arg.Key+"="+arg.Value) } - commands := make([]Command, 0) + buildCommands := make([]Command, 0) // builds for _, build := range repo.Builds { - id := uid() - - cmd := Command{Program: cfg.DockerExecutable, Arguments: []string{"buildx", "build", "-f", build.Dockerfile, "--platform", "linux/" + build.Architecture, "--tag", id, cfg.Action}, WorkingDirectory: workdir} + cmd := Command{Program: cfg.DockerExecutable, Arguments: []string{"buildx", "build", "-f", build.Dockerfile, "--platform", "linux/" + build.Architecture, cfg.Action}, WorkingDirectory: workdir} // args cmd.Arguments = append(cmd.Arguments, globalArgs...) @@ -35,18 +33,30 @@ func RepoToCommands(repo *Repository) ([]Command, error) { // tags for _, tag := range build.Tags { - addUniqueTag(id, repo.Library+"/"+tag) + for _, registry := range registries { + cmd.Arguments = append(cmd.Arguments, "--tag", registry+"/"+repo.Library+"/"+repo.Name+":"+tag) + } } - commands = append(commands, cmd) + cmd.Arguments = append(cmd.Arguments, build.Context) + + buildCommands = append(buildCommands, cmd) } // tags - for _, rtag := range repo.Tags { - for _, tag := range rtag.Tags { - addGroupTag(repo.Library+"/"+rtag.Name, repo.Library+"/"+tag) + tagCommands := make([]Command, 0) + + for _, registry := range registries { + for _, groupTag := range repo.Tags { + cmd := Command{Program: cfg.DockerExecutable, Arguments: []string{"buildx", "imagetools", "create", "--tag", registry + "/" + repo.Library + "/" + repo.Name + ":" + groupTag.Name}} + + for _, tag := range groupTag.Tags { + cmd.Arguments = append(cmd.Arguments, registry+"/"+repo.Library+"/"+repo.Name+":"+tag) + } + + tagCommands = append(tagCommands, cmd) } } - return commands, err + return buildCommands, tagCommands, err } diff --git a/buildx/command.go b/buildx/command.go index 2b2a03e..4619925 100644 --- a/buildx/command.go +++ b/buildx/command.go @@ -1,10 +1,12 @@ package buildx import ( + "fmt" "os" "os/exec" "git.tek.govt.hu/dowerx/buildx-manager/config" + "github.com/sanity-io/litter" ) type Command struct { @@ -20,6 +22,9 @@ func (c *Command) Run() error { if config.GetConfig().Verbose { cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr + + fmt.Println("running command:") + litter.Dump(c) } return cmd.Run() diff --git a/buildx/load.go b/buildx/load.go index 9dfb31a..c050d35 100644 --- a/buildx/load.go +++ b/buildx/load.go @@ -1,6 +1,7 @@ package buildx import ( + "errors" "os" "github.com/drone/envsubst" @@ -13,6 +14,12 @@ func subst(ref *string) error { return err } +func defaultValue(ref *string, value string) { + if *ref == "" { + *ref = value + } +} + func LoadJob(path string) (*Job, error) { var job Job @@ -26,6 +33,31 @@ func LoadJob(path string) (*Job, error) { return nil, err } + // check for empty fields + + // registry + if job.Registries == nil { + job.Registries = []string{"docker.io"} + } + + // repos + for i, repo := range job.Repositories { + if repo.Name == "" { + return nil, errors.New("missing repository name") + } + if repo.Library == "" { + return nil, errors.New("missing library") + } + + defaultValue(&job.Repositories[i].Path, repo.Name) + + // builds + for j := range job.Repositories[i].Builds { + defaultValue(&job.Repositories[i].Builds[j].Context, ".") + defaultValue(&job.Repositories[i].Builds[j].Dockerfile, "Dockerfile") + } + } + // envsubst // registries diff --git a/buildx/tag.go b/buildx/tag.go deleted file mode 100644 index fd25583..0000000 --- a/buildx/tag.go +++ /dev/null @@ -1,62 +0,0 @@ -package buildx - -import ( - "git.tek.govt.hu/dowerx/buildx-manager/config" - "golang.org/x/exp/rand" -) - -var uniqueTags map[string][]string = make(map[string][]string) -var groupTags map[string][]string = make(map[string][]string) -var runes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") - -func uid() string { - for { - id := make([]rune, 16) - for i := range id { - id[i] = runes[rand.Intn(len(runes))] - } - - _, exists := uniqueTags[string(id)] - if !exists { - return string(id) - } - } -} - -func addUniqueTag(id string, tag string) { - uniqueTags[id] = append(uniqueTags[id], tag) -} - -func addGroupTag(id string, tag string) { - groupTags[id] = append(groupTags[id], tag) -} - -func TagsToCommands(registries []string) []Command { - cfg := config.GetConfig() - - commands := make([]Command, 0) - - for _, registry := range registries { - - // unique tags - for id, tags := range uniqueTags { - for _, tag := range tags { - cmd := Command{Program: cfg.DockerExecutable, Arguments: []string{"buildx", "imagetools", "create", "-t", registry + "/" + tag, id}} - commands = append(commands, cmd) - } - } - - // group tags - for newTag, tags := range groupTags { - cmd := Command{Program: cfg.DockerExecutable, Arguments: []string{"buildx", "imagetools", "create", "-t", registry + "/" + newTag}} - - for _, tag := range tags { - cmd.Arguments = append(cmd.Arguments, registry+"/"+tag) - } - - commands = append(commands, cmd) - } - } - - return commands -} diff --git a/buildx/types.go b/buildx/types.go index 5b55505..3bd894a 100644 --- a/buildx/types.go +++ b/buildx/types.go @@ -18,9 +18,10 @@ type Tag struct { type Build struct { Architecture string `yaml:"arch"` - Dockerfile string `yaml:"dockerfile" default:"Dockerfile"` + Dockerfile string `yaml:"dockerfile"` Tags []string `yaml:"tags"` Arguments []Argument `yaml:"args"` + Context string `yaml:"context"` } type Repository struct { diff --git a/config/config.go b/config/config.go index e32eca4..e1ac697 100644 --- a/config/config.go +++ b/config/config.go @@ -36,6 +36,7 @@ func GetConfig() Config { if config.Action != "load" && config.Action != "push" { panic("action must be \"load\" or \"push\"") } + config.Action = "--" + config.Action return *config } diff --git a/go.sum b/go.sum index c96dba1..8a37a11 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/creasty/defaults v1.8.0 h1:z27FJxCAa0JKt3utc0sCImAEb+spPucmKoOdLHvHYKk= +github.com/creasty/defaults v1.8.0/go.mod h1:iGzKe6pbEHnpMPtfDXZEr0NVxWnPTjb1bbDy08fPzYM= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/drone/envsubst v1.0.3 h1:PCIBwNDYjs50AsLZPYdfhSATKaRg/FJmDc2D6+C2x8g= github.com/drone/envsubst v1.0.3/go.mod h1:N2jZmlMufstn1KEqvbHjw40h1KyTmnVzHcSc9bFiJ2g= diff --git a/main.go b/main.go index 302a949..fe3208b 100644 --- a/main.go +++ b/main.go @@ -2,17 +2,13 @@ package main import ( "fmt" - "time" "git.tek.govt.hu/dowerx/buildx-manager/buildx" "git.tek.govt.hu/dowerx/buildx-manager/config" "github.com/sanity-io/litter" - "golang.org/x/exp/rand" ) func main() { - rand.Seed(uint64(time.Now().Unix())) - cfg := config.GetConfig() job, err := buildx.LoadJob(cfg.File) @@ -20,18 +16,16 @@ func main() { panic(err) } - buildCommands := make([]buildx.Command, 0) + var buildCommands []buildx.Command + var tagCommands []buildx.Command for _, repo := range job.Repositories { - cmd, err := buildx.RepoToCommands(&repo) + buildCommands, tagCommands, err = buildx.RepoToCommands(&repo, job.Registries) if err != nil { panic(err) } - buildCommands = append(buildCommands, cmd...) } - tagCommands := buildx.TagsToCommands(job.Registries) - if cfg.Verbose { fmt.Println("config:") litter.Dump(cfg)