Use fatrw binary to read/write from boot partition

Change-type: patch
This commit is contained in:
Felipe Lalanne 2022-06-15 16:12:06 -04:00
parent e3bb7f653e
commit c6f5af1fd9

View File

@ -1,6 +1,7 @@
import { spawn } from 'child_process';
import * as path from 'path';
import * as constants from './constants';
import * as fsUtils from './fs-utils';
import { exec } from './fs-utils';
// Returns an absolute path starting from the hostOS root partition
// This path is accessible from within the Supervisor container
@ -14,10 +15,52 @@ export function pathOnBoot(relPath: string) {
return pathOnRoot(path.join(constants.bootMountPoint, relPath));
}
// Receives an absolute path for a file under the boot partition (e.g. `/mnt/root/mnt/boot/config.txt`)
// and writes the given data. This function uses the best effort to write a file trying to minimize corruption
// due to a power cut. Given that the boot partition is a vfat filesystem, this means
// using write + sync
export async function writeToBoot(file: string, data: string | Buffer) {
return await fsUtils.writeAndSyncFile(file, data);
class CodedError extends Error {
constructor(msg: string, readonly code: number) {
super(msg);
}
}
// Receives an absolute path for a file (assumed to be under the boot partition, e.g. `/mnt/root/mnt/boot/config.txt`)
// and reads from the given location. This function uses fatrw to safely read from a FAT filesystem
// https://github.com/balena-os/fatrw
export async function readFromBoot(
fileName: string,
encoding: 'utf-8',
): Promise<string>;
export async function readFromBoot(
fileName: string,
encoding?: string,
): Promise<Buffer>;
export async function readFromBoot(
fileName: string,
encoding = 'buffer',
): Promise<string | Buffer> {
const cmd = ['fatrw', 'read', fileName].join(' ');
const { stdout } = await exec(cmd, { encoding });
return stdout;
}
// Receives an absolute path for a file (assumed to be under the boot partition, e.g. `/mnt/root/mnt/boot/config.txt`)
// and writes the given data. This function uses fatrw to safely write from a FAT filesystem
// https://github.com/balena-os/fatrw
export async function writeToBoot(fileName: string, data: string | Buffer) {
const fatrw = spawn('fatrw', ['write', fileName], { stdio: 'pipe' });
// Write to the process stdinput
fatrw.stdin.write(data);
fatrw.stdin.end();
// We only care about stderr
let error = '';
for await (const chunk of fatrw.stderr) {
error += chunk;
}
const exitCode: number = await new Promise((resolve) => {
fatrw.on('close', resolve);
});
if (exitCode) {
throw new CodedError(`Write failed with error: ${error}`, exitCode);
}
}