Skip to content

Commit 98c4bf2

Browse files
authored
Remove userinfo to support SNAP installs (#332)
1 parent dd4d63f commit 98c4bf2

File tree

11 files changed

+67
-30
lines changed

11 files changed

+67
-30
lines changed

eslint.config.mjs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,27 @@ export default tseslint.config([
161161
message:
162162
'Usage of raw ResourceAttribute strings is restricted in src code. Use ResourceAttribute enum instead',
163163
},
164+
],
165+
'no-restricted-imports': [
166+
'error',
164167
{
165-
selector: "ImportSpecifier[imported.name='readFileSync']",
166-
message: 'Use methods in File.ts',
167-
},
168-
{
169-
selector: "ImportSpecifier[imported.name='readFile']",
170-
message: 'Use methods in File.ts',
168+
paths: [
169+
{
170+
name: 'os',
171+
importNames: ['userInfo'],
172+
message: 'userInfo is not supported in sandbox Linux environments',
173+
},
174+
{
175+
name: 'fs',
176+
importNames: ['readFileSync', 'readFile'],
177+
message: 'Use methods in File.ts',
178+
},
179+
{
180+
name: 'fs/promises',
181+
importNames: ['readFile'],
182+
message: 'Use methods in File.ts',
183+
},
184+
],
171185
},
172186
],
173187
},

src/datastore/FileStore.ts

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { existsSync, mkdirSync } from 'fs';
1+
import { existsSync, mkdirSync, readdirSync, rmSync } from 'fs';
22
import { join } from 'path';
33
import { Logger } from 'pino';
44
import { LoggerFactory } from '../telemetry/LoggerFactory';
@@ -13,27 +13,40 @@ export class FileStoreFactory implements DataStoreFactory {
1313
@Telemetry({ scope: 'FileStore.Global' }) private readonly telemetry!: ScopedTelemetry;
1414

1515
private readonly stores = new Map<StoreName, EncryptedFileStore>();
16+
private readonly fileDbRoot: string;
1617
private readonly fileDbDir: string;
18+
1719
private readonly metricsInterval: NodeJS.Timeout;
20+
private readonly timeout: NodeJS.Timeout;
1821

1922
constructor(rootDir: string) {
2023
this.log = LoggerFactory.getLogger('FileStore.Global');
2124

22-
this.fileDbDir = join(rootDir, 'filedb', `${Version}`);
25+
this.fileDbRoot = join(rootDir, 'filedb');
26+
this.fileDbDir = join(this.fileDbRoot, Version);
27+
2328
if (!existsSync(this.fileDbDir)) {
2429
mkdirSync(this.fileDbDir, { recursive: true });
2530
}
2631

2732
this.metricsInterval = setInterval(() => {
2833
this.emitMetrics();
2934
}, 60 * 1000);
30-
this.log.info(`Initialized FileStore v${Version}`);
35+
36+
this.timeout = setTimeout(
37+
() => {
38+
this.cleanupOldVersions();
39+
},
40+
2 * 60 * 1000,
41+
);
42+
43+
this.log.info(`Initialized FileDB ${Version}`);
3144
}
3245

3346
get(store: StoreName): DataStore {
3447
let val = this.stores.get(store);
3548
if (!val) {
36-
val = new EncryptedFileStore(encryptionKey(Version), store, this.fileDbDir);
49+
val = new EncryptedFileStore(encryptionKey(VersionNumber), store, this.fileDbDir);
3750
this.stores.set(store, val);
3851
}
3952
return val;
@@ -44,12 +57,13 @@ export class FileStoreFactory implements DataStoreFactory {
4457
}
4558

4659
close(): Promise<void> {
60+
clearTimeout(this.timeout);
4761
clearInterval(this.metricsInterval);
4862
return Promise.resolve();
4963
}
5064

5165
private emitMetrics(): void {
52-
this.telemetry.histogram('version', Version);
66+
this.telemetry.histogram('version', VersionNumber);
5367
this.telemetry.histogram('env.entries', this.stores.size);
5468

5569
let totalBytes = 0;
@@ -67,6 +81,22 @@ export class FileStoreFactory implements DataStoreFactory {
6781
unit: 'By',
6882
});
6983
}
84+
85+
private cleanupOldVersions(): void {
86+
const entries = readdirSync(this.fileDbRoot, { withFileTypes: true });
87+
for (const entry of entries) {
88+
try {
89+
if (entry.name !== Version) {
90+
this.telemetry.count('oldVersion.cleanup.count', 1);
91+
rmSync(join(this.fileDbRoot, entry.name), { recursive: true, force: true });
92+
}
93+
} catch (error) {
94+
this.log.error(error, 'Failed to cleanup old FileDB versions');
95+
this.telemetry.count('oldVersion.cleanup.error', 1);
96+
}
97+
}
98+
}
7099
}
71100

