balena-supervisor/sync/init.ts
Felipe Lalanne 17aa625d3b 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
2023-03-10 17:30:22 -03:00

62 lines
1.7 KiB
TypeScript

import * as Bluebird from 'bluebird';
import * as Docker from 'dockerode';
import { Dockerfile } from 'livepush';
import * as device from './device';
interface Opts {
address: string;
imageName: string;
imageTag: string;
docker: Docker;
dockerfile: Dockerfile;
nocache: boolean;
arch?: string;
}
export async function initDevice(opts: Opts) {
const arch = opts.arch ?? (await device.getDeviceArch(opts.docker));
const image = `${opts.imageName}:${opts.imageTag}`;
const buildCache = await device.readBuildCache(opts.address);
const stageImages = await device.performBuild(opts.docker, opts.dockerfile, {
buildargs: { ARCH: arch },
t: image,
labels: { 'io.balena.livepush-image': '1', 'io.balena.architecture': arch },
cachefrom: (await device.getCacheFrom(opts.docker))
.concat(image)
.concat(buildCache),
nocache: opts.nocache,
});
// Store the list of stage images for the next time the sync
// command is called. This will only live until the device is rebooted
await device.writeBuildCache(opts.address, stageImages);
// Now that we have our new image on the device, we need
// to stop the supervisor, update
// /tmp/update-supervisor.conf with our version, and
// restart the supervisor
await device.stopSupervisor(opts.address);
await device.replaceSupervisorImage(
opts.address,
opts.imageName,
opts.imageTag,
);
await device.startSupervisor(opts.address);
let supervisorContainer: undefined | Docker.ContainerInfo;
while (supervisorContainer == null) {
try {
supervisorContainer = await device.getSupervisorContainer(
opts.docker,
true,
);
} catch {
await Bluebird.delay(500);
}
}
return { containerId: supervisorContainer.Id, stageImages };
}