provisioning/docs/book/architecture/orchestrator_info.html
Jesús Pérez 44648e3206
chore: complete nickel migration and consolidate legacy configs
- Remove KCL ecosystem (~220 files deleted)
- Migrate all infrastructure to Nickel schema system
- Consolidate documentation: legacy docs → provisioning/docs/src/
- Add CI/CD workflows (.github/) and Rust build config (.cargo/)
- Update core system for Nickel schema parsing
- Update README.md and CHANGES.md for v5.0.0 release
- Fix pre-commit hooks: end-of-file, trailing-whitespace
- Breaking changes: KCL workspaces require migration
- Migration bridge available in docs/src/development/
2026-01-08 09:55:37 +00:00

341 lines
16 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE HTML>
<html lang="en" class="ayu sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Orchestrator Info - Provisioning Platform Documentation</title>
<!-- Custom HTML head -->
<meta name="description" content="Complete documentation for the Provisioning Platform - Infrastructure automation with Nushell, KCL, and Rust">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" id="highlight-css" href="../highlight.css">
<link rel="stylesheet" id="tomorrow-night-css" href="../tomorrow-night.css">
<link rel="stylesheet" id="ayu-highlight-css" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<!-- Provide site root and default themes to javascript -->
<script>
const path_to_root = "../";
const default_light_theme = "ayu";
const default_dark_theme = "navy";
</script>
<!-- Start loading toc.js asap -->
<script src="../toc.js"></script>
</head>
<body>
<div id="mdbook-help-container">
<div id="mdbook-help-popup">
<h2 class="mdbook-help-title">Keyboard shortcuts</h2>
<div>
<p>Press <kbd></kbd> or <kbd></kbd> to navigate between chapters</p>
<p>Press <kbd>S</kbd> or <kbd>/</kbd> to search in the book</p>
<p>Press <kbd>?</kbd> to show this help</p>
<p>Press <kbd>Esc</kbd> to hide this help</p>
</div>
</div>
</div>
<div id="body-container">
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
let theme = localStorage.getItem('mdbook-theme');
let sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? default_dark_theme : default_light_theme;
let theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
const html = document.documentElement;
html.classList.remove('ayu')
html.classList.add(theme);
html.classList.add("js");
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
let sidebar = null;
const sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<!-- populated by js -->
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
<noscript>
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
</noscript>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="default_theme">Auto</button></li>
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search (`/`)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="/ s" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Provisioning Platform Documentation</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/provisioning/provisioning-platform" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://github.com/provisioning/provisioning-platform/edit/main/provisioning/docs/src/architecture/orchestrator_info.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<p>Execution Complete</p>
<p>Perfect question! Let me explain clearly:</p>
<p>The Orchestrator IS USED and IS CRITICAL</p>
<p>That code example was misleading. Heres the real architecture:</p>
<p>How It Actually Works</p>
<p>┌──────────────────────────────────────────────────┐
│ User runs: provisioning server create orchestrated
└───────────────────┬──────────────────────────────┘
┌───────────────────────┐
│ Nushell CLI │
│ (provisioning) │
└───────────┬───────────┘
↓ HTTP POST
┌───────────────────────────────┐
│ Rust Orchestrator Daemon │
│ (provisioning-orchestrator) │
│ │
│ • Task Queue │
│ • Workflow Engine │
│ • Dependency Resolution │
│ • Parallel Execution │
└───────────┬───────────────────┘
↓ spawns subprocess
┌───────────────────────────────┐
│ Nushell Business Logic │
│ nu -c “use servers/create.nu”│
│ │
│ Executes actual provider │
│ API calls, configuration │
└───────────────────────────────┘
The Flow in Detail</p>
<ol>
<li>User Command:</li>
</ol>
<p>provisioning server create wuji orchestrated
2. Nushell CLI submits to orchestrator:</p>
<h1 id="cli-code"><a class="header" href="#cli-code">CLI code</a></h1>
<p>http post <a href="http://localhost:9090/workflows/servers/create">http://localhost:9090/workflows/servers/create</a> {
infra: “wuji”
params: {…}
}</p>
<h1 id="returns-workflow_id--abc-123"><a class="header" href="#returns-workflow_id--abc-123">Returns: workflow_id = “abc-123”</a></h1>
<ol>
<li>Orchestrator receives and queues:</li>
</ol>
<p>// Orchestrator receives HTTP request
async fn create_server_workflow(request) {
let task = Task::new(TaskType::ServerCreate, request);
task_queue.enqueue(task).await; // Queue for execution
return workflow_id; // Return immediately
}
4. Orchestrator executes via Nushell subprocess:</p>
<p>// Orchestrator spawns Nushell to run business logic
async fn execute_task(task: Task) {
let output = Command::new(“nu”)
.arg(“-c”)
.arg(“use /usr/local/lib/provisioning/servers/create.nu; create-server wuji”)
.output()
.await?;</p>
<pre><code>// Orchestrator manages: retry, checkpointing, monitoring
</code></pre>
<p>}
5. Nushell executes the actual work:</p>
<h1 id="serverscreatenu"><a class="header" href="#serverscreatenu">servers/create.nu</a></h1>
<p>export def create-server [name: string] {
# This is the business logic
# Calls UpCloud API, creates server, etc.
let provider = (load-provider)
$provider | create-vm $name
}
Why This Architecture?</p>
<p>Problem It Solves</p>
<p>Without Orchestrator (Old Way):</p>
<p>provisioning → template.nu → cluster.nu → taskserv.nu → provider.nu
(Deep call stack = crashes!)
With Orchestrator (Current):</p>
<p>provisioning → Orchestrator → spawns fresh Nushell subprocess for each task
(No deep nesting, parallel execution, recovery)
What Orchestrator Provides</p>
<p>Task Queue - Reliable execution even if system crashes
Parallel Execution - Run 10 tasks at once (Rust async)
Workflow Engine - Handle complex dependencies
Checkpointing - Resume from failure
Monitoring - Real-time progress tracking
What Nushell Provides</p>
<p>Business Logic - Provider integrations, config generation
Flexibility - Easy to modify without recompiling
Readability - Shell-like syntax for infrastructure ops
Multi-Repo Impact: NONE on Integration</p>
<p>In Monorepo:</p>
<p>provisioning/
├── core/nulib/ # Nushell code
└── platform/orchestrator/ # Rust code
In Multi-Repo:</p>
<p>provisioning-core/ # Separate repo, installs to /usr/local/lib/provisioning
provisioning-platform/ # Separate repo, installs to /usr/local/bin/provisioning-orchestrator
Integration is the same:</p>
<p>Orchestrator calls: nu -c “use /usr/local/lib/provisioning/servers/create.nu”
Nushell calls: http post <a href="http://localhost:9090/workflows/">http://localhost:9090/workflows/</a>
No code dependency, just runtime coordination!</p>
<p>The Orchestrator IS Essential</p>
<p>The orchestrator:</p>
<p>✅ IS USED for all complex operations
✅ IS CRITICAL for workflow system (v3.0)
✅ IS REQUIRED for batch operations (v3.1)
✅ SOLVES deep call stack issues
✅ PROVIDES performance and reliability
That misleading code example showed how Platform doesnt link to Core code, but it absolutely uses the orchestrator for coordination.</p>
<p>Does this clear it up? The orchestrator is the performance and reliability layer that makes the whole system work!</p>
<p>Cost: $0.1565 USD
Duration: 137.69s
Turns: 40
Total tokens: 7466(7 in, 7459 out)</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../architecture/nickel-executable-examples.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../architecture/orchestrator-auth-integration.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../architecture/nickel-executable-examples.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../architecture/orchestrator-auth-integration.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js"></script>
<script src="../mark.min.js"></script>
<script src="../searcher.js"></script>
<script src="../clipboard.min.js"></script>
<script src="../highlight.js"></script>
<script src="../book.js"></script>
<!-- Custom JS scripts -->
</div>
</body>
</html>