Repository files navigation

quickstart

quickstart is the Ansible playbook that stands up an Eru cluster on Ubuntu hosts: an etcd cluster for metadata, eru-core as the scheduler, its resource plugins, and any number of nodes registered with core and running eru-agent. One inventory file describes the cluster, one command deploys it, and quickstart.sh collapses the whole thing onto a single machine.

Documentation: projecteru2.github.io/quickstart (source in docs/).

Quick start

One node, on a fresh Ubuntu host, as root:

curl -fsSL https://raw.githubusercontent.com/projecteru2/quickstart/master/quickstart.sh | bash

Several nodes, from any machine with ansible-core installed:

git clone https://github.com/projecteru2/quickstart.git &&cd quickstart
cp inventory.yml.example inventory.yml
$EDITOR inventory.yml # your hosts, and which of them run etcd, core and workloads
make up

The control machine needs root SSH access to every host in the inventory — keys authorized and host keys accepted — before make up; that is plain Ansible, nothing Eru-specific.

Deploying something

eru-cli lands on the core hosts, already pointed at core through ERU. A deploy needs a spec file: it carries the app name and the entrypoints, while the flags carry the placement and the resources.

cat > /tmp/nginx.yaml <<'EOF'appname: nginxentrypoints: web: commands: - nginx - -g - "daemon off;" publish: - "80"EOF
eru-cli workload deploy \
--pod eru --entry web --image nginx:alpine \
--network eru --count 1 --cpu 1 --memory 256M --storage 1G \
/tmp/nginx.yaml

--pod is the node group to deploy on, --entry names an entrypoint from the spec, and --network is the CNI network the playbook configured on every containerd node — pass host instead to share the node's network namespace. --storage is accounted by the resource-storage plugin, which the playbook installs alongside core.

eru-cli pod nodes eru shows what the cluster holds, and eru-cli workload list nginx what is running. verify.sh runs the whole loop — cache the image, deploy, get, exec, logs, stop, start, remove — against a freshly deployed cluster:

./verify.sh # or ./verify.sh <nodename>

What it installs

GroupHost gets
etcdetcd, from the upstream release tarball, as a systemd unit
coreeru-core, the resource-storage and resource-gpu plugins, and eru-cli
node_containerdcontainerd, runc, the CNI plugins, eru-agent, and a node registration
node_processoras and eru-agent; workloads run as transient systemd units
node_cocooneru-agent and a node registration over an existing cocoon install — cocoon itself, per its own docs, and /dev/kvm come first

Core reaches every node over SSH with a key pair the playbook generates for it, so nodes expose no daemon API of their own. A host may belong to etcd, core and one node group at once — the single-node bootstrap does exactly that — but not to both node groups, because one host is one Eru node with one engine.

Related projects

  • core — stateless gRPC resource scheduler
  • agent — per-node daemon reporting node and workload status
  • cli — command line client for the core API
  • resource-extend — external resource plugins (gpu, storage)
  • footstone — container images the project builds with

Development

make check # ansible-playbook --syntax-check against $(INVENTORY)
make lint # ansible-lint over every playbook, role and template
make up # run the playbook; TAGS=etcd,core limits it to those roles
make all # check, then lint

make help lists every target. Both checks run in CI on every push and pull request.

License

This project is licensed under the MIT License. See LICENSE.

About

Ansible playbook that deploys an Eru cluster on Ubuntu: etcd, eru-core, and Docker nodes registered with core and running eru-agent.

Topics

Resources

Stars

30 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

quickstart

quickstart is the Ansible playbook that stands up an Eru cluster on Ubuntu hosts: an etcd cluster for metadata, eru-core as the scheduler, its resource plugins, and any number of nodes registered with core and running eru-agent. One inventory file describes the cluster, one command deploys it, and quickstart.sh collapses the whole thing onto a single machine.

Documentation: projecteru2.github.io/quickstart (source in docs/).

Quick start

One node, on a fresh Ubuntu host, as root:

