balena-supervisor/sync/livepush.ts
Felipe Lalanne 1722286a87 Refactor supervisor Dockerfile to remove custom dependencies
Restructure the supervisor image to remove the dependency on the custom `alpine-supervisor-base`
image and the custom node build. The dockerfile is now a multi-stage
build that splits the process into two build stages and two runtime
stages.

Here is the full list of changes

- The node binary is now copied from  `balenalib/${ARCH}-alpine-node:12-run`, the node binary
now supports running with a debugger.
- The runtime image now inherits from the official `alpine:3.16` image
- Tests are ran within the runtime image configuration instead of the
  build image
- Livepush is ran within the runtime image context
- Unnecessary packages have been removed
- Removed avahi-daemon.conf as that service is not being used
- Fix livepush to work with a multi-stage image. This also deprecates the `image-tag` argument to npm run sync as
`SUPERVISOR_TAG` is no longer used by new OSs
- Fix livepush build on old rpi devices. Allows passing a 'PREFIX'
  argument to let the builder pull images directly from docker hub arch
  repositories. Relates to https://github.com/balena-os/balena-engine/issues/269

Change-type: patch
2022-07-18 12:31:23 -04:00

71 lines
1.8 KiB
TypeScript

import * as chokidar from 'chokidar';
import * as Docker from 'dockerode';
import * as _ from 'lodash';
import * as Path from 'path';
import { Dockerfile, Livepush } from 'livepush';
// TODO: Pass build args to the livepush process
export async function startLivepush(opts: {
dockerfile: Dockerfile;
containerId: string;
docker: Docker;
noinit: boolean;
stageImages?: string[];
}) {
const livepush = await Livepush.init({
stageImages: [],
...opts,
context: Path.join(__dirname, '..'),
});
livepush.addListener('commandExecute', ({ command }) => {
console.log(`Executing command: ${command} `);
});
livepush.addListener('commandReturn', ({ returnCode }) => {
if (returnCode !== 0) {
console.log(` Command executed with code ${returnCode}`);
}
});
livepush.addListener('commandOutput', ({ output }) => {
console.log(output.data.toString());
});
livepush.addListener('containerRestart', () => {
console.log('Restarting container');
});
const livepushExecutor = getExecutor(livepush);
const watcher = chokidar
.watch('.', {
ignored: /((^|[\/\\])\..|(node_modules|sync|test)\/.*)/,
ignoreInitial: opts.noinit,
})
.on('add', (path) => livepushExecutor(path))
.on('change', (path) => livepushExecutor(path))
.on('unlink', (path) => livepushExecutor(undefined, path));
return async () => {
await watcher.close();
await livepush.cleanupIntermediateContainers();
};
}
const getExecutor = (livepush: Livepush) => {
let changedFiles: string[] = [];
let deletedFiles: string[] = [];
const actualExecutor = _.debounce(async () => {
await livepush.performLivepush(changedFiles, deletedFiles);
changedFiles = [];
deletedFiles = [];
});
return (changed?: string, deleted?: string) => {
if (changed) {
changedFiles.push(changed);
}
if (deleted) {
deletedFiles.push(deleted);
}
actualExecutor();
};
};