Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
13 changes: 12 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,11 @@
},
{
"sourceTag": "scope:backend",
"onlyDependOnLibsWithTags": ["scope:backend", "domain:shared"]
"onlyDependOnLibsWithTags": [
"scope:backend",
"scope:shared",
"domain:shared"
]
},
{
"sourceTag": "scope:keycloak",
Expand Down Expand Up @@ -96,6 +100,13 @@
"domain:identity",
"domain:shared"
]
},
{
"sourceTag": "domain:loadweaver",
"onlyDependOnLibsWithTags": [
"domain:loadweaver",
"domain:shared"
]
}
]
}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,4 @@ opencode.json

# Environment variables
*.env
loadweaver.yml
18 changes: 18 additions & 0 deletions apps/loadweaver/cli-loadweaver/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": ["../../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
10 changes: 10 additions & 0 deletions apps/loadweaver/cli-loadweaver/jest.config.cts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = {
displayName: 'loadweaver-cli-loadweaver',
preset: '../../../jest.preset.cjs',
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../../coverage/apps/loadweaver/cli-loadweaver',
};
145 changes: 145 additions & 0 deletions apps/loadweaver/cli-loadweaver/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
{
"name": "loadweaver-cli-loadweaver",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/loadweaver/cli-loadweaver/src",
"projectType": "application",
"tags": ["type:app", "scope:shared", "domain:loadweaver"],
"targets": {
"build": {
"executor": "@nx/esbuild:esbuild",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
"platform": "node",
"outputPath": "dist/apps/loadweaver/cli-loadweaver",
"format": ["cjs"],
"bundle": true,
"main": "apps/loadweaver/cli-loadweaver/src/main.ts",
"tsConfig": "apps/loadweaver/cli-loadweaver/tsconfig.app.json",
"assets": [
{
"input": "libs/domains/loadweaver/shared/feature-cli-wireguard/src/lib/templates",
"glob": "*.tpl",
"output": "templates/wireguard"
},
{
"input": "libs/domains/loadweaver/shared/feature-cli-vip/src/lib/templates",
"glob": "*.tpl",
"output": "templates/vip"
},
{
"input": "libs/domains/loadweaver/shared/feature-cli-traefik/src/lib/templates",
"glob": "*.tpl",
"output": "templates/traefik"
},
{
"input": "libs/domains/loadweaver/shared/feature-cli-routing/src/lib/templates",
"glob": "*.tpl",
"output": "templates/routing"
}
],
"generatePackageJson": true,
"thirdParty": true,
"esbuildOptions": {
"sourcemap": true,
"loader": {
".tpl": "text"
},
"outExtension": {
".js": ".js"
}
}
},
"configurations": {
"development": {},
"production": {
"esbuildOptions": {
"sourcemap": false,
"outExtension": {
".js": ".js"
}
}
}
}
},
"prune-lockfile": {
"dependsOn": ["build"],
"cache": true,
"executor": "@nx/js:prune-lockfile",
"outputs": [
"{workspaceRoot}/dist/apps/loadweaver/cli-loadweaver/package.json",
"{workspaceRoot}/dist/apps/loadweaver/cli-loadweaver/package-lock.json"
],
"options": {
"buildTarget": "build"
}
},
"copy-workspace-modules": {
"dependsOn": ["build"],
"cache": true,
"outputs": [
"{workspaceRoot}/dist/apps/loadweaver/cli-loadweaver/workspace_modules"
],
"executor": "@nx/js:copy-workspace-modules",
"options": {
"buildTarget": "build"
}
},
"prune": {
"dependsOn": ["prune-lockfile", "copy-workspace-modules"],
"executor": "nx:noop"
},
"serve": {
"continuous": true,
"executor": "@nx/js:node",
"defaultConfiguration": "development",
"dependsOn": ["build"],
"options": {
"buildTarget": "loadweaver-cli-loadweaver:build",
"runBuildTargetDependencies": false
},
"configurations": {
"development": {
"buildTarget": "loadweaver-cli-loadweaver:build:development"
},
"production": {
"buildTarget": "loadweaver-cli-loadweaver:build:production"
}
}
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "apps/loadweaver/cli-loadweaver/jest.config.cts",
"passWithNoTests": true
}
},
"run": {
"executor": "nx:run-commands",
"options": {
"command": "node dist/apps/loadweaver/cli-loadweaver/main.js"
},
"dependsOn": [
{
"target": "build"
}
]
},
"binary": {
"executor": "nx:run-commands",
"dependsOn": ["build"],
"outputs": [
"{workspaceRoot}/dist/apps/loadweaver/cli-loadweaver/bin/loadweaver"
],
"options": {
"commands": [
"npx esbuild apps/loadweaver/cli-loadweaver/src/main.ts --bundle --platform=node --format=cjs --loader:.tpl=text --outfile=dist/apps/loadweaver/cli-loadweaver/bin/loadweaver.mjs --banner:js='#!/usr/bin/env node' --tsconfig=apps/loadweaver/cli-loadweaver/tsconfig.app.json",
"mv dist/apps/loadweaver/cli-loadweaver/bin/loadweaver.mjs dist/apps/loadweaver/cli-loadweaver/bin/loadweaver",
"chmod +x dist/apps/loadweaver/cli-loadweaver/bin/loadweaver"
],
"parallel": false
}
}
}
}
Empty file.
8 changes: 8 additions & 0 deletions apps/loadweaver/cli-loadweaver/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { createProgram } from '@forepath/loadweaver/shared/feature-cli/program';