curl -fsSL https://raw.githubusercontent.com/projecteru2/quickstart/master/quickstart.sh | bash

Several nodes, from any machine with ansible-core installed:

git clone https://github.com/projecteru2/quickstart.git &&cd quickstart
cp inventory.yml.example inventory.yml
$EDITOR inventory.yml # your hosts, and which of them run etcd, core and workloads
make up

The control machine needs root SSH access to every host in the inventory — keys authorized and host keys accepted — before make up; that is plain Ansible, nothing Eru-specific.

Deploying something

eru-cli lands on the core hosts, already pointed at core through ERU. A deploy needs a spec file: it carries the app name and the entrypoints, while the flags carry the placement and the resources.

cat > /tmp/nginx.yaml <<'EOF'appname: nginxentrypoints: web: commands: - nginx - -g - "daemon off;" publish: - "80"EOF
eru-cli workload deploy \
--pod eru --entry web --image nginx:alpine \
--network eru --count 1 --cpu 1 --memory 256M --storage 1G \
/tmp/nginx.yaml

--pod is the node group to deploy on, --entry names an entrypoint from the spec, and --network is the CNI network the playbook configured on every containerd node — pass host instead to share the node's network namespace. --storage is accounted by the resource-storage plugin, which the playbook installs alongside core.

eru-cli pod nodes eru shows what the cluster holds, and eru-cli workload list nginx what is running. verify.sh runs the whole loop — cache the image, deploy, get, exec, logs, stop, start, remove — against a freshly deployed cluster:

./verify.sh # or ./verify.sh <nodename>

What it installs

GroupHost gets
etcdetcd, from the upstream release tarball, as a systemd unit
coreeru-core, the resource-storage and resource-gpu plugins, and eru-cli
node_containerdcontainerd, runc, the CNI plugins, eru-agent, and a node registration
node_processoras and eru-agent; workloads run as transient systemd units
node_cocooneru-agent and a node registration over an existing cocoon install — cocoon itself, per its own docs, and /dev/kvm come first

Core reaches every node over SSH with a key pair the playbook generates for it, so nodes expose no daemon API of their own. A host may belong to etcd, core and one node group at once — the single-node bootstrap does exactly that — but not to both node groups, because one host is one Eru node with one engine.

Related projects

  • core — stateless gRPC resource scheduler
  • agent — per-node daemon reporting node and workload status
  • cli — command line client for the core API
  • resource-extend — external resource plugins (gpu, storage)
  • footstone — container images the project builds with

Development

make check # ansible-playbook --syntax-check against $(INVENTORY)
make lint # ansible-lint over every playbook, role and template
make up # run the playbook; TAGS=etcd,core limits it to those roles
make all # check, then lint

make help lists every target. Both checks run in CI on every push and pull request.

License

This project is licensed under the MIT License. See LICENSE.

About

Ansible playbook that deploys an Eru cluster on Ubuntu: etcd, eru-core, and Docker nodes registered with core and running eru-agent.

Topics

Resources

Stars

30 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

quickstart

quickstart is the Ansible playbook that stands up an Eru cluster on Ubuntu hosts: an etcd cluster for metadata, eru-core as the scheduler, its resource plugins, and any number of nodes registered with core and running eru-agent. One inventory file describes the cluster, one command deploys it, and quickstart.sh collapses the whole thing onto a single machine.

Documentation: projecteru2.github.io/quickstart (source in docs/).

Quick start

One node, on a fresh Ubuntu host, as root:

curl -fsSL https://raw.githubusercontent.com/projecteru2/quickstart/master/quickstart.sh | bash

Several nodes, from any machine with ansible-core installed:

git clone https://github.com/projecteru2/quickstart.git &&cd quickstart
cp inventory.yml.example inventory.yml
$EDITOR inventory.yml # your hosts, and which of them run etcd, core and workloads
make up

The control machine needs root SSH access to every host in the inventory — keys authorized and host keys accepted — before make up; that is plain Ansible, nothing Eru-specific.

