| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- package deploy
- import (
- "fmt"
- "os"
- "path/filepath"
- "strings"
- api "github.com/porter-dev/porter/api/client"
- "github.com/porter-dev/porter/api/types"
- "github.com/porter-dev/porter/cli/cmd/docker"
- "github.com/porter-dev/porter/cli/cmd/pack"
- )
- // BuildAgent builds a new Docker container image for a new version of an application
- type BuildAgent struct {
- *SharedOpts
- APIClient *api.Client
- ImageRepo string
- Env map[string]string
- ImageExists bool
- }
- // BuildDocker uses the local Docker daemon to build the image
- func (b *BuildAgent) BuildDocker(
- dockerAgent *docker.Agent,
- basePath,
- buildCtx,
- dockerfilePath,
- tag string,
- currentTag string,
- ) error {
- buildCtx, dockerfilePath, isDockerfileInCtx, err := ResolveDockerPaths(
- basePath,
- buildCtx,
- dockerfilePath,
- )
- if err != nil {
- return err
- }
- opts := &docker.BuildOpts{
- ImageRepo: b.ImageRepo,
- Tag: tag,
- CurrentTag: currentTag,
- BuildContext: buildCtx,
- Env: b.Env,
- DockerfilePath: dockerfilePath,
- IsDockerfileInCtx: isDockerfileInCtx,
- UseCache: b.UseCache,
- }
- return dockerAgent.BuildLocal(
- opts,
- )
- }
- // BuildPack uses the cloud-native buildpack client to build a container image
- func (b *BuildAgent) BuildPack(dockerAgent *docker.Agent, dst, tag, prevTag string, buildConfig *types.BuildConfig) error {
- // retag the image with "pack-cache" tag so that it doesn't re-pull from the registry
- if b.ImageExists {
- err := dockerAgent.TagImage(
- fmt.Sprintf("%s:%s", b.ImageRepo, prevTag),
- fmt.Sprintf("%s:%s", b.ImageRepo, "pack-cache"),
- )
- if err != nil {
- return err
- }
- }
- // create pack agent and build opts
- packAgent := &pack.Agent{}
- opts := &docker.BuildOpts{
- ImageRepo: b.ImageRepo,
- Tag: tag,
- BuildContext: dst,
- Env: b.Env,
- UseCache: b.UseCache,
- }
- // call builder
- return packAgent.Build(opts, buildConfig, fmt.Sprintf("%s:%s", b.ImageRepo, "pack-cache"))
- }
- // 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
- }
|