const program = createProgram();

program.parseAsync(process.argv).catch((err: Error) => {
console.error(err.message);
process.exit(1);
});
15 changes: 15 additions & 0 deletions apps/loadweaver/cli-loadweaver/tsconfig.app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"module": "commonjs",
"types": ["node"]
},
"include": ["src/**/*.ts"],
"exclude": [
"jest.config.ts",
"jest.config.cts",
"src/**/*.spec.ts",
"src/**/*.test.ts"
]
}
16 changes: 16 additions & 0 deletions apps/loadweaver/cli-loadweaver/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"extends": "../../../tsconfig.base.json",
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.spec.json"
}
],
"compilerOptions": {
"esModuleInterop": true
}
}
16 changes: 16 additions & 0 deletions apps/loadweaver/cli-loadweaver/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"module": "commonjs",
"moduleResolution": "node10",
"types": ["jest", "node"]
},
"include": [
"jest.config.ts",
"jest.config.cts",
"src/**/*.test.ts",
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
}
23 changes: 23 additions & 0 deletions docs/loadweaver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Loadweaver

Loadweaver is a Node.js CLI for managing multi-node infrastructure with Docker Swarm, WireGuard, Ceph, Traefik, and floating VIP ingress.

## Quick start

```bash
npx nx run loadweaver-cli-loadweaver:binary
./dist/apps/loadweaver/cli-loadweaver/bin/loadweaver hello
./dist/apps/loadweaver/cli-loadweaver/bin/loadweaver config init-template ./loadweaver.yml
./dist/apps/loadweaver/cli-loadweaver/bin/loadweaver config validate --config ./loadweaver.yml
```

## Documentation

- [Getting started](./getting-started.md)
- [Architecture overview](./architecture/system-overview.md)
- [CLI reference](./cli-reference.md)
- [Configuration](./configuration.md)
- [Workspace state](./workspace.md)
- [System requirements](./deployment/system-requirements.md)
- [Lab guide (3 VMs)](./deployment/lab-guide.md)
- [Production TLS (ACME / DNS)](./deployment/production-tls.md)
22 changes: 22 additions & 0 deletions docs/loadweaver/architecture/system-overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Architecture overview

Loadweaver manages a multi-site cluster where:

- **WireGuard** provides an L3 full mesh (`wg0`) between nodes
- **Docker Swarm** runs services with overlay networks advertised over WireGuard
- **Ceph/CephFS** backs shared storage mounted on every node
- **Traefik** serves ingress from a Swarm stack with shared config/certs on CephFS
- **VIP/keepalived** fronts Traefik for external traffic
- **BIRD (optional)** on hub nodes exchanges routes between sites and remote clusters over WireGuard

See [architecture.mmd](../../libs/domains/loadweaver/shared/feature-cli/docs/architecture.mmd) for the general overview diagram. Focused breakdowns (CLI libraries, network layers, routing, orchestrator sequences) live alongside it under [`feature-cli/docs/`](../../libs/domains/loadweaver/shared/feature-cli/docs/).

## Execution model

The CLI runs from an operator workstation and converges remote nodes over SSH using idempotent commands. **Host bootstrap** installs Docker, WireGuard, keepalived, and cephadm before the stack is configured. Use `--dry-run` to inspect planned operations.

The only prerequisite on the operator machine is SSH access to every node.

## Future extensions

Inter-cluster routing is available via optional `routing` configuration and BIRD on hub nodes. Each cluster keeps its own Swarm, Ceph, and WireGuard mesh; hub nodes peer with remote clusters over eBGP (and optional cross-cluster WireGuard tunnels). See [configuration.md](../configuration.md#advanced-routing-bird) and [inter-cluster routing](./deployment/inter-cluster-routing.md).
Loading
Loading