|
|
@@ -2,7 +2,9 @@ package deploy
|
|
|
|
|
|
import (
|
|
|
"fmt"
|
|
|
+ "os"
|
|
|
"path/filepath"
|
|
|
+ "strings"
|
|
|
|
|
|
"github.com/porter-dev/porter/cli/cmd/api"
|
|
|
"github.com/porter-dev/porter/cli/cmd/docker"
|
|
|
@@ -20,24 +22,34 @@ type BuildAgent struct {
|
|
|
}
|
|
|
|
|
|
// BuildDocker uses the local Docker daemon to build the image
|
|
|
-func (b *BuildAgent) BuildDocker(dockerAgent *docker.Agent, buildCtx, tag string) error {
|
|
|
- opts := &docker.BuildOpts{
|
|
|
- ImageRepo: b.imageRepo,
|
|
|
- Tag: tag,
|
|
|
- BuildContext: buildCtx,
|
|
|
- Env: b.env,
|
|
|
- }
|
|
|
-
|
|
|
- // use the absolute path to the dockerfile
|
|
|
- localDockerfileAbs, err := filepath.Abs(b.LocalDockerfile)
|
|
|
+func (b *BuildAgent) BuildDocker(
|
|
|
+ dockerAgent *docker.Agent,
|
|
|
+ basePath,
|
|
|
+ buildCtx,
|
|
|
+ dockerfilePath,
|
|
|
+ tag string,
|
|
|
+) error {
|
|
|
+ buildCtx, dockerfilePath, isDockerfileInCtx, err := ResolveDockerPaths(
|
|
|
+ basePath,
|
|
|
+ buildCtx,
|
|
|
+ dockerfilePath,
|
|
|
+ )
|
|
|
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
+ opts := &docker.BuildOpts{
|
|
|
+ ImageRepo: b.imageRepo,
|
|
|
+ Tag: tag,
|
|
|
+ BuildContext: buildCtx,
|
|
|
+ Env: b.env,
|
|
|
+ DockerfilePath: dockerfilePath,
|
|
|
+ IsDockerfileInCtx: isDockerfileInCtx,
|
|
|
+ }
|
|
|
+
|
|
|
return dockerAgent.BuildLocal(
|
|
|
opts,
|
|
|
- localDockerfileAbs,
|
|
|
)
|
|
|
}
|
|
|
|
|
|
@@ -80,3 +92,49 @@ func (b *BuildAgent) BuildPack(dockerAgent *docker.Agent, dst, tag string) error
|
|
|
fmt.Sprintf("%s:%s", b.imageRepo, tag),
|
|
|
)
|
|
|
}
|
|
|
+
|
|
|
+// ResolveDockerPaths returns a path to the dockerfile that is either relative or absolute, and a path
|
|
|
+// to the build context that is absolute.
|
|
|
+//
|
|
|
+// The return value will be relative if the dockerfile exists within the build context, absolute
|
|
|
+// otherwise. The second return value is true if the dockerfile exists within the build context,
|
|
|
+// false otherwise.
|
|
|
+func ResolveDockerPaths(
|
|
|
+ basePath string,
|
|
|
+ buildContextPath string,
|
|
|
+ dockerfilePath string,
|
|
|
+) (
|
|
|
+ resBuildCtxPath string,
|
|
|
+ resDockerfilePath string,
|
|
|
+ isDockerfileRelative bool,
|
|
|
+ err error,
|
|
|
+) {
|
|
|
+ resBuildCtxPath, err = filepath.Abs(buildContextPath)
|
|
|
+ resDockerfilePath = dockerfilePath
|
|
|
+
|
|
|
+ // determine if the given dockerfile path is relative
|
|
|
+ if !filepath.IsAbs(dockerfilePath) {
|
|
|
+ // if path is relative, join basepath with path
|
|
|
+ resDockerfilePath = filepath.Join(basePath, dockerfilePath)
|
|
|
+ }
|
|
|
+
|
|
|
+ // compare the path to the dockerfile with the build context
|
|
|
+ pathComp, err := filepath.Rel(resBuildCtxPath, resDockerfilePath)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ return "", "", false, err
|
|
|
+ }
|
|
|
+
|
|
|
+ if !strings.HasPrefix(pathComp, ".."+string(os.PathSeparator)) {
|
|
|
+ // return the relative path to the dockerfile
|
|
|
+ return resBuildCtxPath, pathComp, true, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ resDockerfilePath, err = filepath.Abs(resDockerfilePath)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ return "", "", false, err
|
|
|
+ }
|
|
|
+
|
|
|
+ return resBuildCtxPath, resDockerfilePath, false, nil
|
|
|
+}
|