diff --git a/cmd/exec/exec.go b/cmd/exec/exec.go index 6bd5049..c1a5e47 100644 --- a/cmd/exec/exec.go +++ b/cmd/exec/exec.go @@ -52,6 +52,7 @@ type options struct { quiet bool runtime string + platform string namespace string } @@ -160,6 +161,12 @@ func NewCommand(cli cliutil.CLI) *cobra.Command { "", `Runtime address ("/var/run/docker.sock" | "/run/containerd/containerd.sock" | "https://:8433/...)`, ) + flags.StringVar( + &opts.platform, + "platform", + "", + `Platform (e.g., linux/amd64, linux/arm64) of the target container (for some runtimes it's hard to detect it automatically, but the debug sidecar must be of the same platform as the target)`, + ) return cmd } diff --git a/cmd/exec/exec_containerd.go b/cmd/exec/exec_containerd.go index d4355e9..fd762c1 100644 --- a/cmd/exec/exec_containerd.go +++ b/cmd/exec/exec_containerd.go @@ -19,6 +19,7 @@ import ( "github.com/containerd/containerd/containers" "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/oci" + "github.com/containerd/containerd/platforms" "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" @@ -79,7 +80,16 @@ func runDebuggerContainerd(ctx context.Context, cli cliutil.CLI, opts *options) } cli.PrintAux("Pulling debugger image...\n") - image, err := client.ImagePullEx(ctx, opts.image) + image, err := client.ImagePullEx( + ctx, + opts.image, + func() string { + if len(opts.platform) == 0 { + return platforms.Format(platforms.DefaultSpec()) + } + return opts.platform + }(), + ) if err != nil { return errCannotPull(opts.image, err) } diff --git a/cmd/exec/exec_docker.go b/cmd/exec/exec_docker.go index 2482f9e..02fed2e 100644 --- a/cmd/exec/exec_docker.go +++ b/cmd/exec/exec_docker.go @@ -34,7 +34,14 @@ func runDebuggerDocker(ctx context.Context, cli cliutil.CLI, opts *options) erro } cli.PrintAux("Pulling debugger image...\n") - if err := client.ImagePullEx(ctx, opts.image, types.ImagePullOptions{}); err != nil { + if err := client.ImagePullEx(ctx, opts.image, types.ImagePullOptions{ + Platform: func() string { + if len(opts.platform) == 0 { + return target.Platform + } + return opts.platform + }(), + }); err != nil { return errCannotPull(opts.image, err) } diff --git a/cmd/portforward/portforward.go b/cmd/portforward/portforward.go index 261bbc1..52a58b4 100644 --- a/cmd/portforward/portforward.go +++ b/cmd/portforward/portforward.go @@ -149,7 +149,9 @@ func runPortForward(ctx context.Context, cli cliutil.CLI, opts *options) error { // TODO: Pull only if not present locally. cli.PrintAux("Pulling forwarder image...\n") - if err := client.ImagePullEx(ctx, forwarderImage, types.ImagePullOptions{}); err != nil { + if err := client.ImagePullEx(ctx, forwarderImage, types.ImagePullOptions{ + // Platform: ... TODO: Test if an arm64 sidecar can be attached to an amd64 target and vice versa. + }); err != nil { return fmt.Errorf("cannot pull forwarder image %q: %w", forwarderImage, err) } diff --git a/pkg/containerd/client.go b/pkg/containerd/client.go index f6eeab1..98e60bf 100644 --- a/pkg/containerd/client.go +++ b/pkg/containerd/client.go @@ -89,6 +89,7 @@ func (c *Client) ContainerRemoveEx( func (c *Client) ImagePullEx( ctx context.Context, ref string, + platform string, ) (containerd.Image, error) { if !strings.Contains(ref, ":") { ref = ref + ":latest" @@ -102,7 +103,12 @@ func (c *Client) ImagePullEx( close(progressCh) }() - image, err := c.Pull(ctx, ref, containerd.WithPullUnpack) + image, err := c.Pull( + ctx, + ref, + containerd.WithPullUnpack, + containerd.WithPlatform(platform), + ) stopProgress() if err != nil { return image, err