Use single-arch in dockerfile

This is necessary since the builder no longer passes the platform flag
to the build. This would lead to dockerfiles that are mixing multi and single
arch stages to pull the wrong architecture images, particularly when
trying to build images in emulated builds (e.g. armv7hf built on aarch64).

Moving the full build to single-arch solves this as the docker engine is
capable of chosing the right architecture from the manifest. Once some
of the builder issues are fixed, we should move to #2141

Relates-to: balena-io/balena-builder#1010
Change-type: patch
This commit is contained in:
Felipe Lalanne 2023-03-09 21:16:49 -03:00
parent 4411f4f074
commit 17aa625d3b
2 changed files with 16 additions and 33 deletions

View File

@ -1,24 +1,28 @@
ARG ARCH=%%BALENA_ARCH%% ARG ARCH=%%BALENA_ARCH%%
# Used by livepush to support multi arch images in older
# balenaOS with buggy platform support
# see https://github.com/balena-os/balena-engine/issues/269
ARG PREFIX=library
ARG FATRW_VERSION=0.2.9 ARG FATRW_VERSION=0.2.9
FROM arm32v6/alpine:3.16 as alpine-rpi
FROM arm32v7/alpine:3.16 as alpine-armv7hf
FROM arm64v8/alpine:3.16 as alpine-aarch64
FROM amd64/alpine:3.16 as alpine-amd64
FROM i386/alpine:3.16 as alpine-i386
FROM arm32v6/alpine:3.11 as procmail-rpi
FROM arm32v7/alpine:3.11 as procmail-armv7hf
FROM arm64v8/alpine:3.11 as procmail-aarch64
FROM amd64/alpine:3.11 as procmail-amd64
FROM i386/alpine:3.11 as procmail-i386
################################################### ###################################################
# Build the supervisor dependencies # Build the supervisor dependencies
################################################### ###################################################
FROM balenalib/${ARCH}-alpine-node:16-run as build-base FROM balenalib/${ARCH}-alpine-node:16-run as build-base
ARG ARCH ARG ARCH
ARG PREFIX
ARG FATRW_VERSION ARG FATRW_VERSION
ARG FATRW_ARCHIVE="fatrw-${ARCH}.tar.gz" ARG FATRW_ARCHIVE="fatrw-${ARCH}.tar.gz"
ARG FATRW_LOCATION="https://github.com/balena-os/fatrw/releases/download/v${FATRW_VERSION}/${FATRW_ARCHIVE}" ARG FATRW_LOCATION="https://github.com/balena-os/fatrw/releases/download/v${FATRW_VERSION}/${FATRW_ARCHIVE}"
# Sanity check to prevent a prefix for a non-official docker image being
# inserted. Only 'library' and 'arm32v6' are allowed right now
RUN for allowed in "library" "arm32v6"; do [ "${PREFIX}" = "${allowed}" ] && break; done
WORKDIR /usr/src/app WORKDIR /usr/src/app
@ -63,7 +67,7 @@ RUN /setup-journal.sh
# Extra dependencies. This uses alpine 3.11 as the # Extra dependencies. This uses alpine 3.11 as the
# procmail package was removed on 3.12 # procmail package was removed on 3.12
################################################### ###################################################
FROM ${PREFIX}/alpine:3.11 as extra FROM procmail-${ARCH} as extra
RUN apk add --update --no-cache procmail RUN apk add --update --no-cache procmail
@ -71,7 +75,7 @@ RUN apk add --update --no-cache procmail
# Image with the final production dependencies. # Image with the final production dependencies.
# This image will also be be used for testing # This image will also be be used for testing
################################################### ###################################################
FROM ${PREFIX}/alpine:3.16 as runtime-base FROM alpine-${ARCH} as runtime-base
WORKDIR /usr/src/app WORKDIR /usr/src/app

View File

@ -14,27 +14,6 @@ interface Opts {
arch?: string; arch?: string;
} }
function getPathPrefix(arch: string) {
switch (arch) {
/**
* Proper paths are
* - armv6 - arm32v6
* - armv7hf - arm32v7
* - aarch64 - arm64v8
* - amd64 - amd64
* - i386 - i386
*
* We only set the prefix for v6 images since rpi devices are
* the only ones that seem to have the issue
* https://github.com/balena-os/balena-engine/issues/269
*/
case 'rpi':
return 'arm32v6';
default:
return 'library';
}
}
export async function initDevice(opts: Opts) { export async function initDevice(opts: Opts) {
const arch = opts.arch ?? (await device.getDeviceArch(opts.docker)); const arch = opts.arch ?? (await device.getDeviceArch(opts.docker));
const image = `${opts.imageName}:${opts.imageTag}`; const image = `${opts.imageName}:${opts.imageTag}`;
@ -42,7 +21,7 @@ export async function initDevice(opts: Opts) {
const buildCache = await device.readBuildCache(opts.address); const buildCache = await device.readBuildCache(opts.address);
const stageImages = await device.performBuild(opts.docker, opts.dockerfile, { const stageImages = await device.performBuild(opts.docker, opts.dockerfile, {
buildargs: { ARCH: arch, PREFIX: getPathPrefix(arch) }, buildargs: { ARCH: arch },
t: image, t: image,
labels: { 'io.balena.livepush-image': '1', 'io.balena.architecture': arch }, labels: { 'io.balena.livepush-image': '1', 'io.balena.architecture': arch },
cachefrom: (await device.getCacheFrom(opts.docker)) cachefrom: (await device.getCacheFrom(opts.docker))