Deploying something

eru-cli lands on the core hosts, already pointed at core through ERU. A deploy needs a spec file: it carries the app name and the entrypoints, while the flags carry the placement and the resources.

cat > /tmp/nginx.yaml <<'EOF'appname: nginxentrypoints: web: commands: - nginx - -g - "daemon off;" publish: - "80"EOF
eru-cli workload deploy \
--pod eru --entry web --image nginx:alpine \
--network eru --count 1 --cpu 1 --memory 256M --storage 1G \
/tmp/nginx.yaml

--pod is the node group to deploy on, --entry names an entrypoint from the spec, and --network is the CNI network the playbook configured on every containerd node — pass host instead to share the node's network namespace. --storage is accounted by the resource-storage plugin, which the playbook installs alongside core.

eru-cli pod nodes eru shows what the cluster holds, and eru-cli workload list nginx what is running. verify.sh runs the whole loop — cache the image, deploy, get, exec, logs, stop, start, remove — against a freshly deployed cluster:

./verify.sh # or ./verify.sh <nodename>

What it installs

GroupHost gets
etcdetcd, from the upstream release tarball, as a systemd unit
coreeru-core, the resource-storage and resource-gpu plugins, and eru-cli
node_containerdcontainerd, runc, the CNI plugins, eru-agent, and a node registration
node_processoras and eru-agent; workloads run as transient systemd units
node_cocooneru-agent and a node registration over an existing cocoon install — cocoon itself, per its own docs, and /dev/kvm come first

Core reaches every node over SSH with a key pair the playbook generates for it, so nodes expose no daemon API of their own. A host may belong to etcd, core and one node group at once — the single-node bootstrap does exactly that — but not to both node groups, because one host is one Eru node with one engine.

Related projects

  • core — stateless gRPC resource scheduler
  • agent — per-node daemon reporting node and workload status
  • cli — command line client for the core API
  • resource-extend — external resource plugins (gpu, storage)
  • footstone — container images the project builds with

Development

make check # ansible-playbook --syntax-check against $(INVENTORY)
make lint # ansible-lint over every playbook, role and template
make up # run the playbook; TAGS=etcd,core limits it to those roles
make all # check, then lint

make help lists every target. Both checks run in CI on every push and pull request.

License

This project is licensed under the MIT License. See LICENSE.

About

Ansible playbook that deploys an Eru cluster on Ubuntu: etcd, eru-core, and Docker nodes registered with core and running eru-agent.

Topics

Resources

Stars

30 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

quickstart

quickstart is the Ansible playbook that stands up an Eru cluster on Ubuntu hosts: an etcd cluster for metadata, eru-core as the scheduler, its resource plugins, and any number of nodes registered with core and running eru-agent. One inventory file describes the cluster, one command deploys it, and quickstart.sh collapses the whole thing onto a single machine.

Documentation: projecteru2.github.io/quickstart (source in docs/).

Quick start

One node, on a fresh Ubuntu host, as root:

curl -fsSL https://raw.githubusercontent.com/projecteru2/quickstart/master/quickstart.sh | bash

Several nodes, from any machine with ansible-core installed:

git clone https://github.com/projecteru2/quickstart.git &&cd quickstart
cp inventory.yml.example inventory.yml
$EDITOR inventory.yml # your hosts, and which of them run etcd, core and workloads
make up

The control machine needs root SSH access to every host in the inventory — keys authorized and host keys accepted — before make up; that is plain Ansible, nothing Eru-specific.

Deploying something

eru-cli lands on the core hosts, already pointed at core through ERU. A deploy needs a spec file: it carries the app name and the entrypoints, while the flags carry the placement and the resources.

cat > /tmp/nginx.yaml <<'EOF'appname: nginxentrypoints: web: commands: - nginx - -g - "daemon off;" publish: - "80"EOF
eru-cli workload deploy \
--pod eru --entry web --image nginx:alpine \
--network eru --count 1 --cpu 1 --memory 256M --storage 1G \
/tmp/nginx.yaml

