Expand Warden runtime model
This commit is contained in:
parent
4dec267545
commit
3375dd2c56
5 changed files with 120 additions and 14 deletions
|
|
@ -185,5 +185,23 @@ The intended split is:
|
|||
- `clawdie-cp`: thick, shared networking, persistent
|
||||
- worker jails: thin, shared networking, ephemeral
|
||||
- networked workers: thin, VNET, ephemeral
|
||||
- browser automation desktop: Linux VM, image-backed, outside Bastille jail provisioning
|
||||
|
||||
That policy is defined in code so provisioning decisions are explicit before Bastille automation is added.
|
||||
|
||||
## Bastille Template Mapping
|
||||
|
||||
For Warden, Bastille templates map cleanly to only part of the future runtime matrix:
|
||||
|
||||
- `default/thick` → `controlPlane`
|
||||
- `default/thin` → `worker`
|
||||
- `default/thin` + `default/vnet` → `networkedWorker`
|
||||
- `default/clone` → future optimization for fast worker spawning from a prepared base
|
||||
|
||||
The future `browserVm` profile is different:
|
||||
|
||||
- not a Bastille jail
|
||||
- not a FreeBSD jail template problem
|
||||
- should be implemented as a `bhyve` Linux VM with snapshot or image-based lifecycle
|
||||
|
||||
So no extra `bastille.conf` changes are needed now to prepare for the browser VM path.
|
||||
|
|
|
|||
|
|
@ -121,3 +121,10 @@ Use:
|
|||
- `bhyve` Linux VM for GUI/browser tasks
|
||||
|
||||
Do not force the browser/desktop use case into the plain jail runtime path.
|
||||
|
||||
In Warden profile terms, that future executor is:
|
||||
|
||||
- runtime: `linux-vm`
|
||||
- role: `browser-vm`
|
||||
- provisioning: `image`
|
||||
- networking: `vm-bridged` by default
|
||||
|
|
|
|||
|
|
@ -20,11 +20,12 @@ In practice:
|
|||
|
||||
Warden uses distinct jail profiles so the control-plane and worker layers do not collapse into one shape.
|
||||
|
||||
| Profile | Role | Provisioning | Networking | Persistent | Use |
|
||||
| ------- | ---- | ------------ | ---------- | ---------- | --- |
|
||||
| `controlPlane` | `control-plane` | `thick` | `shared` | yes | Main Clawdie control-plane jail |
|
||||
| `worker` | `worker` | `thin` | `shared` | no | Default short-lived worker jail |
|
||||
| `networkedWorker` | `networked-worker` | `thin` | `vnet` | no | Future worker needing its own network stack |
|
||||
| Profile | Runtime | Role | Provisioning | Networking | Persistent | Use |
|
||||
| ------- | ------- | ---- | ------------ | ---------- | ---------- | --- |
|
||||
| `controlPlane` | `freebsd-jail` | `control-plane` | `thick` | `shared` | yes | Main Clawdie control-plane jail |
|
||||
| `worker` | `freebsd-jail` | `worker` | `thin` | `shared` | no | Default short-lived worker jail |
|
||||
| `networkedWorker` | `freebsd-jail` | `networked-worker` | `thin` | `vnet` | no | Future worker needing its own network stack |
|
||||
| `browserVm` | `linux-vm` | `browser-vm` | `image` | `vm-bridged` | yes | Future Linux desktop/browser executor |
|
||||
|
||||
This policy is now encoded in `src/jail-config.ts`.
|
||||
|
||||
|
|
@ -57,6 +58,6 @@ Do not use `Warden` to rename:
|
|||
The intended model is:
|
||||
|
||||
- **Warden jail runtime** for PI, coding, CLI work, and low-overhead task execution
|
||||
- optional **Warden browser VM** later via `bhyve` for Linux desktop and browser automation workloads
|
||||
- **Warden browser VM** later via `bhyve` for Linux desktop and browser automation workloads
|
||||
|
||||
That keeps the lightweight path lightweight while still leaving room for a heavier GUI executor later.
|
||||
The browser VM is intentionally not modeled as a jail option. It is a separate runtime class.
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ describe('Jail Config', () => {
|
|||
});
|
||||
|
||||
it('should default control-plane profile to thick shared persistent', () => {
|
||||
expect(DEFAULT_JAIL_CONFIG.runtime).toBe('freebsd-jail');
|
||||
expect(DEFAULT_JAIL_CONFIG.role).toBe('control-plane');
|
||||
expect(DEFAULT_JAIL_CONFIG.provisioning).toBe('thick');
|
||||
expect(DEFAULT_JAIL_CONFIG.networking).toBe('shared');
|
||||
|
|
@ -68,6 +69,7 @@ describe('Jail Config', () => {
|
|||
it('should include Warden profile comments', () => {
|
||||
const config = generateJailConfig();
|
||||
|
||||
expect(config).toContain('# Warden runtime: freebsd-jail');
|
||||
expect(config).toContain('# Warden role: control-plane');
|
||||
expect(config).toContain('# Provisioning: thick');
|
||||
expect(config).toContain('# Networking: shared');
|
||||
|
|
@ -212,27 +214,47 @@ describe('Jail Config', () => {
|
|||
|
||||
expect(errors).toContain('Invalid jail networking mode');
|
||||
});
|
||||
|
||||
it('should fail for invalid runtime kind', () => {
|
||||
const errors = validateJailConfig({
|
||||
...DEFAULT_JAIL_CONFIG,
|
||||
runtime: 'invalid' as JailConfig['runtime'],
|
||||
});
|
||||
|
||||
expect(errors).toContain('Invalid Warden runtime kind');
|
||||
});
|
||||
});
|
||||
|
||||
describe('WARDEN_JAIL_PROFILES', () => {
|
||||
it('should define control-plane as thick and shared', () => {
|
||||
expect(WARDEN_JAIL_PROFILES.controlPlane.runtime).toBe('freebsd-jail');
|
||||
expect(WARDEN_JAIL_PROFILES.controlPlane.provisioning).toBe('thick');
|
||||
expect(WARDEN_JAIL_PROFILES.controlPlane.networking).toBe('shared');
|
||||
expect(WARDEN_JAIL_PROFILES.controlPlane.persistent).toBe(true);
|
||||
});
|
||||
|
||||
it('should define worker as thin and shared', () => {
|
||||
expect(WARDEN_JAIL_PROFILES.worker.runtime).toBe('freebsd-jail');
|
||||
expect(WARDEN_JAIL_PROFILES.worker.provisioning).toBe('thin');
|
||||
expect(WARDEN_JAIL_PROFILES.worker.networking).toBe('shared');
|
||||
expect(WARDEN_JAIL_PROFILES.worker.persistent).toBe(false);
|
||||
});
|
||||
|
||||
it('should define networked worker as thin and vnet', () => {
|
||||
expect(WARDEN_JAIL_PROFILES.networkedWorker.runtime).toBe('freebsd-jail');
|
||||
expect(WARDEN_JAIL_PROFILES.networkedWorker.provisioning).toBe('thin');
|
||||
expect(WARDEN_JAIL_PROFILES.networkedWorker.networking).toBe('vnet');
|
||||
expect(WARDEN_JAIL_PROFILES.networkedWorker.persistent).toBe(false);
|
||||
});
|
||||
|
||||
it('should define browser VM as image-backed linux vm', () => {
|
||||
expect(WARDEN_JAIL_PROFILES.browserVm.runtime).toBe('linux-vm');
|
||||
expect(WARDEN_JAIL_PROFILES.browserVm.role).toBe('browser-vm');
|
||||
expect(WARDEN_JAIL_PROFILES.browserVm.provisioning).toBe('image');
|
||||
expect(WARDEN_JAIL_PROFILES.browserVm.networking).toBe('vm-bridged');
|
||||
expect(WARDEN_JAIL_PROFILES.browserVm.persistent).toBe(true);
|
||||
});
|
||||
|
||||
it('should build worker config from profile', () => {
|
||||
const config = getDefaultJailConfigForProfile('worker');
|
||||
|
||||
|
|
@ -250,5 +272,16 @@ describe('Jail Config', () => {
|
|||
expect(config.networking).toBe('vnet');
|
||||
expect(config.persistent).toBe(false);
|
||||
});
|
||||
|
||||
it('should build browser VM config from profile', () => {
|
||||
const config = getDefaultJailConfigForProfile('browserVm');
|
||||
|
||||
expect(config.name).toBe('warden-browser-vm');
|
||||
expect(config.runtime).toBe('linux-vm');
|
||||
expect(config.provisioning).toBe('image');
|
||||
expect(config.networking).toBe('vm-bridged');
|
||||
expect(config.persistent).toBe(true);
|
||||
expect(config.path).toBe('/vm/warden-browser-vm');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ export interface JailConfig {
|
|||
hostname: string;
|
||||
ip: string;
|
||||
path: string;
|
||||
runtime: WardenRuntimeKind;
|
||||
role: JailRole;
|
||||
provisioning: JailProvisioning;
|
||||
networking: JailNetworking;
|
||||
|
|
@ -12,11 +13,17 @@ export interface JailConfig {
|
|||
resources: ResourceLimits;
|
||||
}
|
||||
|
||||
export type JailRole = 'control-plane' | 'worker' | 'networked-worker';
|
||||
export type JailProvisioning = 'thick' | 'thin';
|
||||
export type JailNetworking = 'shared' | 'vnet';
|
||||
export type WardenRuntimeKind = 'freebsd-jail' | 'linux-vm';
|
||||
export type JailRole =
|
||||
| 'control-plane'
|
||||
| 'worker'
|
||||
| 'networked-worker'
|
||||
| 'browser-vm';
|
||||
export type JailProvisioning = 'thick' | 'thin' | 'clone' | 'image';
|
||||
export type JailNetworking = 'shared' | 'vnet' | 'vm-bridged' | 'vm-nat';
|
||||
|
||||
export interface JailProfile {
|
||||
runtime: WardenRuntimeKind;
|
||||
role: JailRole;
|
||||
provisioning: JailProvisioning;
|
||||
networking: JailNetworking;
|
||||
|
|
@ -25,10 +32,11 @@ export interface JailProfile {
|
|||
}
|
||||
|
||||
export const WARDEN_JAIL_PROFILES: Record<
|
||||
'controlPlane' | 'worker' | 'networkedWorker',
|
||||
'controlPlane' | 'worker' | 'networkedWorker' | 'browserVm',
|
||||
JailProfile
|
||||
> = {
|
||||
controlPlane: {
|
||||
runtime: 'freebsd-jail',
|
||||
role: 'control-plane',
|
||||
provisioning: 'thick',
|
||||
networking: 'shared',
|
||||
|
|
@ -36,6 +44,7 @@ export const WARDEN_JAIL_PROFILES: Record<
|
|||
baseRelease: '15.0-RELEASE',
|
||||
},
|
||||
worker: {
|
||||
runtime: 'freebsd-jail',
|
||||
role: 'worker',
|
||||
provisioning: 'thin',
|
||||
networking: 'shared',
|
||||
|
|
@ -43,12 +52,21 @@ export const WARDEN_JAIL_PROFILES: Record<
|
|||
baseRelease: '15.0-RELEASE',
|
||||
},
|
||||
networkedWorker: {
|
||||
runtime: 'freebsd-jail',
|
||||
role: 'networked-worker',
|
||||
provisioning: 'thin',
|
||||
networking: 'vnet',
|
||||
persistent: false,
|
||||
baseRelease: '15.0-RELEASE',
|
||||
},
|
||||
browserVm: {
|
||||
runtime: 'linux-vm',
|
||||
role: 'browser-vm',
|
||||
provisioning: 'image',
|
||||
networking: 'vm-bridged',
|
||||
persistent: true,
|
||||
baseRelease: 'linux-desktop-image',
|
||||
},
|
||||
};
|
||||
|
||||
export interface MountPoint {
|
||||
|
|
@ -69,6 +87,7 @@ export const DEFAULT_JAIL_CONFIG: JailConfig = {
|
|||
hostname: 'clawdie-cp.clawdie.si',
|
||||
ip: '192.168.1.100',
|
||||
path: '/jails/clawdie-cp',
|
||||
runtime: WARDEN_JAIL_PROFILES.controlPlane.runtime,
|
||||
role: WARDEN_JAIL_PROFILES.controlPlane.role,
|
||||
provisioning: WARDEN_JAIL_PROFILES.controlPlane.provisioning,
|
||||
networking: WARDEN_JAIL_PROFILES.controlPlane.networking,
|
||||
|
|
@ -110,6 +129,7 @@ export function generateJailConfig(config: Partial<JailConfig> = {}): string {
|
|||
|
||||
const lines: string[] = [
|
||||
`${finalConfig.name} {`,
|
||||
` # Warden runtime: ${finalConfig.runtime}`,
|
||||
` # Warden role: ${finalConfig.role}`,
|
||||
` # Provisioning: ${finalConfig.provisioning}`,
|
||||
` # Networking: ${finalConfig.networking}`,
|
||||
|
|
@ -183,18 +203,26 @@ export function validateJailConfig(config: JailConfig): string[] {
|
|||
errors.push('Jail path must be absolute');
|
||||
}
|
||||
|
||||
if (!['control-plane', 'worker', 'networked-worker'].includes(config.role)) {
|
||||
if (
|
||||
!['control-plane', 'worker', 'networked-worker', 'browser-vm'].includes(
|
||||
config.role,
|
||||
)
|
||||
) {
|
||||
errors.push('Invalid jail role');
|
||||
}
|
||||
|
||||
if (!['thick', 'thin'].includes(config.provisioning)) {
|
||||
if (!['thick', 'thin', 'clone', 'image'].includes(config.provisioning)) {
|
||||
errors.push('Invalid jail provisioning mode');
|
||||
}
|
||||
|
||||
if (!['shared', 'vnet'].includes(config.networking)) {
|
||||
if (!['shared', 'vnet', 'vm-bridged', 'vm-nat'].includes(config.networking)) {
|
||||
errors.push('Invalid jail networking mode');
|
||||
}
|
||||
|
||||
if (!['freebsd-jail', 'linux-vm'].includes(config.runtime)) {
|
||||
errors.push('Invalid Warden runtime kind');
|
||||
}
|
||||
|
||||
config.mountpoints.forEach((mp, index) => {
|
||||
if (!mp.source || !mp.destination) {
|
||||
errors.push(`Mountpoint ${index} missing source or destination`);
|
||||
|
|
@ -217,12 +245,31 @@ export function getDefaultJailConfigForProfile(
|
|||
return { ...DEFAULT_JAIL_CONFIG };
|
||||
}
|
||||
|
||||
if (profileName === 'browserVm') {
|
||||
return {
|
||||
...DEFAULT_JAIL_CONFIG,
|
||||
name: 'warden-browser-vm',
|
||||
hostname: 'warden-browser-vm.clawdie.si',
|
||||
path: '/vm/warden-browser-vm',
|
||||
runtime: profile.runtime,
|
||||
role: profile.role,
|
||||
provisioning: profile.provisioning,
|
||||
networking: profile.networking,
|
||||
persistent: profile.persistent,
|
||||
environment: {
|
||||
...DEFAULT_JAIL_CONFIG.environment,
|
||||
JAIL_NAME: 'warden-browser-vm',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const suffix = profileName === 'worker' ? 'worker' : 'networked-worker';
|
||||
return {
|
||||
...DEFAULT_JAIL_CONFIG,
|
||||
name: `warden-${suffix}`,
|
||||
hostname: `warden-${suffix}.clawdie.si`,
|
||||
path: `/jails/warden-${suffix}`,
|
||||
runtime: profile.runtime,
|
||||
role: profile.role,
|
||||
provisioning: profile.provisioning,
|
||||
networking: profile.networking,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue