Merge pull request #1878 from balena-os/write-sync-config-json

Write sync config json
This commit is contained in:
bulldozer-balena[bot] 2022-02-02 15:53:26 +00:00 committed by GitHub
commit eaaa4eeec6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 11 additions and 18 deletions

View File

@ -4,7 +4,7 @@ import { promises as fs } from 'fs';
import * as path from 'path'; import * as path from 'path';
import * as constants from '../lib/constants'; import * as constants from '../lib/constants';
import { writeAndSyncFile, writeFileAtomic } from '../lib/fs-utils'; import { writeAndSyncFile } from '../lib/fs-utils';
import * as osRelease from '../lib/os-release'; import * as osRelease from '../lib/os-release';
import log from '../lib/supervisor-console'; import log from '../lib/supervisor-console';
@ -86,21 +86,14 @@ export default class ConfigJsonConfigBackend {
}); });
} }
private write(): Promise<void> { private async write(): Promise<void> {
let atomicWritePossible = true; // We use writeAndSyncFile since /mnt/boot partition is a vfat
return this.pathOnHost() // filesystem which dows not provide atomic file renames. The best
.catch((err) => { // course of action on that case is to write and sync as soon as possible
log.error('There was an error detecting the config.json path', err); return writeAndSyncFile(
atomicWritePossible = false; await this.pathOnHost(),
return constants.configJsonNonAtomicPath; JSON.stringify(this.cache),
}) );
.then((configPath) => {
if (atomicWritePossible) {
return writeFileAtomic(configPath, JSON.stringify(this.cache));
} else {
return writeAndSyncFile(configPath, JSON.stringify(this.cache));
}
});
} }
private async read(): Promise<string> { private async read(): Promise<string> {
@ -133,7 +126,7 @@ export default class ConfigJsonConfigBackend {
// then we can't do atomic changes (only access to config.json we have is in /boot, // then we can't do atomic changes (only access to config.json we have is in /boot,
// which is assumed to be a file bind mount where rename is impossible). // which is assumed to be a file bind mount where rename is impossible).
throw new Error( throw new Error(
'Could not determine config.json path on host, atomic write will not be possible', `OS version '${osVersion}' does not match any known balenaOS version.`,
); );
} }
} }

View File

@ -27,7 +27,7 @@ export async function writeFileAtomic(
data: string | Buffer, data: string | Buffer,
): Promise<void> { ): Promise<void> {
await writeAndSyncFile(`${pathName}.new`, data); await writeAndSyncFile(`${pathName}.new`, data);
await fs.rename(`${pathName}.new`, pathName); await safeRename(`${pathName}.new`, pathName);
} }
export async function safeRename(src: string, dest: string): Promise<void> { export async function safeRename(src: string, dest: string): Promise<void> {