clawdie-ai/setup/tailscale.ts
Clawdie AI cdf2c8f296 Enable Tailscale jail auto-join (Sam & Codex)
Add a setup helper to enable tailscale inside jails when FEATURE_TAILSCALE

and an auth key are present, prefetch tailscale packages, and document

the installer shortcut.

---

Build: FAIL — not run

Tests: FAIL — not run
2026-04-04 15:40:47 +00:00

74 lines
2.1 KiB
TypeScript

import { readEnvFile } from '../src/env.js';
import { logger } from '../src/logger.js';
type BastilleRunner = (args: string[]) => { ok: boolean; output: string };
interface TailscaleConfig {
enabled: boolean;
authKey: string;
}
function parseYes(value?: string): boolean {
return /^(YES|yes|true|TRUE|1)$/u.test(value || '');
}
function loadTailscaleConfig(): TailscaleConfig {
const envValues = readEnvFile(['FEATURE_TAILSCALE', 'TAILSCALE_AUTHKEY']);
const enabled = parseYes(process.env.FEATURE_TAILSCALE || envValues.FEATURE_TAILSCALE);
const authKey = process.env.TAILSCALE_AUTHKEY || envValues.TAILSCALE_AUTHKEY || '';
return { enabled, authKey };
}
function normalizeHostname(value: string): string {
const cleaned = value.toLowerCase().replace(/[^a-z0-9-]/gu, '');
return cleaned || 'clawdie';
}
export function maybeEnableTailscaleInJail(
runBastille: BastilleRunner,
jailName: string,
hostnameHint: string,
): void {
const config = loadTailscaleConfig();
if (!config.enabled) return;
if (!config.authKey) {
logger.warn({ jailName }, 'Tailscale enabled but no auth key; skipping jail login');
return;
}
const hostname = normalizeHostname(hostnameHint || jailName);
const pkg = runBastille(['pkg', jailName, 'install', '-y', 'tailscale']);
if (!pkg.ok) {
logger.warn({ jailName }, 'Tailscale package install failed in jail (skipping)');
return;
}
const sysrc = runBastille(['cmd', jailName, 'sysrc', 'tailscaled_enable=YES']);
if (!sysrc.ok) {
logger.warn({ jailName }, 'Tailscale sysrc enable failed in jail');
}
const start = runBastille(['service', jailName, 'tailscaled', 'restart']);
if (!start.ok) {
logger.warn({ jailName }, 'Tailscale service start failed in jail');
}
const up = runBastille([
'cmd',
jailName,
'tailscale',
'up',
'--authkey',
config.authKey,
'--hostname',
hostname,
]);
if (!up.ok) {
logger.warn({ jailName }, 'Tailscale up failed in jail (check jail logs)');
return;
}
logger.info({ jailName, hostname }, 'Tailscale enabled in jail');
}