--pod is the node group to deploy on, --entry names an entrypoint from the spec, and --network is the CNI network the playbook configured on every containerd node — pass host instead to share the node's network namespace. --storage is accounted by the resource-storage plugin, which the playbook installs alongside core.

eru-cli pod nodes eru shows what the cluster holds, and eru-cli workload list nginx what is running. verify.sh runs the whole loop — cache the image, deploy, get, exec, logs, stop, start, remove — against a freshly deployed cluster:

./verify.sh # or ./verify.sh <nodename>

What it installs

GroupHost gets
etcdetcd, from the upstream release tarball, as a systemd unit
coreeru-core, the resource-storage and resource-gpu plugins, and eru-cli
node_containerdcontainerd, runc, the CNI plugins, eru-agent, and a node registration
node_processoras and eru-agent; workloads run as transient systemd units
node_cocooneru-agent and a node registration over an existing cocoon install — cocoon itself, per its own docs, and /dev/kvm come first

Core reaches every node over SSH with a key pair the playbook generates for it, so nodes expose no daemon API of their own. A host may belong to etcd, core and one node group at once — the single-node bootstrap does exactly that — but not to both node groups, because one host is one Eru node with one engine.

Related projects

  • core — stateless gRPC resource scheduler
  • agent — per-node daemon reporting node and workload status
  • cli — command line client for the core API
  • resource-extend — external resource plugins (gpu, storage)
  • footstone — container images the project builds with

Development

make check # ansible-playbook --syntax-check against $(INVENTORY)
make lint # ansible-lint over every playbook, role and template
make up # run the playbook; TAGS=etcd,core limits it to those roles
make all # check, then lint

make help lists every target. Both checks run in CI on every push and pull request.

License

This project is licensed under the MIT License. See LICENSE.

About

Ansible playbook that deploys an Eru cluster on Ubuntu: etcd, eru-core, and Docker nodes registered with core and running eru-agent.

Topics

Resources

Stars

30 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

quickstart

quickstart is the Ansible playbook that stands up an Eru cluster on Ubuntu hosts: an etcd cluster for metadata, eru-core as the scheduler, its resource plugins, and any number of nodes registered with core and running eru-agent. One inventory file describes the cluster, one command deploys it, and quickstart.sh collapses the whole thing onto a single machine.

Documentation: projecteru2.github.io/quickstart (source in docs/).

Quick start

One node, on a fresh Ubuntu host, as root:

curl -fsSL https://raw.githubusercontent.com/projecteru2/quickstart/master/quickstart.sh | bash

Several nodes, from any machine with ansible-core installed:

git clone https://github.com/projecteru2/quickstart.git &&cd quickstart
cp inventory.yml.example inventory.yml
$EDITOR inventory.yml # your hosts, and which of them run etcd, core and workloads
make up

The control machine needs root SSH access to every host in the inventory — keys authorized and host keys accepted — before make up; that is plain Ansible, nothing Eru-specific.

Deploying something

eru-cli lands on the core hosts, already pointed at core through ERU. A deploy needs a spec file: it carries the app name and the entrypoints, while the flags carry the placement and the resources.

cat > /tmp/nginx.yaml <<'EOF'appname: nginxentrypoints: web: commands: - nginx - -g - "daemon off;" publish: - "80"EOF
eru-cli workload deploy \
--pod eru --entry web --image nginx:alpine \
--network eru --count 1 --cpu 1 --memory 256M --storage 1G \
/tmp/nginx.yaml

--pod is the node group to deploy on, --entry names an entrypoint from the spec, and --network is the CNI network the playbook configured on every containerd node — pass host instead to share the node's network namespace. --storage is accounted by the resource-storage plugin, which the playbook installs alongside core.

eru-cli pod nodes eru shows what the cluster holds, and eru-cli workload list nginx what is running. verify.sh runs the whole loop — cache the image, deploy, get, exec, logs, stop, start, remove — against a freshly deployed cluster:

