diff --git a/mint b/mint new file mode 100755 index 000000000..7dbf996c0 Binary files /dev/null and b/mint differ diff --git a/pkg/app/master/command/build/cli.go b/pkg/app/master/command/build/cli.go index 88c79bcd3..35202b912 100644 --- a/pkg/app/master/command/build/cli.go +++ b/pkg/app/master/command/build/cli.go @@ -89,6 +89,7 @@ var BuildFlags = (append([]cli.Flag{ //Container Build Options cflag(FlagImageBuildEngine), cflag(FlagImageBuildArch), + command.Cflag(command.FlagPlatform), cflag(FlagBuildFromDockerfile), cflag(FlagDockerfileContext), cflag(FlagTagFat), @@ -866,7 +867,8 @@ var CLI = &cli.Command{ kubeOpts, GetAppNodejsInspectOptions(ctx), imageBuildEngine, - imageBuildArch) + imageBuildArch, + ctx.String(command.FlagPlatform)) return nil }, diff --git a/pkg/app/master/command/build/handler.go b/pkg/app/master/command/build/handler.go index 1b7604ab8..c15c9ad74 100644 --- a/pkg/app/master/command/build/handler.go +++ b/pkg/app/master/command/build/handler.go @@ -158,6 +158,7 @@ func OnCommand( appNodejsInspectOpts config.AppNodejsInspectOptions, imageBuildEngine string, imageBuildArch string, + platform string, ) { printState := true logger := log.WithFields(log.Fields{"app": appName, "cmd": Name}) @@ -284,6 +285,7 @@ func OnCommand( execCmd: execCmd, imageBuildEngine: imageBuildEngine, imageBuildArch: imageBuildArch, + platform: platform, }) vinfo := <-viChan @@ -634,7 +636,8 @@ func OnCommand( gparams.StatePath, client, logger, - cmdReport) + cmdReport, + platform) loadExtraIncludePaths := func() { if (includeLastImageLayers > 0) || diff --git a/pkg/app/master/command/build/image.go b/pkg/app/master/command/build/image.go index 60f7e3906..bce5dbd59 100644 --- a/pkg/app/master/command/build/image.go +++ b/pkg/app/master/command/build/image.go @@ -42,6 +42,7 @@ func inspectFatImage( client *dockerapi.Client, logger *log.Entry, cmdReport *report.SlimCommand, + platform string, ) (*image.Inspector, string, string, string) { crtClient := dockercrtclient.New(client) imageInspector, err := image.NewInspector(crtClient, targetRef) @@ -58,7 +59,7 @@ func inspectFatImage( "message": "trying to pull target image", }) - err := imageInspector.Pull(doShowPullLogs, dockerConfigPath, registryAccount, registrySecret) + err := imageInspector.Pull(doShowPullLogs, dockerConfigPath, registryAccount, registrySecret, platform) if err != nil { if strings.Contains(err.Error(), "not found") || strings.Contains(err.Error(), "API error (404)") { diff --git a/pkg/app/master/command/build/kubernetes.go b/pkg/app/master/command/build/kubernetes.go index 1de7cb101..abc9d5992 100644 --- a/pkg/app/master/command/build/kubernetes.go +++ b/pkg/app/master/command/build/kubernetes.go @@ -98,6 +98,7 @@ type kubeHandleOptions struct { execCmd string imageBuildEngine string imageBuildArch string + platform string } func (h *kubeHandler) Handle( @@ -135,7 +136,8 @@ func (h *kubeHandler) Handle( opts.StatePath, h.dockerClient, h.logger, - h.report) + h.report, + opts.platform) workload.TargetContainer().Image = imageInspector.ImageRef // 3. Patch and run the workload diff --git a/pkg/app/master/command/cliflags.go b/pkg/app/master/command/cliflags.go index 842d908d8..c05fc191c 100644 --- a/pkg/app/master/command/cliflags.go +++ b/pkg/app/master/command/cliflags.go @@ -82,6 +82,7 @@ const ( FlagRegistryAccount = "registry-account" FlagRegistrySecret = "registry-secret" FlagShowPullLogs = "show-plogs" + FlagPlatform = "platform" //Compose-related flags FlagComposeFile = "compose-file" @@ -207,6 +208,7 @@ const ( FlagRegistryAccountUsage = "Target registry account used when pulling images from private registries" FlagRegistrySecretUsage = "Target registry secret used when pulling images from private registries" FlagShowPullLogsUsage = "Show image pull logs" + FlagPlatformUsage = "Target platform for the container image if it's a multi-architecture image (e.g., linux/arm64)" //Compose-related flags FlagComposeFileUsage = "Load container info from selected compose file(s)" @@ -493,6 +495,12 @@ var CommonFlags = map[string]cli.Flag{ Usage: FlagShowPullLogsUsage, EnvVars: []string{"DSLIM_PLOG"}, }, + FlagPlatform: &cli.StringFlag{ + Name: FlagPlatform, + Value: "", + Usage: FlagPlatformUsage, + EnvVars: []string{"DSLIM_PLATFORM"}, + }, // FlagComposeFile: &cli.StringSliceFlag{ Name: FlagComposeFile, diff --git a/pkg/app/master/command/debug/cli.go b/pkg/app/master/command/debug/cli.go index 9def11cfd..d7c857caa 100644 --- a/pkg/app/master/command/debug/cli.go +++ b/pkg/app/master/command/debug/cli.go @@ -82,6 +82,7 @@ type CommandParams struct { UID int64 /// GID to use for the debugging sidecar container GID int64 + Platform string /// run the debug sidecar as a privileged container DoRunPrivileged bool /// use the security context params from the target container with the debug sidecar container @@ -170,6 +171,7 @@ var CLI = &cli.Command{ cflag(FlagRunPrivileged), cflag(FlagSecurityContextFromTarget), cflag(FlagFallbackToTargetUser), + command.Cflag(command.FlagPlatform), command.Cflag(command.FlagTUI), }, Action: func(ctx *cli.Context) error { @@ -220,6 +222,7 @@ var CLI = &cli.Command{ ActionConnectSession: ctx.Bool(FlagConnectSession), UID: ctx.Int64(FlagUID), GID: ctx.Int64(FlagGID), + Platform: ctx.String(command.FlagPlatform), DoRunPrivileged: ctx.Bool(FlagRunPrivileged), UseSecurityContextFromTarget: ctx.Bool(FlagSecurityContextFromTarget), DoFallbackToTargetUser: ctx.Bool(FlagFallbackToTargetUser), diff --git a/pkg/app/master/command/debug/handle_containerd_runtime.go b/pkg/app/master/command/debug/handle_containerd_runtime.go index cad8c2d23..6924de65f 100644 --- a/pkg/app/master/command/debug/handle_containerd_runtime.go +++ b/pkg/app/master/command/debug/handle_containerd_runtime.go @@ -282,7 +282,11 @@ func HandleContainerdRuntime( if err != nil { logger.WithError(err).Trace("api.ImageService.Get") logger.Debugf("api.Pull(%s)", commandParams.DebugContainerImage) - debugImage, err = api.Pull(ctx, commandParams.DebugContainerImage, containerd.WithPullUnpack) + pullOpts := []containerd.RemoteOpt{containerd.WithPullUnpack} + if commandParams.Platform != "" { + pullOpts = append(pullOpts, containerd.WithPlatform(commandParams.Platform)) + } + debugImage, err = api.Pull(ctx, commandParams.DebugContainerImage, pullOpts...) if err != nil { logger.WithError(err).Error("api.Pull") xc.FailOn(err) diff --git a/pkg/app/master/command/debug/handle_docker_runtime.go b/pkg/app/master/command/debug/handle_docker_runtime.go index 39ac9a25e..c950ea82e 100644 --- a/pkg/app/master/command/debug/handle_docker_runtime.go +++ b/pkg/app/master/command/debug/handle_docker_runtime.go @@ -214,7 +214,7 @@ func HandleDockerRuntime( noImage, err := imageInspector.NoImage() errutil.FailOn(err) if noImage { - err := imageInspector.Pull(true, "", "", "") + err := imageInspector.Pull(true, "", "", "", commandParams.Platform) xc.FailOn(err) } diff --git a/pkg/app/master/command/debug/handle_kubernetes_runtime.go b/pkg/app/master/command/debug/handle_kubernetes_runtime.go index d7dd1827f..5ff6896ce 100644 --- a/pkg/app/master/command/debug/handle_kubernetes_runtime.go +++ b/pkg/app/master/command/debug/handle_kubernetes_runtime.go @@ -516,7 +516,7 @@ func HandleKubernetesRuntime( if err == nil { var foundImage bool if noImage { - if err := imageInspector.Pull(true, "", "", ""); err != nil { + if err := imageInspector.Pull(true, "", "", "", commandParams.Platform); err != nil { logger.WithError(err).Trace("imageInspector.Pull") } diff --git a/pkg/app/master/command/debug/handle_podman_runtime.go b/pkg/app/master/command/debug/handle_podman_runtime.go index 5db3f4f69..3881c39d5 100644 --- a/pkg/app/master/command/debug/handle_podman_runtime.go +++ b/pkg/app/master/command/debug/handle_podman_runtime.go @@ -529,6 +529,7 @@ func podmanEnsureImage(logger *log.Entry, connCtx context.Context, image string) if !exists { logger.Tracef("Pulling image '%s'...", image) + //TODO: support Platform in podman pull _, err = images.Pull(connCtx, image, nil) if err != nil { return err diff --git a/pkg/app/master/command/profile/cli.go b/pkg/app/master/command/profile/cli.go index cce3306ee..89fe8cf04 100644 --- a/pkg/app/master/command/profile/cli.go +++ b/pkg/app/master/command/profile/cli.go @@ -28,6 +28,7 @@ var CLI = &cli.Command{ command.Cflag(command.FlagRegistryAccount), command.Cflag(command.FlagRegistrySecret), command.Cflag(command.FlagShowPullLogs), + command.Cflag(command.FlagPlatform), //Compose support command.Cflag(command.FlagComposeFile), //not used yet command.Cflag(command.FlagTargetComposeSvc), //not used yet @@ -119,6 +120,7 @@ var CLI = &cli.Command{ registryAccount := ctx.String(command.FlagRegistryAccount) registrySecret := ctx.String(command.FlagRegistrySecret) doShowPullLogs := ctx.Bool(command.FlagShowPullLogs) + platform := ctx.String(command.FlagPlatform) doRmFileArtifacts := ctx.Bool(command.FlagRemoveFileArtifacts) doCopyMetaArtifacts := ctx.String(command.FlagCopyMetaArtifacts) @@ -293,6 +295,7 @@ var CLI = &cli.Command{ registryAccount, registrySecret, doShowPullLogs, + platform, crOpts, httpProbeOpts, portBindings, diff --git a/pkg/app/master/command/profile/handler.go b/pkg/app/master/command/profile/handler.go index 8dcc17860..b73cc7b60 100644 --- a/pkg/app/master/command/profile/handler.go +++ b/pkg/app/master/command/profile/handler.go @@ -51,6 +51,7 @@ func OnCommand( registryAccount string, registrySecret string, doShowPullLogs bool, + platform string, crOpts *config.ContainerRunOptions, httpProbeOpts config.HTTPProbeOptions, portBindings map[docker.Port][]docker.PortBinding, @@ -174,7 +175,7 @@ func OnCommand( "message": "trying to pull target image", }) - err := imageInspector.Pull(doShowPullLogs, dockerConfigPath, registryAccount, registrySecret) + err := imageInspector.Pull(doShowPullLogs, dockerConfigPath, registryAccount, registrySecret, platform) errutil.FailOn(err) } else { xc.Out.Info("target.image.error", diff --git a/pkg/app/master/command/run/cli.go b/pkg/app/master/command/run/cli.go index b86185be8..db4e6ea3f 100644 --- a/pkg/app/master/command/run/cli.go +++ b/pkg/app/master/command/run/cli.go @@ -22,6 +22,7 @@ type CommandParams struct { RegistryAccount string RegistrySecret string DoShowPullLogs bool + Platform string Entrypoint []string Cmd []string DoLiveLogs bool @@ -41,6 +42,7 @@ func CommandFlagValues(ctx *cli.Context) (*CommandParams, error) { RegistryAccount: ctx.String(command.FlagRegistryAccount), RegistrySecret: ctx.String(command.FlagRegistrySecret), DoShowPullLogs: ctx.Bool(command.FlagShowPullLogs), + Platform: ctx.String(command.FlagPlatform), DoLiveLogs: ctx.Bool(FlagLiveLogs), DoTerminal: ctx.Bool(FlagTerminal), EnvVars: ctx.StringSlice(command.FlagEnv), @@ -88,6 +90,7 @@ var CLI = &cli.Command{ command.Cflag(command.FlagRegistryAccount), command.Cflag(command.FlagRegistrySecret), command.Cflag(command.FlagShowPullLogs), + command.Cflag(command.FlagPlatform), command.Cflag(command.FlagEntrypoint), command.Cflag(command.FlagCmd), cflag(FlagLiveLogs), diff --git a/pkg/app/master/command/run/handler.go b/pkg/app/master/command/run/handler.go index bd454fc3b..20830a1c2 100644 --- a/pkg/app/master/command/run/handler.go +++ b/pkg/app/master/command/run/handler.go @@ -92,7 +92,7 @@ func OnCommand( "message": "trying to pull target image", }) - err := imageInspector.Pull(cparams.DoShowPullLogs, cparams.DockerConfigPath, cparams.RegistryAccount, cparams.RegistrySecret) + err := imageInspector.Pull(cparams.DoShowPullLogs, cparams.DockerConfigPath, cparams.RegistryAccount, cparams.RegistrySecret, cparams.Platform) errutil.FailOn(err) } else { xc.Out.Info("target.image.error", diff --git a/pkg/app/master/command/xray/cli.go b/pkg/app/master/command/xray/cli.go index cbbb831f7..e2106342a 100644 --- a/pkg/app/master/command/xray/cli.go +++ b/pkg/app/master/command/xray/cli.go @@ -54,6 +54,7 @@ var XRayFlags = []cli.Flag{ command.Cflag(command.FlagRegistryAccount), command.Cflag(command.FlagRegistrySecret), command.Cflag(command.FlagShowPullLogs), + command.Cflag(command.FlagPlatform), cflag(FlagChanges), cflag(FlagChangesOutput), cflag(FlagLayer), @@ -204,6 +205,7 @@ var CLI = &cli.Command{ registryAccount := ctx.String(command.FlagRegistryAccount) registrySecret := ctx.String(command.FlagRegistrySecret) doShowPullLogs := ctx.Bool(command.FlagShowPullLogs) + platform := ctx.String(command.FlagPlatform) changes, err := parseChangeTypes(ctx.StringSlice(FlagChanges)) if err != nil { @@ -350,6 +352,7 @@ var CLI = &cli.Command{ registryAccount, registrySecret, doShowPullLogs, + platform, changes, changesOutputs, layers, diff --git a/pkg/app/master/command/xray/handler.go b/pkg/app/master/command/xray/handler.go index 258d52d11..dc0697754 100644 --- a/pkg/app/master/command/xray/handler.go +++ b/pkg/app/master/command/xray/handler.go @@ -107,6 +107,7 @@ func OnCommand( registryAccount string, registrySecret string, doShowPullLogs bool, + platform string, changes map[string]struct{}, changesOutputs map[string]struct{}, layers map[string]struct{}, @@ -257,7 +258,7 @@ func OnCommand( "message": "trying to pull target image", }) - err := imageInspector.Pull(doShowPullLogs, dockerConfigPath, registryAccount, registrySecret) + err := imageInspector.Pull(doShowPullLogs, dockerConfigPath, registryAccount, registrySecret, platform) if err != nil { if strings.Contains(err.Error(), "not found") || strings.Contains(err.Error(), "API error (404)") { diff --git a/pkg/app/master/inspectors/image/image_inspector.go b/pkg/app/master/inspectors/image/image_inspector.go index aa6640d45..e0b7415da 100644 --- a/pkg/app/master/inspectors/image/image_inspector.go +++ b/pkg/app/master/inspectors/image/image_inspector.go @@ -92,7 +92,7 @@ func (i *Inspector) NoImage() (bool, error) { } // Pull tries to download the target image -func (i *Inspector) Pull(showPullLog bool, dockerConfigPath, registryAccount, registrySecret string) error { +func (i *Inspector) Pull(showPullLog bool, dockerConfigPath, registryAccount, registrySecret, platform string) error { var pullLog bytes.Buffer var repo string var tag string @@ -108,6 +108,7 @@ func (i *Inspector) Pull(showPullLog bool, dockerConfigPath, registryAccount, re input := crt.PullImageOptions{ Repository: repo, Tag: tag, + Platform: platform, } if showPullLog { diff --git a/pkg/crt/clients.go b/pkg/crt/clients.go index 724b82b0f..ee0bfcdbe 100644 --- a/pkg/crt/clients.go +++ b/pkg/crt/clients.go @@ -109,6 +109,7 @@ type ImageHistory struct { type PullImageOptions struct { Repository string Tag string + Platform string OutputStream io.Writer } diff --git a/pkg/crt/docker/dockercrtclient/dockercrtclient.go b/pkg/crt/docker/dockercrtclient/dockercrtclient.go index e1be5da20..eb07c2eb8 100644 --- a/pkg/crt/docker/dockercrtclient/dockercrtclient.go +++ b/pkg/crt/docker/dockercrtclient/dockercrtclient.go @@ -255,6 +255,7 @@ func (ref *Instance) PullImage(opts crt.PullImageOptions, authConfig crt.AuthCon input := docker.PullImageOptions{ Repository: opts.Repository, Tag: opts.Tag, + Platform: opts.Platform, } if opts.OutputStream != nil {