Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for 'platform' parameter #75

Merged
merged 1 commit into from
Oct 14, 2021
Merged
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
85 changes: 76 additions & 9 deletions .github/workflows/multiarch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ env:
IMAGE_TAG: latest

jobs:
build:
name: Build image using Buildah
build-multiarch:
name: Build multi-architecture image using Buildah
runs-on: ubuntu-20.04
strategy:
fail-fast: false
Expand Down Expand Up @@ -51,7 +51,7 @@ jobs:
EOF

- name: Build Image
id: build_image
id: build_image_multiarch
uses: ./buildah-build/
with:
image: ${{ env.IMAGE_NAME }}
Expand All @@ -63,19 +63,86 @@ jobs:

- name: Echo Outputs
run: |
echo "Image: ${{ steps.build_image.outputs.image }}"
echo "Tags: ${{ steps.build_image.outputs.tags }}"
echo "Tagged Image: ${{ steps.build_image.outputs.image-with-tag }}"
echo "Image: ${{ steps.build_image_multiarch.outputs.image }}"
echo "Tags: ${{ steps.build_image_multiarch.outputs.tags }}"
echo "Tagged Image: ${{ steps.build_image_multiarch.outputs.image-with-tag }}"

- name: Check images created
run: buildah images | grep '${{ env.IMAGE_NAME }}'

- name: Check image metadata
run: |
set -x
buildah inspect ${{ steps.build_image.outputs.image }}:${{ env.IMAGE_TAG }} | jq ".OCIv1.architecture"
buildah inspect ${{ steps.build_image.outputs.image }}:${{ env.IMAGE_TAG }} | jq ".Docker.architecture"
buildah inspect ${{ steps.build_image_multiarch.outputs.image }}:${{ env.IMAGE_TAG }} | jq ".OCIv1.architecture"
buildah inspect ${{ steps.build_image_multiarch.outputs.image }}:${{ env.IMAGE_TAG }} | jq ".Docker.architecture"

- name: Run image
run: |
podman run --rm ${{ steps.build_image.outputs.image }}:${{ env.IMAGE_TAG }}
podman run --rm ${{ steps.build_image_multiarch.outputs.image }}:${{ env.IMAGE_TAG }}

build-multiplatform:
name: Build multi-platform image using Buildah
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
platform: [ "linux/amd64", "linux/arm64/v8" ]
install_latest: [ true, false ]

steps:

# Checkout buildah action github repository
- name: Checkout Buildah action
uses: actions/checkout@v2
with:
path: "buildah-build"

- name: Install latest buildah
if: matrix.install_latest
run: |
bash buildah-build/.github/install_latest_buildah.sh

- name: Install qemu dependency
run: |
sudo apt-get update
sudo apt-get install -y qemu-user-static

- name: Create Containerfile
run: |
cat > Containerfile<<EOF

FROM docker.io/alpine:3.14

RUN echo "hello world"

ENTRYPOINT [ "sh", "-c", "echo -n 'Machine: ' && uname -m && echo -n 'Bits: ' && getconf LONG_BIT && echo 'goodbye world'" ]
EOF

- name: Build Image
id: build_image_multiplatform
uses: ./buildah-build/
with:
image: ${{ env.IMAGE_NAME }}
tags: ${{ env.IMAGE_TAG }}
platform: ${{ matrix.platform }}
containerfiles: |
./Containerfile

- name: Echo Outputs
run: |
echo "Image: ${{ steps.build_image_multiplatform.outputs.image }}"
echo "Tags: ${{ steps.build_image_multiplatform.outputs.tags }}"
echo "Tagged Image: ${{ steps.build_image_multiplatform.outputs.image-with-tag }}"

- name: Check images created
run: buildah images | grep '${{ env.IMAGE_NAME }}'

- name: Check image metadata
run: |
set -x
buildah inspect ${{ steps.build_image_multiplatform.outputs.image }}:${{ env.IMAGE_TAG }} | jq ".OCIv1.architecture"
buildah inspect ${{ steps.build_image_multiplatform.outputs.image }}:${{ env.IMAGE_TAG }} | jq ".Docker.architecture"

