mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2024-12-21 14:37:49 +00:00
Stop using host journalctl
The supervisor had to chroot into the host root in order to read the journal logs. This won't be possible anymore once the supervisor becomes an app. This commit copies the journalctl binary and necessary libraries from a debian image into the supervisor image in order to be able to use the tool on runtime. Change-type: patch
This commit is contained in:
parent
3e1b1b0be1
commit
91b119cbae
@ -37,7 +37,6 @@ RUN strip /usr/local/bin/node
|
|||||||
|
|
||||||
# Install fatrw
|
# Install fatrw
|
||||||
RUN curl -SLO "${FATRW_LOCATION}" && \
|
RUN curl -SLO "${FATRW_LOCATION}" && \
|
||||||
echo curl -SLO "${FATRW_LOCATION}" && \
|
|
||||||
ls -la "${FATRW_ARCHIVE}" && \
|
ls -la "${FATRW_ARCHIVE}" && \
|
||||||
tar -xzf "${FATRW_ARCHIVE}" -C /usr/local/bin && \
|
tar -xzf "${FATRW_ARCHIVE}" -C /usr/local/bin && \
|
||||||
rm -f "${FATRW_ARCHIVE}"
|
rm -f "${FATRW_ARCHIVE}"
|
||||||
@ -45,6 +44,21 @@ RUN curl -SLO "${FATRW_LOCATION}" && \
|
|||||||
# Just install dev dependencies first
|
# Just install dev dependencies first
|
||||||
RUN npm ci --build-from-source --sqlite=/usr/lib
|
RUN npm ci --build-from-source --sqlite=/usr/lib
|
||||||
|
|
||||||
|
###################################################################
|
||||||
|
# Journal access.
|
||||||
|
# The supervisor is built on an alpine image but still needs
|
||||||
|
# to use journalctl (from systemd) which cannot be built for
|
||||||
|
# musl. We hack around this by copying the binary and its library
|
||||||
|
# dependencies to the final image
|
||||||
|
###################################################################
|
||||||
|
FROM balenalib/${ARCH}-debian:bullseye-run as journal
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends systemd
|
||||||
|
|
||||||
|
COPY ./build-utils/setup-journal.sh /
|
||||||
|
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
|
||||||
@ -70,6 +84,9 @@ COPY --from=build-base /usr/local/bin/fatrw /usr/local/bin/fatrw
|
|||||||
# Similarly, from the procmail package we just need the lockfile binary
|
# Similarly, from the procmail package we just need the lockfile binary
|
||||||
COPY --from=extra /usr/bin/lockfile /usr/bin/lockfile
|
COPY --from=extra /usr/bin/lockfile /usr/bin/lockfile
|
||||||
|
|
||||||
|
# Copy journalctl and library dependecies to the final image
|
||||||
|
COPY --from=journal /sysroot /
|
||||||
|
|
||||||
# Runtime dependencies
|
# Runtime dependencies
|
||||||
RUN apk add --no-cache \
|
RUN apk add --no-cache \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
|
12
build-utils/setup-journal.sh
Executable file
12
build-utils/setup-journal.sh
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
mkdir -p /sysroot/bin
|
||||||
|
cp /bin/journalctl /sysroot/bin/
|
||||||
|
# Get all library dependencies from the binary
|
||||||
|
for lib in $(ldd /bin/journalctl | grep -oE '(\/.+?) '); do
|
||||||
|
mkdir -p "/sysroot/$(dirname "$lib")"
|
||||||
|
# Copy the dependency dereferencing any symlinks
|
||||||
|
cp -L "$lib" "/sysroot/$lib"
|
||||||
|
done
|
10
entry.sh
10
entry.sh
@ -26,6 +26,16 @@ if [ -n "${BALENA_ROOT_CA}" ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Setup necessary directories for journalctl
|
||||||
|
# NOTE: this won't be necessary once the supervisor can update
|
||||||
|
# itself, as using the label io.balena.features.journal-logs will
|
||||||
|
# achieve the same objective
|
||||||
|
if [ -d /mnt/root/run/log/journal ]; then
|
||||||
|
mkdir -p /run/log
|
||||||
|
ln -sf /mnt/root/run/log/journal /run/log/journal
|
||||||
|
ln -sf /mnt/root/etc/machine-id /etc/machine-id
|
||||||
|
fi
|
||||||
|
|
||||||
# Mount the host kernel module path onto the expected location
|
# Mount the host kernel module path onto the expected location
|
||||||
# We need to do this as busybox doesn't support using a custom location
|
# We need to do this as busybox doesn't support using a custom location
|
||||||
if [ ! -d /lib/modules ]; then
|
if [ ! -d /lib/modules ]; then
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { ChildProcess, spawn } from 'child_process';
|
import { ChildProcess, spawn } from 'child_process';
|
||||||
|
|
||||||
import constants = require('./constants');
|
|
||||||
import log from './supervisor-console';
|
import log from './supervisor-console';
|
||||||
|
|
||||||
export function spawnJournalctl(opts: {
|
export function spawnJournalctl(opts: {
|
||||||
@ -13,11 +12,7 @@ export function spawnJournalctl(opts: {
|
|||||||
filterString?: string;
|
filterString?: string;
|
||||||
since?: number;
|
since?: number;
|
||||||
}): ChildProcess {
|
}): ChildProcess {
|
||||||
const args = [
|
const args: string[] = [];
|
||||||
// The directory we want to run the chroot from
|
|
||||||
constants.rootMountPoint,
|
|
||||||
'journalctl',
|
|
||||||
];
|
|
||||||
if (opts.all) {
|
if (opts.all) {
|
||||||
args.push('-a');
|
args.push('-a');
|
||||||
}
|
}
|
||||||
@ -52,9 +47,9 @@ export function spawnJournalctl(opts: {
|
|||||||
args.push(opts.filterString);
|
args.push(opts.filterString);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug('Spawning journald with: chroot ', args.join(' '));
|
log.debug('Spawning journalctl', args.join(' '));
|
||||||
|
|
||||||
const journald = spawn('chroot', args, {
|
const journald = spawn('journalctl', args, {
|
||||||
stdio: 'pipe',
|
stdio: 'pipe',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { SinonStub, stub } from 'sinon';
|
import { SinonStub, stub } from 'sinon';
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
|
|
||||||
import constants = require('~/lib/constants');
|
|
||||||
import { spawnJournalctl } from '~/lib/journald';
|
import { spawnJournalctl } from '~/lib/journald';
|
||||||
|
|
||||||
describe('lib/journald', () => {
|
describe('lib/journald', () => {
|
||||||
@ -29,8 +28,7 @@ describe('lib/journald', () => {
|
|||||||
format: 'json-pretty',
|
format: 'json-pretty',
|
||||||
});
|
});
|
||||||
|
|
||||||
const expectedCommand = `chroot`;
|
const expectedCommand = `journalctl`;
|
||||||
const expectedCoreArgs = [`${constants.rootMountPoint}`, 'journalctl'];
|
|
||||||
const expectedOptionalArgs = [
|
const expectedOptionalArgs = [
|
||||||
'-a',
|
'-a',
|
||||||
'--follow',
|
'--follow',
|
||||||
@ -45,13 +43,11 @@ describe('lib/journald', () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const actualCommand = spawn.firstCall.args[0];
|
const actualCommand = spawn.firstCall.args[0];
|
||||||
const actualCoreArgs = spawn.firstCall.args[1].slice(0, 2);
|
const actualOptionalArgs = spawn.firstCall.args[1];
|
||||||
const actualOptionalArgs = spawn.firstCall.args[1].slice(2);
|
|
||||||
|
|
||||||
expect(spawn.calledOnce).to.be.true;
|
expect(spawn.calledOnce).to.be.true;
|
||||||
|
|
||||||
expect(actualCommand).deep.equal(expectedCommand);
|
expect(actualCommand).deep.equal(expectedCommand);
|
||||||
expect(actualCoreArgs).deep.equal(expectedCoreArgs);
|
|
||||||
|
|
||||||
expectedOptionalArgs.forEach((arg) => {
|
expectedOptionalArgs.forEach((arg) => {
|
||||||
expect(actualOptionalArgs).to.include(arg);
|
expect(actualOptionalArgs).to.include(arg);
|
||||||
|
Loading…
Reference in New Issue
Block a user