./verify.sh # or ./verify.sh <nodename>

What it installs

GroupHost gets
etcdetcd, from the upstream release tarball, as a systemd unit
coreeru-core, the resource-storage and resource-gpu plugins, and eru-cli
node_containerdcontainerd, runc, the CNI plugins, eru-agent, and a node registration
node_processoras and eru-agent; workloads run as transient systemd units
node_cocooneru-agent and a node registration over an existing cocoon install — cocoon itself, per its own docs, and /dev/kvm come first

Core reaches every node over SSH with a key pair the playbook generates for it, so nodes expose no daemon API of their own. A host may belong to etcd, core and one node group at once — the single-node bootstrap does exactly that — but not to both node groups, because one host is one Eru node with one engine.

Related projects

  • core — stateless gRPC resource scheduler
  • agent — per-node daemon reporting node and workload status
  • cli — command line client for the core API
  • resource-extend — external resource plugins (gpu, storage)
  • footstone — container images the project builds with

Development

make check # ansible-playbook --syntax-check against $(INVENTORY)
make lint # ansible-lint over every playbook, role and template
make up # run the playbook; TAGS=etcd,core limits it to those roles
make all # check, then lint

make help lists every target. Both checks run in CI on every push and pull request.

License

This project is licensed under the MIT License. See LICENSE.

About

Ansible playbook that deploys an Eru cluster on Ubuntu: etcd, eru-core, and Docker nodes registered with core and running eru-agent.

Topics

Resources

Stars

30 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

quickstart

quickstart is the Ansible playbook that stands up an Eru cluster on Ubuntu hosts: an etcd cluster for metadata, eru-core as the scheduler, its resource plugins, and any number of nodes registered with core and running eru-agent. One inventory file describes the cluster, one command deploys it, and quickstart.sh collapses the whole thing onto a single machine.

Documentation: projecteru2.github.io/quickstart (source in docs/).

Quick start

One node, on a fresh Ubuntu host, as root:

curl -fsSL https://raw.githubusercontent.com/projecteru2/quickstart/master/quickstart.sh | bash

Several nodes, from any machine with ansible-core installed:

git clone https://github.com/projecteru2/quickstart.git &&cd quickstart
cp inventory.yml.example inventory.yml
$EDITOR inventory.yml # your hosts, and which of them run etcd, core and workloads
make up

The control machine needs root SSH access to every host in the inventory — keys authorized and host keys accepted — before make up; that is plain Ansible, nothing Eru-specific.

Deploying something

eru-cli lands on the core hosts, already pointed at core through ERU. A deploy needs a spec file: it carries the app name and the entrypoints, while the flags carry the placement and the resources.

cat > /tmp/nginx.yaml <<'EOF'appname: nginxentrypoints: web: commands: - nginx - -g - "daemon off;" publish: - "80"EOF
eru-cli workload deploy \
--pod eru --entry web --image nginx:alpine \
--network eru --count 1 --cpu 1 --memory 256M --storage 1G \
/tmp/nginx.yaml

--pod is the node group to deploy on, --entry names an entrypoint from the spec, and --network is the CNI network the playbook configured on every containerd node — pass host instead to share the node's network namespace. --storage is accounted by the resource-storage plugin, which the playbook installs alongside core.

eru-cli pod nodes eru shows what the cluster holds, and eru-cli workload list nginx what is running. verify.sh runs the whole loop — cache the image, deploy, get, exec, logs, stop, start, remove — against a freshly deployed cluster:

./verify.sh # or ./verify.sh <nodename>

What it installs

GroupHost gets
etcdetcd, from the upstream release tarball, as a systemd unit
coreeru-core, the resource-storage and resource-gpu plugins, and eru-cli
node_containerdcontainerd, runc, the CNI plugins, eru-agent, and a node registration
node_processoras and eru-agent; workloads run as transient systemd units
node_cocooneru-agent and a node registration over an existing cocoon install — cocoon itself, per its own docs, and /dev/kvm come first