72-
const Version = 1;
101+
const VersionNumber = 2;
102+
const Version = `v${VersionNumber}`;

src/datastore/LMDB.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export class LMDBStoreFactory implements DataStoreFactory {
6969
noSubdir: config.noSubdir,
7070
overlappingSync: config.overlappingSync,
7171
},
72-
`Initialized LMDB v${VersionNumber} with stores: ${toString(storeNames)}`,
72+
`Initialized LMDB ${Version} with stores: ${toString(storeNames)}`,
7373
);
7474
}
7575

@@ -139,7 +139,7 @@ export class LMDBStoreFactory implements DataStoreFactory {
139139
}
140140
}
141141

142-
const VersionNumber = 4;
142+
const VersionNumber = 5;
143143
const Version = `v${VersionNumber}`;
144144
const Encoding: 'msgpack' | 'json' | 'string' | 'binary' | 'ordered-binary' = 'msgpack';
145145
const TotalMaxDbSize = 250 * 1024 * 1024; // 250MB max size

src/datastore/file/EncryptedFileStore.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { existsSync, readFileSync, statSync, unlinkSync } from 'fs'; // eslint-disable-line no-restricted-syntax -- files being checked
1+
import { existsSync, readFileSync, statSync, unlinkSync } from 'fs'; // eslint-disable-line no-restricted-imports -- files being checked
22
import { writeFile } from 'fs/promises';
33
import { join } from 'path';
44
import { Mutex } from 'async-mutex';

src/datastore/file/Encryption.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { stableMachineSpecificKey } from '../../utils/MachineKey';
33

44
export function encryptionKey(version: number): Buffer {
55
switch (version) {
6+
case 2:
67
case 1: {
78
return stableMachineSpecificKey('filedb-static-salt', 'filedb-encryption-key-derivation', 32);
89
}

src/datastore/lmdb/Utils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { stableMachineSpecificKey } from '../../utils/MachineKey';
22

33
export function encryptionStrategy(version: number): string | Buffer | undefined {
44
switch (version) {
5+
case 5:
56
case 4: {
67
return stableMachineSpecificKey('lmdb-static-salt', 'lmdb-encryption-key-derivation', 16).toString('hex');
78
}

src/services/S3Service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { readFileSync } from 'fs'; // eslint-disable-line no-restricted-syntax -- Needs to be fixed
1+
import { readFileSync } from 'fs'; // eslint-disable-line no-restricted-imports -- TODO: Needs to be fixed
22
import { fileURLToPath } from 'url';
33
import { S3Client, PutObjectCommand, ListBucketsCommand, HeadObjectCommand } from '@aws-sdk/client-s3';
44
import { Measure } from '../telemetry/TelemetryDecorator';

src/telemetry/LoggerFactory.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
22
import { existsSync } from 'fs';
3-
import { readdir, stat, unlink, writeFile, readFile } from 'fs/promises'; // eslint-disable-line no-restricted-syntax -- circular dependency
3+
import { readdir, stat, unlink, writeFile, readFile } from 'fs/promises'; // eslint-disable-line no-restricted-imports -- circular dependency
44
import { join } from 'path';
55
import { DateTime } from 'luxon';
66
import pino, { LevelWithSilent, Logger } from 'pino';

src/utils/ClientUtil.ts

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/utils/File.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { readFileSync, existsSync, PathLike } from 'fs'; // eslint-disable-line no-restricted-syntax
2-
import { readFile } from 'fs/promises'; // eslint-disable-line no-restricted-syntax
1+
import { readFileSync, existsSync, PathLike } from 'fs'; // eslint-disable-line no-restricted-imports
2+
import { readFile } from 'fs/promises'; // eslint-disable-line no-restricted-imports
33
import { LoggerFactory } from '../telemetry/LoggerFactory';
44
import { toString } from './String';
55

0 commit comments

Comments
 (0)