- name: Run image
run: |
podman run --rm ${{ steps.build_image_multiplatform.outputs.image }}:${{ env.IMAGE_TAG }}
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ After building your image, use [push-to-registry](https://github.com/redhat-acti
| Input Name | Description | Default |
| ---------- | ----------- | ------- |
| arch | Label the image with this architecture, instead of defaulting to the host architecture. Refer to [Multi arch builds](#multi-arch-builds) for more information. | None (host architecture)
| platform | Label the image with this platform, instead of defaulting to the host platform. Refer to [Multi arch builds](#multi-arch-builds) for more information. | None (host platform)
| build-args | Build arguments to pass to the Docker build using `--build-arg`, if using a Containerfile that requires ARGs. Use the form `arg_name=arg_value`, and separate arguments with newlines. | None
| context | Path to directory to use as the build context. | `.`
| containerfiles\* | The list of Containerfile paths to perform a build using docker instructions. This is a multiline input to allow multiple Containerfiles. | **Must be provided**
Expand All @@ -43,6 +44,7 @@ After building your image, use [push-to-registry](https://github.com/redhat-acti
| Input Name | Description | Default |
| ---------- | ----------- | ------- |
| arch | Label the image with this architecture, instead of defaulting to the host architecture. Refer to [Multi arch builds](#multi-arch-builds) for more information. | None (host architecture)
| platform | Label the image with this platform, instead of defaulting to the host platform. Refer to [Multi arch builds](#multi-arch-builds) for more information. | None (host platform)
| base-image | The base image to use for the container. | **Must be provided**
| content | Paths to files or directories to copy inside the container to create the file image. This is a multiline input to allow you to copy multiple files/directories.| None
| entrypoint | The entry point to set for the container. This is a multiline input; split arguments across lines. | None
Expand Down Expand Up @@ -179,8 +181,8 @@ sudo podman run --rm --privileged docker.io/tonistiigi/binfmt --install all
```
This registration remains active until the host reboots.

### The `arch` input
The `arch` argument overrides the Architecture label in the output image. It does not actually affect the architectures the output image will run on. The image must still be built for the required architecture.
### The `arch` and `platform` inputs
The `arch` and `platform` arguments override the Architecture and Platform labels in the output image, respectively. They do not actually affect the architectures and platforms the output image will run on. The image must still be built for the required architecture or platform.

There is a simple example [in this issue](https://github.com/redhat-actions/buildah-build/issues/60#issuecomment-876552452).

Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ inputs:
archs:
description: 'Alias for "arch". "arch" takes precedence if both are set.'
required: false
platform:
description: 'Label the image with this PLATFORM, instead of defaulting to the host platform.'
required: false
extra-args:
description: |
Extra args to be passed to buildah bud.
Expand Down
2 changes: 1 addition & 1 deletion dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

13 changes: 11 additions & 2 deletions src/buildah.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ export interface BuildahConfigSettings {
port?: string;
workingdir?: string;
arch?: string;
platform?: string;
}

interface Buildah {
buildUsingDocker(
image: string, context: string, containerFiles: string[], buildArgs: string[],
useOCI: boolean, arch: string, layers: string, extraArgs: string[]
useOCI: boolean, arch: string, platform: string, layers: string, extraArgs: string[]
): Promise<CommandResult>;
from(baseImage: string): Promise<CommandResult>;
config(container: string, setting: BuildahConfigSettings): Promise<CommandResult>;
Expand Down Expand Up @@ -63,13 +64,17 @@ export class BuildahCli implements Buildah {

async buildUsingDocker(
image: string, context: string, containerFiles: string[], buildArgs: string[],
useOCI: boolean, arch: string, layers: string, extraArgs: string[]
useOCI: boolean, arch: string, platform: string, layers: string, extraArgs: string[]
): Promise<CommandResult> {
const args: string[] = [ "bud" ];
if (arch) {
args.push("--arch");
args.push(arch);
}
if (platform) {
args.push("--platform");
args.push(platform);
}
containerFiles.forEach((file) => {
args.push("-f");
args.push(file);
Expand Down Expand Up @@ -135,6 +140,10 @@ export class BuildahCli implements Buildah {
args.push("--arch");
args.push(settings.arch);
}
if (settings.platform) {
args.push("--platform");
args.push(settings.platform);
}
if (settings.workingdir) {
args.push("--workingdir");
args.push(settings.workingdir);
Expand Down
6 changes: 6 additions & 0 deletions src/generated/inputs-outputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ export enum Inputs {
* Default: "false"
*/
OCI = "oci",
/**
* Label the image with this PLATFORM, instead of defaulting to the host platform.
* Required: false
* Default: None.
*/
PLATFORM = "platform",
/**
* The port to expose when running containers based on image
* Required: false
Expand Down
19 changes: 13 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import * as path from "path";
import { Inputs, Outputs } from "./generated/inputs-outputs";
import { BuildahCli, BuildahConfigSettings } from "./buildah";
import {
getArch, getContainerfiles, getInputList, splitByNewline,
getArch, getPlatform, getContainerfiles, getInputList, splitByNewline,
isFullImageName, getFullImageName,
} from "./utils";

Expand Down Expand Up @@ -54,12 +54,17 @@ export async function run(): Promise<void> {
const useOCI = core.getInput(Inputs.OCI) === "true";

const arch = getArch();
const platform = getPlatform();

if (arch && platform) {
throw new Error("The --platform option may not be used in combination with the --arch option.");
}

if (containerFiles.length !== 0) {
await doBuildUsingContainerFiles(cli, newImage, workspace, containerFiles, useOCI, arch);
await doBuildUsingContainerFiles(cli, newImage, workspace, containerFiles, useOCI, arch, platform);
}
else {
await doBuildFromScratch(cli, newImage, useOCI, arch);
await doBuildFromScratch(cli, newImage, useOCI, arch, platform);
}

if (tagsList.length > 1) {
Expand All @@ -71,7 +76,8 @@ export async function run(): Promise<void> {
}

async function doBuildUsingContainerFiles(
cli: BuildahCli, newImage: string, workspace: string, containerFiles: string[], useOCI: boolean, arch: string
cli: BuildahCli, newImage: string, workspace: string, containerFiles: string[], useOCI: boolean, arch: string,
platform: string
): Promise<void> {
if (containerFiles.length === 1) {
core.info(`Performing build from Containerfile`);
Expand All @@ -94,12 +100,12 @@ async function doBuildUsingContainerFiles(
buildahBudExtraArgs = lines.flatMap((line) => line.split(" ")).map((arg) => arg.trim());
}
await cli.buildUsingDocker(
newImage, context, containerFileAbsPaths, buildArgs, useOCI, arch, layers, buildahBudExtraArgs
newImage, context, containerFileAbsPaths, buildArgs, useOCI, arch, platform, layers, buildahBudExtraArgs
);
}

async function doBuildFromScratch(
cli: BuildahCli, newImage: string, useOCI: boolean, arch: string
cli: BuildahCli, newImage: string, useOCI: boolean, arch: string, platform: string
): Promise<void> {
core.info(`Performing build from scratch`);

Expand All @@ -119,6 +125,7 @@ async function doBuildFromScratch(
workingdir: workingDir,
envs,
arch,
platform,
};
await cli.config(containerId, newImageConfig);
await cli.copy(containerId, content);
Expand Down
4 changes: 4 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ export function getArch(): string {
return arch || archs;
}

export function getPlatform(): string {
return core.getInput(Inputs.PLATFORM);
}

export function getContainerfiles(): string[] {
// 'containerfile' should be used over 'dockerfile',
// see https://github.com/redhat-actions/buildah-build/issues/57
Expand Down