Core reaches every node over SSH with a key pair the playbook generates for it, so nodes expose no daemon API of their own. A host may belong to etcd, core and one node group at once — the single-node bootstrap does exactly that — but not to both node groups, because one host is one Eru node with one engine.

Related projects

  • core — stateless gRPC resource scheduler
  • agent — per-node daemon reporting node and workload status
  • cli — command line client for the core API
  • resource-extend — external resource plugins (gpu, storage)
  • footstone — container images the project builds with

Development

make check # ansible-playbook --syntax-check against $(INVENTORY)
make lint # ansible-lint over every playbook, role and template
make up # run the playbook; TAGS=etcd,core limits it to those roles
make all # check, then lint

make help lists every target. Both checks run in CI on every push and pull request.

License

This project is licensed under the MIT License. See LICENSE.

About

Ansible playbook that deploys an Eru cluster on Ubuntu: etcd, eru-core, and Docker nodes registered with core and running eru-agent.

Topics

Resources

Stars

30 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

quickstart

quickstart is the Ansible playbook that stands up an Eru cluster on Ubuntu hosts: an etcd cluster for metadata, eru-core as the scheduler, its resource plugins, and any number of nodes registered with core and running eru-agent. One inventory file describes the cluster, one command deploys it, and quickstart.sh collapses the whole thing onto a single machine.

Documentation: projecteru2.github.io/quickstart (source in docs/).

Quick start

One node, on a fresh Ubuntu host, as root:

curl -fsSL https://raw.githubusercontent.com/projecteru2/quickstart/master/quickstart.sh | bash

Several nodes, from any machine with ansible-core installed:

git clone https://github.com/projecteru2/quickstart.git &&cd quickstart
cp inventory.yml.example inventory.yml
$EDITOR inventory.yml # your hosts, and which of them run etcd, core and workloads
make up

The control machine needs root SSH access to every host in the inventory — keys authorized and host keys accepted — before make up; that is plain Ansible, nothing Eru-specific.

Deploying something

eru-cli lands on the core hosts, already pointed at core through ERU. A deploy needs a spec file: it carries the app name and the entrypoints, while the flags carry the placement and the resources.

cat > /tmp/nginx.yaml <<'EOF'appname: nginxentrypoints: web: commands: - nginx - -g - "daemon off;" publish: - "80"EOF
eru-cli workload deploy \
--pod eru --entry web --image nginx:alpine \
--network eru --count 1 --cpu 1 --memory 256M --storage 1G \
/tmp/nginx.yaml

--pod is the node group to deploy on, --entry names an entrypoint from the spec, and --network is the CNI network the playbook configured on every containerd node — pass host instead to share the node's network namespace. --storage is accounted by the resource-storage plugin, which the playbook installs alongside core.

eru-cli pod nodes eru shows what the cluster holds, and eru-cli workload list nginx what is running. verify.sh runs the whole loop — cache the image, deploy, get, exec, logs, stop, start, remove — against a freshly deployed cluster:

./verify.sh # or ./verify.sh <nodename>

What it installs

GroupHost gets
etcdetcd, from the upstream release tarball, as a systemd unit
coreeru-core, the resource-storage and resource-gpu plugins, and eru-cli
node_containerdcontainerd, runc, the CNI plugins, eru-agent, and a node registration
node_processoras and eru-agent; workloads run as transient systemd units
node_cocooneru-agent and a node registration over an existing cocoon install — cocoon itself, per its own docs, and /dev/kvm come first

Core reaches every node over SSH with a key pair the playbook generates for it, so nodes expose no daemon API of their own. A host may belong to etcd, core and one node group at once — the single-node bootstrap does exactly that — but not to both node groups, because one host is one Eru node with one engine.

Related projects

  • core — stateless gRPC resource scheduler
  • agent — per-node daemon reporting node and workload status
  • cli — command line client for the core API
  • resource-extend — external resource plugins (gpu, storage)
  • footstone — container images the project builds with

Development

