Skip to content

Commit

Permalink
feat: podman multiarch support (#1157)
Browse files Browse the repository at this point in the history
* feat: use podman for building custom images if executable is found

Signed-off-by: Soumil Paranjpay <[email protected]>

* feat: add support for multiarch with podman

Signed-off-by: shashank381 <[email protected]>

* feat: allow providing container runtime for multi arch scripts

Signed-off-by: shashank381 <[email protected]>

---------

Signed-off-by: shashank381 <[email protected]>
Co-authored-by: Soumil Paranjpay <[email protected]>
  • Loading branch information
shashank381 and Soumil-07 authored Apr 9, 2024
1 parent 3bf7465 commit f1a2483
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

REGISTRY_URL={{ .RegistryURL }}
REGISTRY_NAMESPACE={{ .RegistryNamespace }}
CONTAINER_RUNTIME=docker
CONTAINER_RUNTIME={{ .ContainerRuntime }}
if [ "$#" -gt 1 ]; then
REGISTRY_URL=$1
REGISTRY_NAMESPACE=$2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
:: 1) buildandpush_multiarchimages.bat
:: 2) buildandpush_multiarchimages.bat index.docker.io your_registry_namespace
:: 3) buildandpush_multiarchimages.bat quay.io your_quay_username linux/amd64,linux/arm64,linux/s390x
:: 4) ./buildandpush_multiarchimages.bat docker
:: 5) ./buildandpush_multiarchimages.bat podman quay.io your_quay_username linux/amd64,linux/arm64,linux/s390x

