diff --git a/pkg/skaffold/build/cache/cache.go b/pkg/skaffold/build/cache/cache.go index ca32e87ccbc..d16691cd2fd 100644 --- a/pkg/skaffold/build/cache/cache.go +++ b/pkg/skaffold/build/cache/cache.go @@ -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" @@ -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 diff --git a/pkg/skaffold/build/cache/hash.go b/pkg/skaffold/build/cache/hash.go index e103fdd2463..2f5be235826 100644 --- a/pkg/skaffold/build/cache/hash.go +++ b/pkg/skaffold/build/cache/hash.go @@ -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" @@ -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) } diff --git a/pkg/skaffold/build/cache/hash_test.go b/pkg/skaffold/build/cache/hash_test.go index 75c3b6ad654..b31352137ca 100644 --- a/pkg/skaffold/build/cache/hash_test.go +++ b/pkg/skaffold/build/cache/hash_test.go @@ -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" @@ -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 } } @@ -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 } diff --git a/pkg/skaffold/build/cache/retrieve_test.go b/pkg/skaffold/build/cache/retrieve_test.go index 7abbf80b97c..a2b1a2f5cd8 100644 --- a/pkg/skaffold/build/cache/retrieve_test.go +++ b/pkg/skaffold/build/cache/retrieve_test.go @@ -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" @@ -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") @@ -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 } diff --git a/pkg/skaffold/build/cluster/kaniko.go b/pkg/skaffold/build/cluster/kaniko.go index 95c583dd845..afe2f441156 100644 --- a/pkg/skaffold/build/cluster/kaniko.go +++ b/pkg/skaffold/build/cluster/kaniko.go @@ -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" @@ -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 { diff --git a/pkg/skaffold/build/custom/dependencies.go b/pkg/skaffold/build/custom/dependencies.go index 68276bc989a..0db225bd95b 100644 --- a/pkg/skaffold/build/custom/dependencies.go +++ b/pkg/skaffold/build/custom/dependencies.go @@ -23,6 +23,8 @@ 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" @@ -30,10 +32,10 @@ import ( ) // 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, " ") diff --git a/pkg/skaffold/build/custom/dependencies_test.go b/pkg/skaffold/build/custom/dependencies_test.go index 3c9a28d7d25..b1adf15f725 100644 --- a/pkg/skaffold/build/custom/dependencies_test.go +++ b/pkg/skaffold/build/custom/dependencies_test.go @@ -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" @@ -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) } @@ -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) @@ -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) }) diff --git a/pkg/skaffold/build/docker/docker.go b/pkg/skaffold/build/docker/docker.go index 9e9f826435d..172509aa7b9 100644 --- a/pkg/skaffold/build/docker/docker.go +++ b/pkg/skaffold/build/docker/docker.go @@ -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 { diff --git a/pkg/skaffold/build/gcb/cloud_build.go b/pkg/skaffold/build/gcb/cloud_build.go index 1431fbe8d7c..c86d3851355 100644 --- a/pkg/skaffold/build/gcb/cloud_build.go +++ b/pkg/skaffold/build/gcb/cloud_build.go @@ -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" @@ -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, diff --git a/pkg/skaffold/debug/apply_transforms.go b/pkg/skaffold/debug/apply_transforms.go index 312874e4383..8baded15e96 100644 --- a/pkg/skaffold/debug/apply_transforms.go +++ b/pkg/skaffold/debug/apply_transforms.go @@ -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" @@ -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) diff --git a/pkg/skaffold/diagnose/diagnose.go b/pkg/skaffold/diagnose/diagnose.go index dcab9463f1e..5800498e9f6 100644 --- a/pkg/skaffold/diagnose/diagnose.go +++ b/pkg/skaffold/diagnose/diagnose.go @@ -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" @@ -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 } @@ -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 diff --git a/pkg/skaffold/docker/context.go b/pkg/skaffold/docker/context.go index e683332606c..101b7bb7099 100644 --- a/pkg/skaffold/docker/context.go +++ b/pkg/skaffold/docker/context.go @@ -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) } diff --git a/pkg/skaffold/docker/context_test.go b/pkg/skaffold/docker/context_test.go index b6d603a8c71..e118fd84047 100644 --- a/pkg/skaffold/docker/context_test.go +++ b/pkg/skaffold/docker/context_test.go @@ -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" ) @@ -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 { diff --git a/pkg/skaffold/docker/dependencies.go b/pkg/skaffold/docker/dependencies.go index d378a73e8d1..7f7b8386d03 100644 --- a/pkg/skaffold/docker/dependencies.go +++ b/pkg/skaffold/docker/dependencies.go @@ -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" @@ -73,12 +74,12 @@ 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 } @@ -86,25 +87,25 @@ func GetDependencies(ctx context.Context, buildCfg BuildConfig, cfg Config) ([]s // 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) }) } @@ -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 @@ -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 } @@ -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 @@ -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 } diff --git a/pkg/skaffold/docker/dependencies_test.go b/pkg/skaffold/docker/dependencies_test.go index 939adbdfc62..f1d1b8936e6 100644 --- a/pkg/skaffold/docker/dependencies_test.go +++ b/pkg/skaffold/docker/dependencies_test.go @@ -612,7 +612,7 @@ func TestGetDependencies(t *testing.T) { m := mockConfig{ mode: config.RunModes.Dev, } - deps, err := GetDependencies(context.Background(), NewBuildConfig(workspace, "test", "Dockerfile", test.buildArgs), m) + deps, err := GetDependencies(context.Background(), NewBuildConfig(workspace, "test", "Dockerfile", test.buildArgs), m, v1.Platform{}) t.CheckError(test.shouldErr, err) t.CheckDeepEqual(test.expected, deps) }) @@ -692,7 +692,7 @@ func TestGetDependenciesCached(t *testing.T) { imageFetcher := fakeImageFetcher{} tests := []struct { description string - retrieveImgMock func(context.Context, string, Config) (*v1.ConfigFile, error) + retrieveImgMock func(context.Context, string, Config, v1.Platform) (*v1.ConfigFile, error) dependencyCache map[string][]string dependencyCacheErr map[string]error expected []string @@ -706,7 +706,7 @@ func TestGetDependenciesCached(t *testing.T) { }, { description: "with cached results getDependencies should read from cache", - retrieveImgMock: func(context.Context, string, Config) (*v1.ConfigFile, error) { + retrieveImgMock: func(context.Context, string, Config, v1.Platform) (*v1.ConfigFile, error) { return nil, fmt.Errorf("unexpected call") }, dependencyCache: map[string][]string{"dummy": {"random.go"}}, @@ -714,7 +714,7 @@ func TestGetDependenciesCached(t *testing.T) { }, { description: "with cached results is error getDependencies should read from cache", - retrieveImgMock: func(context.Context, string, Config) (*v1.ConfigFile, error) { + retrieveImgMock: func(context.Context, string, Config, v1.Platform) (*v1.ConfigFile, error) { return &v1.ConfigFile{}, nil }, dependencyCacheErr: map[string]error{"dummy": fmt.Errorf("remote manifest fetch")}, @@ -747,7 +747,7 @@ func TestGetDependenciesCached(t *testing.T) { return nil, v }) } - deps, err := GetDependenciesCached(context.Background(), NewBuildConfig(tmpDir.Root(), "dummy", "Dockerfile", map[string]*string{}), nil) + deps, err := GetDependenciesCached(context.Background(), NewBuildConfig(tmpDir.Root(), "dummy", "Dockerfile", map[string]*string{}), nil, v1.Platform{}) t.CheckErrorAndDeepEqual(test.shouldErr, err, test.expected, deps) }) } diff --git a/pkg/skaffold/docker/dockertest.go b/pkg/skaffold/docker/dockertest.go index 833c51b713b..196f5d2fd07 100644 --- a/pkg/skaffold/docker/dockertest.go +++ b/pkg/skaffold/docker/dockertest.go @@ -94,7 +94,7 @@ func NewConfigStub(mode config.RunMode, prune bool) Config { type fakeImageFetcher struct{} -func (f *fakeImageFetcher) fetch(_ context.Context, image string, _ Config) (*v1.ConfigFile, error) { +func (f *fakeImageFetcher) fetch(_ context.Context, image string, _ Config, _ v1.Platform) (*v1.ConfigFile, error) { switch image { case "ubuntu:14.04", "busybox", "nginx", "golang:1.9.2", "jboss/wildfly:14.0.1.Final", "gcr.io/distroless/base", "gcr.io/distroless/base:latest": return &v1.ConfigFile{}, nil @@ -113,7 +113,7 @@ func (f *fakeImageFetcher) fetch(_ context.Context, image string, _ Config) (*v1 return nil, fmt.Errorf("no image found for %s", image) } -type FetchImage func(context.Context, string, Config) (*v1.ConfigFile, error) +type FetchImage func(context.Context, string, Config, v1.Platform) (*v1.ConfigFile, error) func NewFakeImageFetcher() FetchImage { fetcher := fakeImageFetcher{} diff --git a/pkg/skaffold/docker/image.go b/pkg/skaffold/docker/image.go index 3bd7f51eb60..a1e21526d1c 100644 --- a/pkg/skaffold/docker/image.go +++ b/pkg/skaffold/docker/image.go @@ -83,8 +83,8 @@ type LocalDaemon interface { Close() error ExtraEnv() []string ServerVersion(ctx context.Context) (types.Version, error) - ConfigFile(ctx context.Context, image string) (*v1.ConfigFile, error) - Build(ctx context.Context, out io.Writer, workspace string, artifact string, a *latest.DockerArtifact, opts BuildOptions) (string, error) + ConfigFile(ctx context.Context, image string, platform v1.Platform) (*v1.ConfigFile, error) + Build(ctx context.Context, out io.Writer, workspace string, artifact string, a *latest.DockerArtifact, opts BuildOptions, platform v1.Platform) (string, error) ContainerLogs(ctx context.Context, w *io.PipeWriter, id string) error ContainerExists(ctx context.Context, name string) bool ContainerInspect(ctx context.Context, id string) (types.ContainerJSON, error) @@ -281,7 +281,7 @@ func (l *localDaemon) ServerVersion(ctx context.Context) (types.Version, error) } // ConfigFile retrieves and caches image configurations. -func (l *localDaemon) ConfigFile(ctx context.Context, image string) (*v1.ConfigFile, error) { +func (l *localDaemon) ConfigFile(ctx context.Context, image string, platform v1.Platform) (*v1.ConfigFile, error) { l.imageCacheLock.Lock() defer l.imageCacheLock.Unlock() @@ -298,7 +298,7 @@ func (l *localDaemon) ConfigFile(ctx context.Context, image string) (*v1.ConfigF return nil, err } } else { - cfg, err = RetrieveRemoteConfig(image, l.cfg, v1.Platform{}) + cfg, err = RetrieveRemoteConfig(image, l.cfg, platform) if err != nil { return nil, err } @@ -317,7 +317,7 @@ func (l *localDaemon) CheckCompatible(a *latest.DockerArtifact) error { } // Build performs a docker build and returns the imageID. -func (l *localDaemon) Build(ctx context.Context, out io.Writer, workspace string, artifact string, a *latest.DockerArtifact, opts BuildOptions) (string, error) { +func (l *localDaemon) Build(ctx context.Context, out io.Writer, workspace string, artifact string, a *latest.DockerArtifact, opts BuildOptions, platform v1.Platform) (string, error) { log.Entry(ctx).Debugf("Running docker build: context: %s, dockerfile: %s", workspace, a.DockerfilePath) if err := l.CheckCompatible(a); err != nil { @@ -339,7 +339,7 @@ func (l *localDaemon) Build(ctx context.Context, out io.Writer, workspace string buildCtx, buildCtxWriter := io.Pipe() go func() { err := CreateDockerTarContext(ctx, buildCtxWriter, - NewBuildConfig(workspace, artifact, a.DockerfilePath, buildArgs), l.cfg) + NewBuildConfig(workspace, artifact, a.DockerfilePath, buildArgs), l.cfg, platform) if err != nil { buildCtxWriter.CloseWithError(fmt.Errorf("creating docker context: %w", err)) return diff --git a/pkg/skaffold/docker/image_test.go b/pkg/skaffold/docker/image_test.go index 322e9fb419d..c8f2ef74902 100644 --- a/pkg/skaffold/docker/image_test.go +++ b/pkg/skaffold/docker/image_test.go @@ -26,6 +26,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/client" + gcrv1 "github.com/google/go-containerregistry/pkg/v1" "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/config" sErrors "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/errors" @@ -203,7 +204,7 @@ func TestBuild(t *testing.T) { localDocker := NewLocalDaemon(test.api, nil, false, nil) opts := BuildOptions{Tag: "finalimage", Mode: test.mode} - _, err := localDocker.Build(context.Background(), io.Discard, test.workspace, "final-image", test.artifact, opts) + _, err := localDocker.Build(context.Background(), io.Discard, test.workspace, "final-image", test.artifact, opts, gcrv1.Platform{}) if test.shouldErr { t.CheckErrorContains(test.expectedError, err) @@ -488,7 +489,7 @@ func TestConfigFile(t *testing.T) { api := (&testutil.FakeAPIClient{}).Add("gcr.io/image", "sha256:imageIDabcab") localDocker := NewLocalDaemon(api, nil, false, nil) - cfg, err := localDocker.ConfigFile(context.Background(), "gcr.io/image") + cfg, err := localDocker.ConfigFile(context.Background(), "gcr.io/image", gcrv1.Platform{}) testutil.CheckErrorAndDeepEqual(t, false, err, "sha256:imageIDabcab", cfg.Config.Image) } @@ -514,7 +515,7 @@ func TestConfigFileConcurrentCalls(t *testing.T) { for i := 0; i < 100; i++ { wg.Add(1) go func() { - localDocker.ConfigFile(context.Background(), "gcr.io/image") + localDocker.ConfigFile(context.Background(), "gcr.io/image", gcrv1.Platform{}) wg.Done() }() } diff --git a/pkg/skaffold/docker/image_util.go b/pkg/skaffold/docker/image_util.go index 801a7f944b6..6bafe57cd0e 100644 --- a/pkg/skaffold/docker/image_util.go +++ b/pkg/skaffold/docker/image_util.go @@ -36,7 +36,8 @@ func RetrieveConfigFile(ctx context.Context, tagged string, cfg Config) (*v1.Con localDocker, err := NewAPIClient(ctx, cfg) if err == nil { - cf, err = localDocker.ConfigFile(context.Background(), tagged) + // Use empty platform as we're retrieving config for an already-tagged image + cf, err = localDocker.ConfigFile(context.Background(), tagged, v1.Platform{}) } if err != nil { // No local Docker is available diff --git a/pkg/skaffold/docker/parse.go b/pkg/skaffold/docker/parse.go index af4229ca1e2..d674a721fd0 100644 --- a/pkg/skaffold/docker/parse.go +++ b/pkg/skaffold/docker/parse.go @@ -83,7 +83,7 @@ var ( // ReadCopyCmdsFromDockerfile parses a given dockerfile for COPY commands accounting for build args, env vars, globs, etc // and returns an array of FromTos specifying the files that will be copied 'from' local dirs 'to' container dirs in the COPY statements -func ReadCopyCmdsFromDockerfile(ctx context.Context, onlyLastImage bool, absDockerfilePath, workspace string, buildArgs map[string]*string, cfg Config) ([]FromTo, error) { +func ReadCopyCmdsFromDockerfile(ctx context.Context, onlyLastImage bool, absDockerfilePath, workspace string, buildArgs map[string]*string, cfg Config, platform v1.Platform) ([]FromTo, error) { r, err := os.ReadFile(absDockerfilePath) if err != nil { return nil, err @@ -104,12 +104,12 @@ func ReadCopyCmdsFromDockerfile(ctx context.Context, onlyLastImage bool, absDock return nil, fmt.Errorf("putting build arguments: %w", err) } - dockerfileLinesWithOnbuild, err := expandOnbuildInstructions(ctx, dockerfileLines, cfg) + dockerfileLinesWithOnbuild, err := expandOnbuildInstructions(ctx, dockerfileLines, cfg, platform) if err != nil { return nil, err } - cpCmds, err := extractCopyCommands(ctx, dockerfileLinesWithOnbuild, onlyLastImage, cfg) + cpCmds, err := extractCopyCommands(ctx, dockerfileLinesWithOnbuild, onlyLastImage, cfg, platform) if err != nil { return nil, fmt.Errorf("listing copied files: %w", err) } @@ -248,7 +248,7 @@ func expandSrcGlobPatterns(workspace string, cpCmds []*copyCommand) ([]FromTo, e return fts, nil } -func extractCopyCommands(ctx context.Context, nodes []*parser.Node, onlyLastImage bool, cfg Config) ([]*copyCommand, error) { +func extractCopyCommands(ctx context.Context, nodes []*parser.Node, onlyLastImage bool, cfg Config, platform v1.Platform) ([]*copyCommand, error) { stages := map[string]bool{ "scratch": true, } @@ -276,7 +276,7 @@ func extractCopyCommands(ctx context.Context, nodes []*parser.Node, onlyLastImag // If `from` references a previous stage, then the `workdir` // was already changed. if !stages[strings.ToLower(from.image)] { - img, err := RetrieveImage(ctx, from.image, cfg) + img, err := RetrieveImage(ctx, from.image, cfg, platform) if err == nil { workdir = img.Config.WorkingDir } else if _, ok, err := isOldImageManifestProblem(cfg, err); !ok { @@ -369,7 +369,7 @@ func readCopyCommand(value *parser.Node, envs []string, workdir string) (*copyCo }, nil } -func expandOnbuildInstructions(ctx context.Context, nodes []*parser.Node, cfg Config) ([]*parser.Node, error) { +func expandOnbuildInstructions(ctx context.Context, nodes []*parser.Node, cfg Config, platform v1.Platform) ([]*parser.Node, error) { onbuildNodesCache := map[string][]*parser.Node{ "scratch": nil, } @@ -390,7 +390,7 @@ func expandOnbuildInstructions(ctx context.Context, nodes []*parser.Node, cfg Co // some build args like artifact dependencies are not available until the first build sequence has completed. // skip check if there are unavailable images onbuildNodes = []*parser.Node{} - } else if ons, err := parseOnbuild(ctx, from.image, cfg); err == nil { + } else if ons, err := parseOnbuild(ctx, from.image, cfg, platform); err == nil { onbuildNodes = ons } else if warnMsg, ok, _ := isOldImageManifestProblem(cfg, err); ok && warnMsg != "" { log.Entry(context.TODO()).Warn(warnMsg) @@ -410,11 +410,11 @@ func expandOnbuildInstructions(ctx context.Context, nodes []*parser.Node, cfg Co return expandedNodes, nil } -func parseOnbuild(ctx context.Context, image string, cfg Config) ([]*parser.Node, error) { +func parseOnbuild(ctx context.Context, image string, cfg Config, platform v1.Platform) ([]*parser.Node, error) { log.Entry(context.TODO()).Tracef("Checking base image %s for ONBUILD triggers.", image) // Image names are case SENSITIVE - img, err := RetrieveImage(ctx, image, cfg) + img, err := RetrieveImage(ctx, image, cfg, platform) if err != nil { return nil, fmt.Errorf("retrieving image %q: %w", image, err) } @@ -459,13 +459,13 @@ func unquote(v string) string { return unquoted } -func retrieveImage(ctx context.Context, image string, cfg Config) (*v1.ConfigFile, error) { +func retrieveImage(ctx context.Context, image string, cfg Config, platform v1.Platform) (*v1.ConfigFile, error) { localDaemon, err := NewAPIClient(ctx, cfg) if err != nil { return nil, fmt.Errorf("getting docker client: %w", err) } - return localDaemon.ConfigFile(context.Background(), image) + return localDaemon.ConfigFile(context.Background(), image, platform) } func hasMultiStageFlag(flags []string) bool { diff --git a/pkg/skaffold/docker/parse_test.go b/pkg/skaffold/docker/parse_test.go index be46cd4e9b1..b5f2c87ced5 100644 --- a/pkg/skaffold/docker/parse_test.go +++ b/pkg/skaffold/docker/parse_test.go @@ -24,6 +24,7 @@ import ( "strings" "testing" + v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/moby/buildkit/frontend/dockerfile/parser" "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/config" @@ -108,7 +109,7 @@ func TestReadCopyCmdsFromDockerfile(t *testing.T) { } cfg := mockConfig{mode: config.RunModes.Build} - actual, err := ReadCopyCmdsFromDockerfile(context.Background(), false, dockerfilePath, tmp.Path("."), make(map[string]*string), cfg) + actual, err := ReadCopyCmdsFromDockerfile(context.Background(), false, dockerfilePath, tmp.Path("."), make(map[string]*string), cfg, v1.Platform{}) t.CheckError(test.shouldFail, err) t.CheckDeepEqual(test.expected, actual) diff --git a/pkg/skaffold/docker/syncmap.go b/pkg/skaffold/docker/syncmap.go index d088acb2f88..a1e7d92526a 100644 --- a/pkg/skaffold/docker/syncmap.go +++ b/pkg/skaffold/docker/syncmap.go @@ -23,6 +23,8 @@ import ( "path" "path/filepath" + v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/util" "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/walk" ) @@ -37,7 +39,8 @@ func SyncMap(ctx context.Context, workspace string, dockerfilePath string, build } // only the COPY/ADD commands from the last image are syncable - fts, err := ReadCopyCmdsFromDockerfile(ctx, true, absDockerfilePath, workspace, buildArgs, cfg) + // Use empty platform as this is for file syncing, not platform-specific image retrieval + fts, err := ReadCopyCmdsFromDockerfile(ctx, true, absDockerfilePath, workspace, buildArgs, cfg, v1.Platform{}) if err != nil { return nil, err } diff --git a/pkg/skaffold/graph/dependencies.go b/pkg/skaffold/graph/dependencies.go index 1854d19f2a8..a70e9fbb5ec 100644 --- a/pkg/skaffold/graph/dependencies.go +++ b/pkg/skaffold/graph/dependencies.go @@ -20,6 +20,8 @@ import ( "context" "fmt" + v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/build/bazel" "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/build/buildpacks" "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/build/custom" @@ -43,7 +45,7 @@ type SourceDependenciesCache interface { TransitiveArtifactDependencies(ctx context.Context, a *latest.Artifact) ([]string, error) // SingleArtifactDependencies returns the source dependencies for only the target artifact. // The result (even if an error) is cached so that the function is evaluated only once for every artifact. The cache is reset before the start of the next devloop. - SingleArtifactDependencies(ctx context.Context, a *latest.Artifact, tag string) ([]string, error) + SingleArtifactDependencies(ctx context.Context, a *latest.Artifact, tag string, platform v1.Platform) ([]string, error) // Reset removes the cached source dependencies for all artifacts Reset() } @@ -70,7 +72,9 @@ func (r *dependencyResolverImpl) TransitiveArtifactDependencies(ctx context.Cont return nil, fmt.Errorf("unable to resolve tag for image: %s", a.ImageName) } - deps, err := r.SingleArtifactDependencies(ctx, a, tag) + // For TransitiveArtifactDependencies, use empty platform as this is a legacy method + // that doesn't have platform context + deps, err := r.SingleArtifactDependencies(ctx, a, tag, v1.Platform{}) if err != nil { endTrace(instrumentation.TraceEndError(err)) return nil, err @@ -86,14 +90,14 @@ func (r *dependencyResolverImpl) TransitiveArtifactDependencies(ctx context.Cont return deps, nil } -func (r *dependencyResolverImpl) SingleArtifactDependencies(ctx context.Context, a *latest.Artifact, tag string) ([]string, error) { +func (r *dependencyResolverImpl) SingleArtifactDependencies(ctx context.Context, a *latest.Artifact, tag string, platform v1.Platform) ([]string, error) { ctx, endTrace := instrumentation.StartTrace(ctx, "SingleArtifactDependencies", map[string]string{ "ArtifactName": instrumentation.PII(a.ImageName), }) defer endTrace() res, err := r.cache.Exec(a.ImageName, func() ([]string, error) { - return getDependenciesFunc(ctx, a, r.cfg, r.artifactResolver, tag) + return getDependenciesFunc(ctx, a, r.cfg, r.artifactResolver, tag, platform) }) if err != nil { endTrace(instrumentation.TraceEndError(err)) @@ -110,7 +114,7 @@ func (r *dependencyResolverImpl) Reset() { } // sourceDependenciesForArtifact returns the build dependencies for the current artifact. -func sourceDependenciesForArtifact(ctx context.Context, a *latest.Artifact, cfg docker.Config, r docker.ArtifactResolver, tag string) ([]string, error) { +func sourceDependenciesForArtifact(ctx context.Context, a *latest.Artifact, cfg docker.Config, r docker.ArtifactResolver, tag string, platform v1.Platform) ([]string, error) { var ( paths []string err error @@ -133,7 +137,7 @@ func sourceDependenciesForArtifact(ctx context.Context, a *latest.Artifact, cfg if evalErr != nil { return nil, fmt.Errorf("unable to evaluate build args: %w", evalErr) } - paths, err = docker.GetDependencies(ctx, docker.NewBuildConfig(a.Workspace, a.ImageName, a.DockerArtifact.DockerfilePath, args), cfg) + paths, err = docker.GetDependencies(ctx, docker.NewBuildConfig(a.Workspace, a.ImageName, a.DockerArtifact.DockerfilePath, args), cfg, platform) case a.KanikoArtifact != nil: deps := docker.ResolveDependencyImages(a.Dependencies, r, false) @@ -141,7 +145,7 @@ func sourceDependenciesForArtifact(ctx context.Context, a *latest.Artifact, cfg if evalErr != nil { return nil, fmt.Errorf("unable to evaluate build args: %w", evalErr) } - paths, err = docker.GetDependencies(ctx, docker.NewBuildConfig(kaniko.GetContext(a.KanikoArtifact, a.Workspace), a.ImageName, a.KanikoArtifact.DockerfilePath, args), cfg) + paths, err = docker.GetDependencies(ctx, docker.NewBuildConfig(kaniko.GetContext(a.KanikoArtifact, a.Workspace), a.ImageName, a.KanikoArtifact.DockerfilePath, args), cfg, platform) case a.BazelArtifact != nil: paths, err = bazel.GetDependencies(ctx, a.Workspace, a.BazelArtifact) @@ -150,7 +154,7 @@ func sourceDependenciesForArtifact(ctx context.Context, a *latest.Artifact, cfg paths, err = jib.GetDependencies(ctx, a.Workspace, a.JibArtifact) case a.CustomArtifact != nil: - paths, err = custom.GetDependencies(ctx, a.Workspace, a.ImageName, a.CustomArtifact, cfg) + paths, err = custom.GetDependencies(ctx, a.Workspace, a.ImageName, a.CustomArtifact, cfg, platform) case a.BuildpackArtifact != nil: paths, err = buildpacks.GetDependencies(ctx, a.Workspace, a.BuildpackArtifact) diff --git a/pkg/skaffold/graph/dependencies_test.go b/pkg/skaffold/graph/dependencies_test.go index 0137f8ff7a1..8d9b5ba89a2 100644 --- a/pkg/skaffold/graph/dependencies_test.go +++ b/pkg/skaffold/graph/dependencies_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/google/go-cmp/cmp/cmpopts" + v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/config" "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/docker" @@ -44,7 +45,7 @@ func TestSourceDependenciesCache(t *testing.T) { "img4": {"file41", "file42"}, } counts := map[string]int{"img1": 0, "img2": 0, "img3": 0, "img4": 0} - t.Override(&getDependenciesFunc, func(_ context.Context, a *latest.Artifact, _ docker.Config, _ docker.ArtifactResolver, _ string) ([]string, error) { + t.Override(&getDependenciesFunc, func(_ context.Context, a *latest.Artifact, _ docker.Config, _ docker.ArtifactResolver, _ string, _ v1.Platform) ([]string, error) { counts[a.ImageName]++ return deps[a.ImageName], nil }) @@ -137,7 +138,7 @@ COPY $IMAGE_TAG.go . } test.artifact.DockerArtifact.BuildArgs = args } - paths, err := sourceDependenciesForArtifact(context.Background(), test.artifact, test.dockerConfig, d, test.tag) + paths, err := sourceDependenciesForArtifact(context.Background(), test.artifact, test.dockerConfig, d, test.tag, v1.Platform{}) t.CheckNoError(err) t.CheckDeepEqual(test.expectedPaths, paths, cmpopts.SortSlices(func(x, y string) bool { return x < y })) diff --git a/pkg/skaffold/lint/dockerfiles.go b/pkg/skaffold/lint/dockerfiles.go index 22956348d1a..d1a5dc9b149 100644 --- a/pkg/skaffold/lint/dockerfiles.go +++ b/pkg/skaffold/lint/dockerfiles.go @@ -20,6 +20,7 @@ import ( "context" "path/filepath" + v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/moby/buildkit/frontend/dockerfile/command" "go.lsp.dev/protocol" @@ -152,7 +153,7 @@ func GetDockerfilesLintResults(ctx context.Context, opts Options, dockerCfg dock // TODO(aaron-prindle) currently this dep map is computed twice; here and in skaffoldyamls.go, make a singleton/share-the-info // TODO(aaron-prindle) currently copy commands are parsed twice; here and in linters.go fromToToDepMap, err := getDockerDependenciesForEachFromTo(context.TODO(), - docker.NewBuildConfig(ws, a.ImageName, fp, map[string]*string{}), nil) + docker.NewBuildConfig(ws, a.ImageName, fp, map[string]*string{}), nil, v1.Platform{}) if err != nil { return nil, err } diff --git a/pkg/skaffold/lint/dockerfiles_test.go b/pkg/skaffold/lint/dockerfiles_test.go index 45c20b72e03..f34ac2bf0c7 100644 --- a/pkg/skaffold/lint/dockerfiles_test.go +++ b/pkg/skaffold/lint/dockerfiles_test.go @@ -25,6 +25,8 @@ import ( "testing" "text/template" + v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/config" "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/docker" "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/parser" @@ -162,7 +164,7 @@ func TestGetDockerfilesLintResults(t *testing.T) { t.Override(&realWorkDir, func() (string, error) { return "", nil }) - t.Override(&getDockerDependenciesForEachFromTo, func(ctx context.Context, buildCfg docker.BuildConfig, cfg docker.Config) (map[string][]string, error) { + t.Override(&getDockerDependenciesForEachFromTo, func(ctx context.Context, buildCfg docker.BuildConfig, cfg docker.Config, _ v1.Platform) (map[string][]string, error) { deps := make([]string, 1001) for i := 0; i < 1001; i++ { deps[i] = fmt.Sprintf(".git/%d", i) @@ -177,7 +179,7 @@ func TestGetDockerfilesLintResults(t *testing.T) { } return m, nil }) - t.Override(&readCopyCmdsFromDockerfile, func(ctx context.Context, onlyLastImage bool, absDockerfilePath, workspace string, buildArgs map[string]*string, cfg docker.Config) ([]docker.FromTo, error) { + t.Override(&readCopyCmdsFromDockerfile, func(ctx context.Context, onlyLastImage bool, absDockerfilePath, workspace string, buildArgs map[string]*string, cfg docker.Config, _ v1.Platform) ([]docker.FromTo, error) { return docker.ExtractOnlyCopyCommands(absDockerfilePath) }) tmpdir := t.TempDir() diff --git a/pkg/skaffold/lint/linters.go b/pkg/skaffold/lint/linters.go index bc371dad9e8..d05db0dc277 100644 --- a/pkg/skaffold/lint/linters.go +++ b/pkg/skaffold/lint/linters.go @@ -23,6 +23,7 @@ import ( "regexp" "text/template" + v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/moby/buildkit/frontend/dockerfile/command" "sigs.k8s.io/kustomize/kyaml/yaml" @@ -37,7 +38,7 @@ type DockerfileCommandLinter struct{} func (*DockerfileCommandLinter) Lint(params InputParams, rules *[]Rule) (*[]Result, error) { results := &[]Result{} - fromTos, err := readCopyCmdsFromDockerfile(context.TODO(), false, params.ConfigFile.AbsPath, params.WorkspacePath, map[string]*string{}, params.DockerConfig) + fromTos, err := readCopyCmdsFromDockerfile(context.TODO(), false, params.ConfigFile.AbsPath, params.WorkspacePath, map[string]*string{}, params.DockerConfig, v1.Platform{}) if err != nil { return nil, err } diff --git a/pkg/skaffold/runner/listen_test.go b/pkg/skaffold/runner/listen_test.go index f2fde4f733d..8929bae6493 100644 --- a/pkg/skaffold/runner/listen_test.go +++ b/pkg/skaffold/runner/listen_test.go @@ -21,6 +21,8 @@ import ( "errors" "testing" + v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/filemon" "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/schema/latest" "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/trigger" @@ -59,7 +61,7 @@ func (f *fakeDepsResolver) TransitiveArtifactDependencies(context.Context, *late return nil, nil } -func (f *fakeDepsResolver) SingleArtifactDependencies(context.Context, *latest.Artifact, string) ([]string, error) { +func (f *fakeDepsResolver) SingleArtifactDependencies(context.Context, *latest.Artifact, string, v1.Platform) ([]string, error) { return nil, nil } diff --git a/pkg/skaffold/runner/new.go b/pkg/skaffold/runner/new.go index f73dd9d8aab..c43e5fc893a 100644 --- a/pkg/skaffold/runner/new.go +++ b/pkg/skaffold/runner/new.go @@ -20,6 +20,8 @@ import ( "context" "fmt" + v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/build" "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/build/cache" "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/deploy" @@ -117,11 +119,11 @@ func NewForConfig(ctx context.Context, runCtx *runcontext.RunContext) (*Skaffold return nil, fmt.Errorf("creating actiosn runner: %w", err) } - depLister := func(ctx context.Context, artifact *latest.Artifact, tag string) ([]string, error) { + depLister := func(ctx context.Context, artifact *latest.Artifact, tag string, platform v1.Platform) ([]string, error) { ctx, endTrace := instrumentation.StartTrace(ctx, "NewForConfig_depLister") defer endTrace() - buildDependencies, err := sourceDependencies.SingleArtifactDependencies(ctx, artifact, tag) + buildDependencies, err := sourceDependencies.SingleArtifactDependencies(ctx, artifact, tag, platform) if err != nil { endTrace(instrumentation.TraceEndError(err)) return nil, err diff --git a/pkg/skaffold/sync/sync_test.go b/pkg/skaffold/sync/sync_test.go index 8a0e4facc9c..32f6a27aa3a 100644 --- a/pkg/skaffold/sync/sync_test.go +++ b/pkg/skaffold/sync/sync_test.go @@ -1075,7 +1075,7 @@ func TestSyncMap(t *testing.T) { type fakeImageFetcher struct{} -func (f *fakeImageFetcher) fetch(context.Context, string, docker.Config) (*registryv1.ConfigFile, error) { +func (f *fakeImageFetcher) fetch(context.Context, string, docker.Config, registryv1.Platform) (*registryv1.ConfigFile, error) { return ®istryv1.ConfigFile{}, nil } diff --git a/pkg/skaffold/tag/custom_template_test.go b/pkg/skaffold/tag/custom_template_test.go index aa84c4a7d31..30c231f995c 100644 --- a/pkg/skaffold/tag/custom_template_test.go +++ b/pkg/skaffold/tag/custom_template_test.go @@ -21,6 +21,8 @@ import ( "testing" "time" + v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/config" "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/runner/runcontext" "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/schema/latest" @@ -35,7 +37,7 @@ func (r *dependencyResolverImpl) TransitiveArtifactDependencies(ctx context.Cont return []string{}, nil } -func (r *dependencyResolverImpl) SingleArtifactDependencies(ctx context.Context, a *latest.Artifact, tag string) ([]string, error) { +func (r *dependencyResolverImpl) SingleArtifactDependencies(ctx context.Context, a *latest.Artifact, tag string, platform v1.Platform) ([]string, error) { return []string{}, nil }