headplane/app/integration/proc.ts

82 lines
1.9 KiB
TypeScript
Raw Normal View History

2024-12-31 10:30:14 +05:30
import { readdir, readFile } from 'node:fs/promises';
import { platform } from 'node:os';
import { join, resolve } from 'node:path';
import { kill } from 'node:process';
2024-12-31 10:30:14 +05:30
import log from '~/utils/log';
2024-12-31 10:30:14 +05:30
import { createIntegration } from './integration';
interface Context {
2024-12-31 10:30:14 +05:30
pid: number | undefined;
}
export default createIntegration<Context>({
name: 'Native Linux (/proc)',
context: {
pid: undefined,
},
isAvailable: async (context) => {
if (platform() !== 'linux') {
2024-12-31 10:30:14 +05:30
log.error('INTG', '/proc is only available on Linux');
return false;
}
2024-12-31 10:30:14 +05:30
log.debug('INTG', 'Checking /proc for Headscale process');
const dir = resolve('/proc');
try {
2024-12-31 10:30:14 +05:30
const subdirs = await readdir(dir);
const promises = subdirs.map(async (dir) => {
2024-12-31 10:30:14 +05:30
const pid = Number.parseInt(dir, 10);
if (Number.isNaN(pid)) {
2024-12-31 10:30:14 +05:30
return;
}
2024-12-31 10:30:14 +05:30
const path = join('/proc', dir, 'cmdline');
try {
2024-12-31 10:30:14 +05:30
log.debug('INTG', 'Reading %s', path);
const data = await readFile(path, 'utf8');
if (data.includes('headscale')) {
2024-12-31 10:30:14 +05:30
return pid;
}
} catch (error) {
2024-12-31 10:30:14 +05:30
log.error('INTG', 'Failed to read %s: %s', path, error);
}
2024-12-31 10:30:14 +05:30
});
2024-12-31 10:30:14 +05:30
const results = await Promise.allSettled(promises);
const pids = [];
for (const result of results) {
if (result.status === 'fulfilled' && result.value) {
2024-12-31 10:30:14 +05:30
pids.push(result.value);
}
}
2024-12-31 10:30:14 +05:30
log.debug('INTG', 'Found Headscale processes: %o', pids);
if (pids.length > 1) {
2024-12-31 10:30:14 +05:30
log.error(
'INTG',
'Found %d Headscale processes: %s',
pids.length,
pids.join(', '),
2024-12-31 10:30:14 +05:30
);
return false;
}
if (pids.length === 0) {
2024-12-31 10:30:14 +05:30
log.error('INTG', 'Could not find Headscale process');
return false;
}
2024-12-31 10:30:14 +05:30
context.pid = pids[0];
log.info('INTG', 'Found Headscale process with PID: %d', context.pid);
return true;
} catch {
2024-12-31 10:30:14 +05:30
log.error('INTG', 'Failed to read /proc');
return false;
}
2024-12-31 10:30:14 +05:30
},
});