@echo off
for /F "delims=" %%i in ("%cd%") do set basename="%%~ni"
Expand All @@ -29,6 +31,12 @@ if not %basename% == "scripts" (
REM go to the parent directory so that all the relative paths will be correct
cd {{ .RelParentOfSourceDir }}

SET CONTAINER_RUNTIME={{ .ContainerRuntime }}
IF "%1"!="" (
SET CONTAINER_RUNTIME=%1%
shift
)

IF "%3"=="" GOTO DEFAULT_PLATFORMS
SET PLATFORMS=%3%
GOTO REGISTRY
Expand All @@ -42,22 +50,41 @@ GOTO REGISTRY
IF "%1"=="" GOTO DEFAULT_REGISTRY
SET REGISTRY_URL=%1
SET REGISTRY_NAMESPACE=%2
GOTO MAIN
GOTO DOCKER_CONTAINER_RUNTIME

:DEFAULT_REGISTRY
SET REGISTRY_URL={{ .RegistryURL }}
SET REGISTRY_NAMESPACE={{ .RegistryNamespace }}
GOTO DOCKER_CONTAINER_RUNTIME

:DOCKER_CONTAINER_RUNTIME
IF NOT "%CONTAINER_RUNTIME%" == "docker" GOTO PODMAN_CONTAINER_RUNTIME
GOTO MAIN

:PODMAN_CONTAINER_RUNTIME
IF NOT "%CONTAINER_RUNTIME%" == "podman" GOTO UNSUPPORTED_BUILD_SYSTEM
GOTO MAIN

:UNSUPPORTED_BUILD_SYSTEM
echo 'Unsupported build system passed as an argument for pushing the images.'
GOTO SKIP

:MAIN
:: Uncomment the below line if you want to enable login before pushing
:: docker login %REGISTRY_URL%
{{- range $dockerfile := .DockerfilesConfig }}

echo "building and pushing image {{ $dockerfile.ImageName }}"
pushd {{ $dockerfile.ContextWindows }}
docker buildx build --platform ${PLATFORMS} -f {{ $dockerfile.DockerfileName }} --push --tag ${REGISTRY_URL}/${REGISTRY_NAMESPACE}/{{ $dockerfile.ImageName }} .
IF "%CONTAINER_RUNTIME%" == "docker" (
docker buildx build --platform ${PLATFORMS} -f {{ $dockerfile.DockerfileName }} --push --tag ${REGISTRY_URL}/${REGISTRY_NAMESPACE}/{{ $dockerfile.ImageName }} .
) ELSE (
podman manifest create ${REGISTRY_URL}/${REGISTRY_NAMESPACE}/{{ $dockerfile.ImageName }}
podman build --platform ${PLATFORMS} -f {{ $dockerfile.DockerfileName }} --manifest ${REGISTRY_URL}/${REGISTRY_NAMESPACE}/{{ $dockerfile.ImageName }} .
podman manifest push ${REGISTRY_URL}/${REGISTRY_NAMESPACE}/{{ $dockerfile.ImageName }}
)
popd
{{- end }}

echo "done"

:SKIP
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
# 1) ./buildandpush_multiarchimages.sh
# 2) ./buildandpush_multiarchimages.sh index.docker.io your_registry_namespace
# 3) ./buildandpush_multiarchimages.sh quay.io your_quay_username linux/amd64,linux/arm64,linux/s390x
# 4) ./buildandpush_multiarchimages.sh docker
# 5) ./buildandpush_multiarchimages.sh podman quay.io your_quay_username linux/amd64,linux/arm64,linux/s390x

if [[ "$(basename "$PWD")" != 'scripts' ]] ; then
echo 'please run this script from the "scripts" directory'
Expand All @@ -29,20 +31,41 @@ cd {{ .RelParentOfSourceDir }} # go to the parent directory so that all the rela
REGISTRY_URL={{ .RegistryURL }}
REGISTRY_NAMESPACE={{ .RegistryNamespace }}
PLATFORMS="linux/amd64,linux/arm64,linux/s390x,linux/ppc64le"
CONTAINER_RUNTIME={{ .ContainerRuntime }}

if [ "$#" -gt 0 ] && [[ "$1" == "docker" || "$1" == "podman" ]]; then
CONTAINER_RUNTIME=$1
shift;
fi

if [ "$#" -gt 1 ]; then
REGISTRY_URL=$1
REGISTRY_NAMESPACE=$2
fi
if [ "$#" -eq 3 ]; then
PLATFORMS=$3
fi

if [ "${CONTAINER_RUNTIME}" != "docker" ] && [ "${CONTAINER_RUNTIME}" != "podman" ]; then
echo 'Unsupported container runtime passed as an argument for building the images: '"${CONTAINER_RUNTIME}"
exit 1
fi


# Uncomment the below line if you want to enable login before pushing
# docker login ${REGISTRY_URL}
{{- range $dockerfile := .DockerfilesConfig }}

echo 'building and pushing image {{ $dockerfile.ImageName }}'
cd {{ $dockerfile.ContextUnix }}
docker buildx build --platform ${PLATFORMS} -f {{ $dockerfile.DockerfileName }} --push --tag ${REGISTRY_URL}/${REGISTRY_NAMESPACE}/{{ $dockerfile.ImageName }} .
if [ "${CONTAINER_RUNTIME}" == "docker" ]
then
docker buildx build --platform ${PLATFORMS} -f {{ $dockerfile.DockerfileName }} --push --tag ${REGISTRY_URL}/${REGISTRY_NAMESPACE}/{{ $dockerfile.ImageName }} .
else
podman manifest create ${REGISTRY_URL}/${REGISTRY_NAMESPACE}/{{ $dockerfile.ImageName }}
podman build --platform ${PLATFORMS} -f {{ $dockerfile.DockerfileName }} --manifest ${REGISTRY_URL}/${REGISTRY_NAMESPACE}/{{ $dockerfile.ImageName }} .
podman manifest push ${REGISTRY_URL}/${REGISTRY_NAMESPACE}/{{ $dockerfile.ImageName }}
fi

cd -
{{- end }}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ if [[ "$(basename "$PWD")" != 'scripts' ]] ; then
echo 'please run this script from the "scripts" directory'
exit 1
fi
CONTAINER_RUNTIME=docker
CONTAINER_RUNTIME={{ .ContainerRuntime }}
if [ "$#" -eq 1 ]; then
CONTAINER_RUNTIME=$1
fi
Expand Down
12 changes: 12 additions & 0 deletions common/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"math/rand"
"net/url"
"os"
"os/exec"
"path/filepath"
"reflect"
"regexp"
Expand Down Expand Up @@ -1593,3 +1594,14 @@ func IsHTTPURL(str string) bool {

return regex.MatchString(str)
}

// GetDefaultContainerRuntime returns the preferred container runtime of the host
func GetDefaultContainerRuntime() string {
_, err := exec.LookPath("podman")
if err == nil {
logrus.Info("Podman executable found in the directories named by the PATH environment variable. Using Podman as the container runtime.")
return "podman"
}
logrus.Info("Couldn't find Podman executable in the directories named by the PATH environment variable. Using Docker as the container runtime.")
return "docker"
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type DockerfileImagePushScriptConfig struct {

// ImagePushTemplateConfig represents template config used by ImagePush script
type ImagePushTemplateConfig struct {
ContainerRuntime string
RegistryURL string
RegistryNamespace string
Images []string
Expand Down Expand Up @@ -79,7 +80,9 @@ func (t *ContainerImagesPushScript) DirectoryDetect(dir string) (services map[st
// Transform transforms the artifacts
func (t *ContainerImagesPushScript) Transform(newArtifacts []transformertypes.Artifact, alreadySeenArtifacts []transformertypes.Artifact) ([]transformertypes.PathMapping, []transformertypes.Artifact, error) {
pathMappings := []transformertypes.PathMapping{}
ipt := ImagePushTemplateConfig{}
ipt := ImagePushTemplateConfig{
ContainerRuntime: common.GetDefaultContainerRuntime(),
}
for _, a := range newArtifacts {
if a.Type != artifacts.NewImagesArtifactType {
continue
Expand Down
2 changes: 2 additions & 0 deletions transformer/dockerfile/dockerfilebuildscripttransformer.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type DockerfileImageBuildScriptConfig struct {

// DockerfileImageBuildScriptTemplateConfig represents the data used to fill the build script generator template
type DockerfileImageBuildScriptTemplateConfig struct {
ContainerRuntime string
RelParentOfSourceDir string
DockerfilesConfig []DockerfileImageBuildConfig
RegistryURL string
Expand Down Expand Up @@ -177,6 +178,7 @@ func (t *DockerfileImageBuildScript) Transform(newArtifacts []transformertypes.A
RegistryURL: commonqa.ImageRegistry(),
RegistryNamespace: commonqa.ImageRegistryNamespace(),
DockerfilesConfig: dockerfilesImageBuildConfig,
ContainerRuntime: common.GetDefaultContainerRuntime(),
}
pathMappings = append(pathMappings, transformertypes.PathMapping{
Type: transformertypes.TemplatePathMappingType,
Expand Down

0 comments on commit f1a2483

Please sign in to comment.