grim/convey

Add a podman/build task with unit tests
redux
2021-10-11, Gary Kramlich
fc69cdc14dd1
Parents 18b7a8f77329
Children 10db01f3d13a
Add a podman/build task with unit tests
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/podman/build.go Mon Oct 11 04:00:43 2021 -0500
@@ -0,0 +1,99 @@
+package podman
+
+import (
+ "path/filepath"
+ "strings"
+
+ log "github.com/sirupsen/logrus"
+
+ "keep.imfreedom.org/grim/convey/environment"
+ "keep.imfreedom.org/grim/convey/exec"
+ "keep.imfreedom.org/grim/convey/runtime"
+ "keep.imfreedom.org/grim/convey/tasks"
+ "keep.imfreedom.org/grim/convey/yaml"
+)
+
+type Build struct {
+ Annotations yaml.StringOrSlice `yaml:"annotations"`
+ Containerfile string `yaml:"containerfile"`
+ Context string `yaml:"context"`
+ Tags yaml.StringOrSlice `yaml:"tags"`
+ Target string `yaml:"target"`
+}
+
+func (b *Build) Execute(name string, logger *log.Entry, stageEnv environment.Environment, rt *runtime.Runtime) error {
+ env := stageEnv.Copy().Merge(rt.Environment)
+
+ ws, err := rt.Workspace()
+ if err != nil {
+ return err
+ }
+
+ context := filepath.Join(ws.Path(), env.Expand(b.Context))
+ if !strings.HasSuffix(context, string(filepath.Separator)) {
+ context += string(filepath.Separator)
+ }
+ log.Infof("resolved context: %q", context)
+ log.Infof("wspath: %q", ws.Path())
+ if !strings.HasPrefix(context, ws.Path()) {
+ return ErrContextOutsideOfWorkspace
+ }
+
+ generator := exec.NewGenerator(
+ "podman",
+ "build",
+ "--tag", env.Expand(b.Tags[0]),
+ "--file", env.Expand(b.Containerfile),
+ )
+
+ for _, annotation := range b.Annotations {
+ generator.Append("--annotation", annotation)
+ }
+
+ if b.Target != "" {
+ generator.Append("--target", b.Target)
+ }
+
+ generator.Append(context)
+
+ err = exec.Run(name, generator.Command(), rt.Timeout)
+ if err != nil {
+ return err
+ }
+
+ // if we were give more than one tag run a tag test to do the rest
+ if len(b.Tags) > 1 {
+ t := Tag{
+ Image: b.Tags[0],
+ Targets: b.Tags[1:],
+ }
+
+ return t.Execute(name, logger, stageEnv, rt)
+ }
+
+ return nil
+}
+
+func (b *Build) New() tasks.Task {
+ return &Build{}
+}
+
+func (b *Build) Valid() error {
+ if b.Containerfile == "" {
+ return ErrNoContainerfile
+ }
+
+ if len(b.Tags) == 0 {
+ return ErrNoTags
+ }
+
+ if b.Context == "" {
+ b.Context = "."
+ }
+
+ return nil
+}
+
+func (b *Build) Deprecated() error {
+ return nil
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/podman/build_test.go Mon Oct 11 04:00:43 2021 -0500
@@ -0,0 +1,38 @@
+package podman
+
+import (
+ "testing"
+
+ . "github.com/onsi/gomega"
+)
+
+func TestBuild(t *testing.T) {
+ g := NewGomegaWithT(t)
+
+ b := &Build{
+ Containerfile: "Dockerfile",
+ Tags: []string{"foo:latest"},
+ }
+
+ g.Expect(b.Valid()).To(BeNil())
+}
+
+func TestBuildContainerfileRequired(t *testing.T) {
+ g := NewGomegaWithT(t)
+
+ b := &Build{
+ Tags: []string{"foo:latest"},
+ }
+
+ g.Expect(b.Valid()).To(MatchError(ErrNoContainerfile))
+}
+
+func TestBuildTagsRequired(t *testing.T) {
+ g := NewGomegaWithT(t)
+
+ b := &Build{
+ Containerfile: "Dockerfile",
+ }
+
+ g.Expect(b.Valid()).To(MatchError(ErrNoTags))
+}
--- a/podman/errors.go Mon Oct 11 02:17:28 2021 -0500
+++ b/podman/errors.go Mon Oct 11 04:00:43 2021 -0500
@@ -8,6 +8,10 @@
// common errors
ErrNoImage = errors.New("no image specified")
+ // build errors
+ ErrNoContainerfile = errors.New("no container file specified")
+ ErrContextOutsideOfWorkspace = errors.New("context is outside of the workspace")
+
// login/logout errors
ErrNoRegistry = errors.New("no registry specified")
ErrNoUsername = errors.New("no username provided")
--- a/podman/tasks.go Mon Oct 11 02:17:28 2021 -0500
+++ b/podman/tasks.go Mon Oct 11 04:00:43 2021 -0500
@@ -6,6 +6,7 @@
var (
Tasks = map[string]tasks.Task{
+ "podman/build": &Build{},
"podman/login": &Login{},
"podman/logout": &Logout{},
"podman/pull": &Pull{},