Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion pkg/skaffold/build/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"path/filepath"
"sync"

v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/mitchellh/go-homedir"

"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/build"
Expand Down Expand Up @@ -61,7 +62,7 @@ type cache struct {
}

// DependencyLister fetches a list of dependencies for an artifact
type DependencyLister func(ctx context.Context, artifact *latest.Artifact, tag string) ([]string, error)
type DependencyLister func(ctx context.Context, artifact *latest.Artifact, tag string, platform v1.Platform) ([]string, error)

type Config interface {
docker.Config
Expand Down
13 changes: 12 additions & 1 deletion pkg/skaffold/build/cache/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import (
"os"
"sort"

v1 "github.com/google/go-containerregistry/pkg/v1"

"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/build/buildpacks"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/build/kaniko"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/config"
Expand Down Expand Up @@ -112,8 +114,17 @@ func singleArtifactHash(ctx context.Context, out io.Writer, depLister Dependency
}
inputs = append(inputs, config)

// Extract platform for dependency resolution
// For single-platform builds, use that platform
// For multi-platform builds, use the first platform (dependencies are typically platform-independent)
// For no platform specified, use empty platform (default behavior)
var pl v1.Platform
if len(m.Platforms) > 0 {
pl = util.ConvertToV1Platform(m.Platforms[0])
}

// Append the digest of each input file
deps, err := depLister(ctx, a, tag)
deps, err := depLister(ctx, a, tag, pl)
if err != nil {
return "", fmt.Errorf("getting dependencies for %q: %w", a.ImageName, err)
}
Expand Down
6 changes: 4 additions & 2 deletions pkg/skaffold/build/cache/hash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
"os"
"testing"

v1 "github.com/google/go-containerregistry/pkg/v1"

"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/config"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/graph"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/platform"
Expand All @@ -31,7 +33,7 @@ import (
)

func stubDependencyLister(dependencies []string) DependencyLister {
return func(context.Context, *latest.Artifact, string) ([]string, error) {
return func(context.Context, *latest.Artifact, string, v1.Platform) ([]string, error) {
return dependencies, nil
}
}
Expand Down Expand Up @@ -244,7 +246,7 @@ func TestGetHashForArtifactWithDependencies(t *testing.T) {
}
}

depLister := func(_ context.Context, a *latest.Artifact, tag string) ([]string, error) {
depLister := func(_ context.Context, a *latest.Artifact, tag string, _ v1.Platform) ([]string, error) {
return test.fileDeps[a.ImageName], nil
}

Expand Down
5 changes: 3 additions & 2 deletions pkg/skaffold/build/cache/retrieve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"testing"

"github.com/docker/docker/api/types/registry"
gcrv1 "github.com/google/go-containerregistry/pkg/v1"
specs "github.com/opencontainers/image-spec/specs-go/v1"

"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/build"
Expand All @@ -37,7 +38,7 @@ import (
)

func depLister(files map[string][]string) DependencyLister {
return func(_ context.Context, artifact *latest.Artifact, tag string) ([]string, error) {
return func(_ context.Context, artifact *latest.Artifact, tag string, _ gcrv1.Platform) ([]string, error) {
list, found := files[artifact.ImageName]
if !found {
return nil, errors.New("unknown artifact")
Expand Down Expand Up @@ -69,7 +70,7 @@ func (b *mockBuilder) Build(ctx context.Context, out io.Writer, tags tag.ImageTa
b.built = append(b.built, artifact)
tag := tags[artifact.ImageName]
opts := docker.BuildOptions{Tag: tag, Mode: config.RunModes.Dev}
_, err := b.dockerDaemon.Build(ctx, out, artifact.Workspace, artifact.ImageName, artifact.DockerArtifact, opts)
_, err := b.dockerDaemon.Build(ctx, out, artifact.Workspace, artifact.ImageName, artifact.DockerArtifact, opts, gcrv1.Platform{})
if err != nil {
return nil, err
}
Expand Down
4 changes: 3 additions & 1 deletion pkg/skaffold/build/cluster/kaniko.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (

"github.com/docker/docker/pkg/progress"
"github.com/docker/docker/pkg/streamformatter"
gcrv1 "github.com/google/go-containerregistry/pkg/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
Expand Down Expand Up @@ -157,8 +158,9 @@ func (b *Builder) copyKanikoBuildContext(ctx context.Context, out io.Writer, wor
}
}()

// Use empty platform for Kaniko as it is no longer officially maintained
err := docker.CreateDockerTarContext(ctx, gzipWriter, docker.NewBuildConfig(
kaniko.GetContext(artifact, workspace), artifactName, artifact.DockerfilePath, artifact.BuildArgs), b.cfg)
kaniko.GetContext(artifact, workspace), artifactName, artifact.DockerfilePath, artifact.BuildArgs), b.cfg, gcrv1.Platform{})
if err != nil {
closeErr := buildCtxWriter.CloseWithError(fmt.Errorf("creating docker context: %w", err))
if closeErr != nil {
Expand Down
6 changes: 4 additions & 2 deletions pkg/skaffold/build/custom/dependencies.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,19 @@ import (
"os/exec"
"strings"

v1 "github.com/google/go-containerregistry/pkg/v1"

"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/build/list"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/docker"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/schema/latest"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/util"
)

// GetDependencies returns dependencies listed for a custom artifact
func GetDependencies(ctx context.Context, workspace string, artifactName string, a *latest.CustomArtifact, cfg docker.Config) ([]string, error) {
func GetDependencies(ctx context.Context, workspace string, artifactName string, a *latest.CustomArtifact, cfg docker.Config, platform v1.Platform) ([]string, error) {
switch {
case a.Dependencies.Dockerfile != nil:
return docker.GetDependencies(ctx, getDockerBuildConfig(workspace, artifactName, a), cfg)
return docker.GetDependencies(ctx, getDockerBuildConfig(workspace, artifactName, a), cfg, platform)

case a.Dependencies.Command != "":
split := strings.Split(a.Dependencies.Command, " ")
Expand Down
8 changes: 5 additions & 3 deletions pkg/skaffold/build/custom/dependencies_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"path/filepath"
"testing"

v1 "github.com/google/go-containerregistry/pkg/v1"

"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/schema/latest"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/util"
"github.com/GoogleContainerTools/skaffold/v2/testutil"
Expand Down Expand Up @@ -50,7 +52,7 @@ func TestGetDependenciesDockerfile(t *testing.T) {
}

expected := []string{"Dockerfile", filepath.FromSlash("baz/file"), "foo"}
deps, err := GetDependencies(context.Background(), tmpDir.Root(), "test", customArtifact, nil)
deps, err := GetDependencies(context.Background(), tmpDir.Root(), "test", customArtifact, nil, v1.Platform{})

testutil.CheckErrorAndDeepEqual(t, false, err, expected, deps)
}
Expand All @@ -72,7 +74,7 @@ func TestGetDependenciesCommand(t *testing.T) {
}

expected := []string{"file1", "file2", "file3"}
deps, err := GetDependencies(context.Background(), workspace, "test", customArtifact, nil)
deps, err := GetDependencies(context.Background(), workspace, "test", customArtifact, nil, v1.Platform{})

t.CheckNoError(err)
t.CheckDeepEqual(expected, deps)
Expand Down Expand Up @@ -127,7 +129,7 @@ func TestGetDependenciesPaths(t *testing.T) {
Paths: test.paths,
Ignore: test.ignore,
},
}, nil)
}, nil, v1.Platform{})

t.CheckErrorAndDeepEqual(test.shouldErr, err, test.expected, deps)
})
Expand Down
2 changes: 1 addition & 1 deletion pkg/skaffold/build/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (b *Builder) Build(ctx context.Context, out io.Writer, a *latest.Artifact,
if b.useCLI || (b.useBuildKit != nil && *b.useBuildKit) || len(a.DockerArtifact.CliFlags) > 0 || matcher.IsCrossPlatform() {
imageID, err = b.dockerCLIBuild(ctx, output.GetUnderlyingWriter(out), a.ImageName, a.Workspace, dockerfile, a.ArtifactType.DockerArtifact, opts, pl)
} else {
imageID, err = b.localDocker.Build(ctx, out, a.Workspace, a.ImageName, a.ArtifactType.DockerArtifact, opts)
imageID, err = b.localDocker.Build(ctx, out, a.Workspace, a.ImageName, a.ArtifactType.DockerArtifact, opts, pl)
}

if err != nil {
Expand Down
12 changes: 11 additions & 1 deletion pkg/skaffold/build/gcb/cloud_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"time"

cstorage "cloud.google.com/go/storage"
gcrv1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/uuid"
"google.golang.org/api/cloudbuild/v1"
"google.golang.org/api/googleapi"
Expand Down Expand Up @@ -127,7 +128,16 @@ func (b *Builder) buildArtifactWithCloudBuild(ctx context.Context, out io.Writer
})
}

dependencies, err := b.sourceDependencies.SingleArtifactDependencies(ctx, artifact, tag)
// Extract platform for dependency resolution
// For single-platform builds, use that platform
// For multi-platform builds, use the first platform (dependencies are typically platform-independent)
// For no platform specified, use empty platform (default behavior)
var pl gcrv1.Platform
if len(platform.Platforms) > 0 {
pl = util.ConvertToV1Platform(platform.Platforms[0])
}

dependencies, err := b.sourceDependencies.SingleArtifactDependencies(ctx, artifact, tag, pl)
if err != nil {
return "", sErrors.NewErrorWithStatusCode(&proto.ActionableErr{
ErrCode: proto.StatusCode_BUILD_GCB_GET_DEPENDENCY_ERR,
Expand Down
5 changes: 4 additions & 1 deletion pkg/skaffold/debug/apply_transforms.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"fmt"
"strings"

v1 "github.com/google/go-containerregistry/pkg/v1"

"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/debug/types"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/docker"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/graph"
Expand Down Expand Up @@ -63,7 +65,8 @@ func RetrieveImageConfiguration(ctx context.Context, artifact *graph.Artifact, i
}

// the apiClient will go to the remote registry if local docker daemon is not available
manifest, err := apiClient.ConfigFile(ctx, artifact.Tag)
// Use empty platform as we're inspecting an already-built image
manifest, err := apiClient.ConfigFile(ctx, artifact.Tag, v1.Platform{})
if err != nil {
log.Entry(ctx).Debugf("Error retrieving image manifest for %v: %v", artifact.Tag, err)
return ImageConfiguration{}, fmt.Errorf("retrieving image config for %q: %w", artifact.Tag, err)
Expand Down
7 changes: 5 additions & 2 deletions pkg/skaffold/diagnose/diagnose.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
"io"
"time"

v1 "github.com/google/go-containerregistry/pkg/v1"

"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/build"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/docker"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/filemon"
Expand Down Expand Up @@ -129,7 +131,7 @@ func timeToListDependencies(ctx context.Context, a *latest.Artifact, tag string,
start := time.Now()
g := graph.ToArtifactGraph(cfg.Artifacts())
sourceDependencies := graph.NewSourceDependenciesCache(cfg, nil, g)
paths, err := sourceDependencies.SingleArtifactDependencies(ctx, a, tag)
paths, err := sourceDependencies.SingleArtifactDependencies(ctx, a, tag, v1.Platform{})
return timeutil.Humanize(time.Since(start)), paths, err
}

Expand All @@ -151,8 +153,9 @@ func timeToComputeMTimes(deps []string) (string, error) {
func sizeOfDockerContext(ctx context.Context, a *latest.Artifact, cfg docker.Config) (int64, error) {
buildCtx, buildCtxWriter := io.Pipe()
go func() {
// Use empty platform for diagnostics as platform info is not available in this context
err := docker.CreateDockerTarContext(ctx, buildCtxWriter, docker.NewBuildConfig(
a.Workspace, a.ImageName, a.DockerArtifact.DockerfilePath, nil), cfg)
a.Workspace, a.ImageName, a.DockerArtifact.DockerfilePath, nil), cfg, v1.Platform{})
if err != nil {
buildCtxWriter.CloseWithError(fmt.Errorf("creating docker context: %w", err))
return
Expand Down
6 changes: 4 additions & 2 deletions pkg/skaffold/docker/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ import (
"io"
"path/filepath"

v1 "github.com/google/go-containerregistry/pkg/v1"

"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/util"
)

func CreateDockerTarContext(ctx context.Context, w io.Writer, buildCfg BuildConfig, cfg Config) error {
paths, err := GetDependenciesCached(ctx, buildCfg, cfg)
func CreateDockerTarContext(ctx context.Context, w io.Writer, buildCfg BuildConfig, cfg Config, platform v1.Platform) error {
paths, err := GetDependenciesCached(ctx, buildCfg, cfg, platform)
if err != nil {
return fmt.Errorf("getting relative tar paths: %w", err)
}
Expand Down
4 changes: 3 additions & 1 deletion pkg/skaffold/docker/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
"io"
"testing"

v1 "github.com/google/go-containerregistry/pkg/v1"

"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/schema/latest"
"github.com/GoogleContainerTools/skaffold/v2/testutil"
)
Expand All @@ -46,7 +48,7 @@ func TestDockerContext(t *testing.T) {

reader, writer := io.Pipe()
go func() {
err := CreateDockerTarContext(context.Background(), writer, NewBuildConfig(dir, "test", artifact.DockerfilePath, artifact.BuildArgs), nil)
err := CreateDockerTarContext(context.Background(), writer, NewBuildConfig(dir, "test", artifact.DockerfilePath, artifact.BuildArgs), nil, v1.Platform{})
if err != nil {
writer.CloseWithError(err)
} else {
Expand Down
21 changes: 11 additions & 10 deletions pkg/skaffold/docker/dependencies.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"runtime"
"sort"

v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/moby/buildkit/frontend/dockerfile/dockerignore"

"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/constants"
Expand Down Expand Up @@ -73,38 +74,38 @@ func NormalizeDockerfilePath(context, dockerfile string) (string, error) {
// GetDependencies finds the sources dependency for the given docker artifact.
// it caches the results for the computed dependency which can be used by `GetDependenciesCached`
// All paths are relative to the workspace.
func GetDependencies(ctx context.Context, buildCfg BuildConfig, cfg Config) ([]string, error) {
func GetDependencies(ctx context.Context, buildCfg BuildConfig, cfg Config, platform v1.Platform) ([]string, error) {
absDockerfilePath, err := NormalizeDockerfilePath(buildCfg.workspace, buildCfg.dockerfilePath)
if err != nil {
return nil, fmt.Errorf("normalizing dockerfilePath path: %w", err)
}
result, err := getDependencies(ctx, buildCfg.workspace, buildCfg.dockerfilePath, absDockerfilePath, buildCfg.args, cfg)
result, err := getDependencies(ctx, buildCfg.workspace, buildCfg.dockerfilePath, absDockerfilePath, buildCfg.args, cfg, platform)
dependencyCache.Store(buildCfg.artifact, result, err)
return result, err
}

// GetDependencies finds the sources dependency for the given docker artifact.
// it caches the results for the computed dependency which can be used by `GetDependenciesCached`
// All paths are relative to the workspace.
func GetDependenciesByDockerCopyFromTo(ctx context.Context, buildCfg BuildConfig, cfg Config) (map[string][]string, error) {
func GetDependenciesByDockerCopyFromTo(ctx context.Context, buildCfg BuildConfig, cfg Config, platform v1.Platform) (map[string][]string, error) {
absDockerfilePath, err := NormalizeDockerfilePath(buildCfg.workspace, buildCfg.dockerfilePath)
if err != nil {
return nil, fmt.Errorf("normalizing dockerfilePath path: %w", err)
}
ftToDependencies := getDependenciesByDockerCopyFromTo(ctx, buildCfg.workspace, buildCfg.dockerfilePath, absDockerfilePath, buildCfg.args, cfg)
ftToDependencies := getDependenciesByDockerCopyFromTo(ctx, buildCfg.workspace, buildCfg.dockerfilePath, absDockerfilePath, buildCfg.args, cfg, platform)
return resultPairForDockerCopyFromTo(ftToDependencies)
}

// GetDependenciesCached reads from cache finds the sources dependency for the given docker artifact.
// All paths are relative to the workspace.
func GetDependenciesCached(ctx context.Context, buildCfg BuildConfig, cfg Config) ([]string, error) {
func GetDependenciesCached(ctx context.Context, buildCfg BuildConfig, cfg Config, platform v1.Platform) ([]string, error) {
absDockerfilePath, err := NormalizeDockerfilePath(buildCfg.workspace, buildCfg.dockerfilePath)
if err != nil {
return nil, fmt.Errorf("normalizing dockerfilePath path: %w", err)
}

return dependencyCache.Exec(buildCfg.artifact, func() ([]string, error) {
return getDependencies(ctx, buildCfg.workspace, buildCfg.dockerfilePath, absDockerfilePath, buildCfg.args, cfg)
return getDependencies(ctx, buildCfg.workspace, buildCfg.dockerfilePath, absDockerfilePath, buildCfg.args, cfg, platform)
})
}

Expand All @@ -119,7 +120,7 @@ func resultPairForDockerCopyFromTo(deps interface{}) (map[string][]string, error
}
}

func getDependencies(ctx context.Context, workspace string, dockerfilePath string, absDockerfilePath string, buildArgs map[string]*string, cfg Config) ([]string, error) {
func getDependencies(ctx context.Context, workspace string, dockerfilePath string, absDockerfilePath string, buildArgs map[string]*string, cfg Config, platform v1.Platform) ([]string, error) {
// If the Dockerfile doesn't exist, we can't compute the dependency.
// But since we know the Dockerfile is a dependency, let's return a list
// with only that file. It makes errors down the line more actionable
Expand All @@ -128,7 +129,7 @@ func getDependencies(ctx context.Context, workspace string, dockerfilePath strin
return []string{dockerfilePath}, nil
}

fts, err := ReadCopyCmdsFromDockerfile(ctx, false, absDockerfilePath, workspace, buildArgs, cfg)
fts, err := ReadCopyCmdsFromDockerfile(ctx, false, absDockerfilePath, workspace, buildArgs, cfg, platform)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -167,7 +168,7 @@ func getDependencies(ctx context.Context, workspace string, dockerfilePath strin
return dependencies, nil
}

func getDependenciesByDockerCopyFromTo(ctx context.Context, workspace string, dockerfilePath string, absDockerfilePath string, buildArgs map[string]*string, cfg Config) interface{} {
func getDependenciesByDockerCopyFromTo(ctx context.Context, workspace string, dockerfilePath string, absDockerfilePath string, buildArgs map[string]*string, cfg Config, platform v1.Platform) interface{} {
// If the Dockerfile doesn't exist, we can't compute the dependency.
// But since we know the Dockerfile is a dependency, let's return a list
// with only that file. It makes errors down the line more actionable
Expand All @@ -176,7 +177,7 @@ func getDependenciesByDockerCopyFromTo(ctx context.Context, workspace string, do
return []string{dockerfilePath}
}

fts, err := ReadCopyCmdsFromDockerfile(ctx, false, absDockerfilePath, workspace, buildArgs, cfg)
fts, err := ReadCopyCmdsFromDockerfile(ctx, false, absDockerfilePath, workspace, buildArgs, cfg, platform)
if err != nil {
return err
}
Expand Down
Loading