diff --git a/image/build.go b/image/build.go index c2e6fbae..1080607f 100644 --- a/image/build.go +++ b/image/build.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io" + "os" "path/filepath" "time" @@ -14,6 +15,8 @@ import ( "github.com/moby/term" "github.com/docker/docker/api/types/build" + "github.com/docker/docker/builder/remotecontext/git" + "github.com/docker/docker/builder/remotecontext/urlutil" "github.com/docker/docker/pkg/jsonmessage" "github.com/docker/go-sdk/client" ) @@ -23,13 +26,25 @@ import ( // This function is useful for creating a build context to build an image. // The dockerfile path needs to be relative to the build context. func ArchiveBuildContext(dir string, dockerfile string) (r io.ReadCloser, err error) { - // always pass context as absolute path - abs, err := filepath.Abs(dir) - if err != nil { - return nil, fmt.Errorf("absolute path: %w", err) + switch { + case isLocalDir(dir): + // always pass context as absolute path + dir, err = filepath.Abs(dir) + if err != nil { + return nil, fmt.Errorf("absolute path: %w", err) + } + case urlutil.IsGitURL(dir): + clone, err := git.Clone(dir) + if err != nil { + return nil, fmt.Errorf("unable to clone git build context: %w", err) + } + dir = clone + // TODO case urlutil.IsURL(dir): + default: + return nil, fmt.Errorf("unable to prepare context: path %q not found", dir) } - dockerIgnoreExists, excluded, err := ParseDockerIgnore(abs) + dockerIgnoreExists, excluded, err := ParseDockerIgnore(dir) if err != nil { return nil, fmt.Errorf("parse docker ignore: %w", err) } @@ -41,7 +56,7 @@ func ArchiveBuildContext(dir string, dockerfile string) (r io.ReadCloser, err er } buildContext, err := archive.TarWithOptions( - abs, + dir, &archive.TarOptions{ ExcludePatterns: excluded, IncludeFiles: includes, @@ -55,6 +70,11 @@ func ArchiveBuildContext(dir string, dockerfile string) (r io.ReadCloser, err er return buildContext, nil } +func isLocalDir(c string) bool { + _, err := os.Stat(c) + return err == nil +} + // ImageBuildClient is a client that can build images. type ImageBuildClient interface { ImageClient diff --git a/image/go.mod b/image/go.mod index fecf4232..9f245919 100644 --- a/image/go.mod +++ b/image/go.mod @@ -40,6 +40,7 @@ require ( github.com/klauspost/compress v1.18.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/sys/sequential v0.6.0 // indirect + github.com/moby/sys/symlink v0.3.0 // indirect github.com/moby/sys/user v0.4.0 // indirect github.com/moby/sys/userns v0.1.0 // indirect github.com/morikuni/aec v1.0.0 // indirect diff --git a/image/go.sum b/image/go.sum index 2059f8da..af2a2d65 100644 --- a/image/go.sum +++ b/image/go.sum @@ -62,6 +62,8 @@ github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs= github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= +github.com/moby/sys/symlink v0.3.0 h1:GZX89mEZ9u53f97npBy4Rc3vJKj7JBDj/PN2I22GrNU= +github.com/moby/sys/symlink v0.3.0/go.mod h1:3eNdhduHmYPcgsJtZXW1W4XUJdZGBIkttZ8xKqPUJq0= github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs= github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=