Add support for 'platform' parameter (#75)

Signed-off-by: James Addison <jay@jp-hosting.net>
This commit is contained in:
James Addison 2021-10-14 23:09:15 +01:00 committed by GitHub
parent 979e6a6c6e
commit 3bb95d0042
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 119 additions and 21 deletions

View file

@ -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
@ -51,7 +51,7 @@ jobs:
EOF
- name: Build Image
id: build_image
id: build_image_multiarch
uses: ./buildah-build/
with:
image: ${{ env.IMAGE_NAME }}
@ -63,9 +63,9 @@ 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 }}'
@ -73,9 +73,76 @@ jobs:
- 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 }}

View file

@ -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**
@ -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
@ -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).

View file

@ -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.

2
dist/index.js vendored

File diff suppressed because one or more lines are too long

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

View file

@ -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>;
@ -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);
@ -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);

View file

@ -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

View file

@ -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";
@ -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) {
@ -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`);
@ -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`);
@ -119,6 +125,7 @@ async function doBuildFromScratch(
workingdir: workingDir,
envs,
arch,
platform,
};
await cli.config(containerId, newImageConfig);
await cli.copy(containerId, content);

View file

@ -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