make check # ansible-playbook --syntax-check against $(INVENTORY)
make lint # ansible-lint over every playbook, role and template
make up # run the playbook; TAGS=etcd,core limits it to those roles
make all # check, then lint

make help lists every target. Both checks run in CI on every push and pull request.

License

This project is licensed under the MIT License. See LICENSE.

About

Ansible playbook that deploys an Eru cluster on Ubuntu: etcd, eru-core, and Docker nodes registered with core and running eru-agent.

Topics

Resources

Stars

30 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

quickstart

quickstart is the Ansible playbook that stands up an Eru cluster on Ubuntu hosts: an etcd cluster for metadata, eru-core as the scheduler, its resource plugins, and any number of nodes registered with core and running eru-agent. One inventory file describes the cluster, one command deploys it, and quickstart.sh collapses the whole thing onto a single machine.

Documentation: projecteru2.github.io/quickstart (source in docs/).

Quick start

One node, on a fresh Ubuntu host, as root:

curl -fsSL https://raw.githubusercontent.com/projecteru2/quickstart/master/quickstart.sh | bash

Several nodes, from any machine with ansible-core installed:

git clone https://github.com/projecteru2/quickstart.git &&cd quickstart
cp inventory.yml.example inventory.yml
$EDITOR inventory.yml # your hosts, and which of them run etcd, core and workloads
make up

The control machine needs root SSH access to every host in the inventory — keys authorized and host keys accepted — before make up; that is plain Ansible, nothing Eru-specific.

Deploying something

eru-cli lands on the core hosts, already pointed at core through ERU. A deploy needs a spec file: it carries the app name and the entrypoints, while the flags carry the placement and the resources.

cat > /tmp/nginx.yaml <<'EOF'appname: nginxentrypoints: web: commands: - nginx - -g - "daemon off;" publish: - "80"EOF
eru-cli workload deploy \
--pod eru --entry web --image nginx:alpine \
--network eru --count 1 --cpu 1 --memory 256M --storage 1G \
/tmp/nginx.yaml

--pod is the node group to deploy on, --entry names an entrypoint from the spec, and --network is the CNI network the playbook configured on every containerd node — pass host instead to share the node's network namespace. --storage is accounted by the resource-storage plugin, which the playbook installs alongside core.

eru-cli pod nodes eru shows what the cluster holds, and eru-cli workload list nginx what is running. verify.sh runs the whole loop — cache the image, deploy, get, exec, logs, stop, start, remove — against a freshly deployed cluster:

./verify.sh # or ./verify.sh <nodename>

What it installs

GroupHost gets
etcdetcd, from the upstream release tarball, as a systemd unit
coreeru-core, the resource-storage and resource-gpu plugins, and eru-cli
node_containerdcontainerd, runc, the CNI plugins, eru-agent, and a node registration
node_processoras and eru-agent; workloads run as transient systemd units
node_cocooneru-agent and a node registration over an existing cocoon install — cocoon itself, per its own docs, and /dev/kvm come first

Core reaches every node over SSH with a key pair the playbook generates for it, so nodes expose no daemon API of their own. A host may belong to etcd, core and one node group at once — the single-node bootstrap does exactly that — but not to both node groups, because one host is one Eru node with one engine.

Related projects

  • core — stateless gRPC resource scheduler
  • agent — per-node daemon reporting node and workload status
  • cli — command line client for the core API
  • resource-extend — external resource plugins (gpu, storage)
  • footstone — container images the project builds with

Development

make check # ansible-playbook --syntax-check against $(INVENTORY)
make lint # ansible-lint over every playbook, role and template
make up # run the playbook; TAGS=etcd,core limits it to those roles
make all # check, then lint

make help lists every target. Both checks run in CI on every push and pull request.

License

This project is licensed under the MIT License. See LICENSE.

About

Ansible playbook that deploys an Eru cluster on Ubuntu: etcd, eru-core, and Docker nodes registered with core and running eru-agent.

Topics

Resources

Stars

30 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages