openvibers/openvibe.run Commits

Route compute placement through OpenVibe Link (#221)

OP OpenVibers committed 4 days ago · 0475167186 · 7 files, +23 −13

Changes

ddiff --git a/docs/compute-broker.md b/docs/compute-broker.md
iindex 412c653..56d8ec0 100644
---- a/docs/compute-broker.md
++++ b/docs/compute-broker.md
@@@ -83,14 +83,14 @@ the pool and RAM inventory. The image's enrollment mechanism is an operator prer
For workers without this naming integration, put the machine id in trusted inventory and bind it
with `POST /api/v1/compute/rentals/:id/bind`, JSON `{ "machine": "dev_…" }`, as the operator with
--an Origin matching Run. Automatic secure enrollment itself is not implemented here; do not bake reusable Node credentials into an image. Unbound rentals
++an Origin matching Run. Automatic secure enrollment itself is not implemented here; do not bake reusable Link credentials into an image. Unbound rentals
count as starting capacity and are deleted at their deadline; never regarded as usable desktops.
Ordinary scale-down marks a host draining, excludes it from placement, waits for zero sessions,
then requests deletion. At the runtime/budget limit, Run ends sessions before release. Unknown
host observations never count as zero occupancy. Each rental's stop deadline survives restart.
Desktop sizing is available, but the current released Bot session API creates browser desks only;
--full Linux desktop execution still needs the Computer/Node runtime work and security review.
++full Linux desktop execution still needs the Computer/Link runtime work and security review.
Checks: `npm test -- compute sessions dispatch`; the full suite is `OV_ALLOW_SUITE=1 npm test`.
The SDK dependency is pinned to the reviewed job commit until its PR is merged and released;
ddiff --git a/docs/link-egress.md b/docs/link-egress.md
iindex f2497d7..71d7712 100644
---- a/docs/link-egress.md
++++ b/docs/link-egress.md
@@@ -5,15 +5,15 @@ chooses an online device owned by that same person, or returns the saved offline
the session waiting; a Network failure never silently selects a direct route. Personal-machine desks keep their
existing path.
--The cloud Node reads the decision assigned to its own machine and desk, then starts the browser behind a local
--proxy in the desk's isolated network. Session credentials stay in the Node proxy process. Run stores only the
++The cloud Link reads the decision assigned to its own machine and desk, then starts the browser behind a local
++proxy in the desk's isolated network. Session credentials stay in the Link proxy process. Run stores only the
display label, "Going out through: …", in `run_sessions.egress_label` and exposes it in placement reasons.
Each desk check renews authorization for two minutes. Ending the desk revokes it before asking Bot to stop;
if Network is unavailable, Bot still receives the stop and the credential expires without renewal. Link checks
open streams every five seconds. Session credentials are neither public API fields nor events nor logs.
--Deploy Network #702 and Connect #76, then the updated Node and computer plugin on cloud hosts and home devices,
++Deploy Network #702 and Connect #76, then the updated Link and computer plugin on cloud hosts and home devices,
before this Run integration. This is the common Run browser-desk path used by cloud session callers. Cloud
products which do not yet create a Run session must adopt that path to inherit its owner and browsing policy.
Migration 0016 is expand-only and reserves 0015 for the open blind-fill PR; its files are untouched.
ddiff --git a/server/api/auth.js b/server/api/auth.js
iindex 6819cde..670a45f 100644
---- a/server/api/auth.js
++++ b/server/api/auth.js
@@@ -9,7 +9,7 @@
* { kind: 'anonymous' }
*
* A request that presents a token is judged on that token alone: a bad one is refused, never downgraded.
-- * A node principal (nod_…) is not a Run principal and is refused like any other non-service token.
++ * A node principal (lnk_…) is not a Run principal and is refused like any other non-service token.
*
* The project a job belongs to comes from the token's own project_id claim (a developer app or agent
* token names one), never from the request body or a query: the requester and the billed project are
ddiff --git a/server/web/discovery.js b/server/web/discovery.js
iindex 156212a..5670413 100644
---- a/server/web/discovery.js
++++ b/server/web/discovery.js
@@@ -8,7 +8,7 @@ const home = require('./home');
const MAX_BYTES = 512 * 1024;
const REPO = 'https://github.com/OpenVibers/OpenVibe.Run';
--const NODE_REPO = 'https://github.com/OpenVibers/OpenVibe.Node';
++const NODE_REPO = 'https://github.com/OpenVibers/OpenVibe.Link';
// The public pages, in the order the sitemap lists them.
const PAGES = ['/', '/updates', '/terms', '/privacy', '/dmca'];
ddiff --git a/server/web/home.js b/server/web/home.js
iindex 1215edd..aedf747 100644
---- a/server/web/home.js
++++ b/server/web/home.js
@@@ -61,7 +61,7 @@ echo "hello from job $OPENVIBE_JOB_ID: $args"
printf '{"ok":true}' >&3
EOF
sudo chmod 755 /opt/fn/hello/run
--# Add it to "worker" → "functions" in /etc/openvibe-node/config.json, then: sudo systemctl restart openvibe-node
++# Add it to "worker" → "functions" in /etc/openvibe-link/config.json, then: sudo systemctl restart openvibe-link
# {"name": "hello", "version": "1.0.0", "command": ["/opt/fn/hello/run"]}`;
const SUBMIT_EXAMPLE = `curl -X POST https://openvibe.run/api/v1/jobs \\
@@@ -159,7 +159,7 @@ function body() {
label: 'How a job runs',
center: { title: 'Your node', sub: 'runs the job' },
inner: [
-- { icon: 'ov:plug', label: 'Pair', href: 'https://openvibe.bot/machines' },
++ { icon: 'ov:plug', label: 'Pair', href: 'https://openvibe.link/machines' },
{ icon: 'ov:code', label: 'Submit', href: '#api' },
{ icon: 'ov:shield', label: 'Sandbox', href: '#how' },
{ icon: 'ov:history', label: 'Stream', href: '#how' },
@@@ -176,14 +176,14 @@ function body() {
accent: 'or on a node that can.',
lede: 'Pair a computer once and the jobs you start run there, on your hardware, with their output streamed back to you. '
+ 'Or send a job to one API with your project\'s token: Run picks a node that offers the runtime it asks for and meters it per second.',
-- actions: [{ label: 'Pair your machine', href: 'https://openvibe.bot/machines', primary: true }, { label: 'Try it from OpenVibe.Codes', href: 'https://openvibe.codes/run' }, { label: 'The API', href: '#api' }],
++ actions: [{ label: 'Pair your machine', href: 'https://openvibe.link/machines', primary: true }, { label: 'Try it from OpenVibe.Codes', href: 'https://openvibe.codes/run' }, { label: 'The API', href: '#api' }],
note: 'Alpha. A job runs on nodes paired with OpenVibe (the OpenVibe Link); with none online for its class it waits, then expires.',
}) + showcase.steps({
id: 'machine',
title: 'Your machine, your jobs',
lede: 'A computer you pair runs only the jobs you start: placement matches its owner before anything else.',
items: [
-- { title: 'Pair it', href: 'https://openvibe.bot/machines', text: 'On openvibe.bot/machines, copy the one-line install command and run it on the computer. It joins as a worker under your account.' },
++ { title: 'Pair it', href: 'https://openvibe.link/machines', text: 'On openvibe.link/machines, copy the one-line install command and run it on the computer. It joins as a worker under your account.' },
{ title: 'Start a job', href: 'https://openvibe.codes/run', text: 'OpenVibe.Codes\' "Run on your machine" sends a coding task there, or your own code submits one through the API.' },
{ title: 'Watch it run', text: 'The job\'s event stream shows each state change and the machine\'s output as it is written.' },
{ title: 'Keep the record', text: 'Every job ends succeeded, failed, cancelled or expired, with its timings, its exit and the seconds it ran.' },
@@@ -235,7 +235,7 @@ function body() {
+ showcase.cta({
title: 'Open source',
text: 'Run is AGPL-3.0, and so is the OpenVibe Link that turns a computer into a worker.',
-- actions: [{ label: 'OpenVibers/OpenVibe.Run', href: 'https://github.com/OpenVibers/OpenVibe.Run' }, { label: 'The OpenVibe Link', href: 'https://github.com/OpenVibers/OpenVibe.Node' }],
++ actions: [{ label: 'OpenVibers/OpenVibe.Run', href: 'https://github.com/OpenVibers/OpenVibe.Run' }, { label: 'The OpenVibe Link', href: 'https://github.com/OpenVibers/OpenVibe.Link' }],
});
}
ddiff --git a/test/link-brand.test.js b/test/link-brand.test.js
nnew file mode 100644
iindex 0000000..eaa904f
---- /dev/null
++++ b/test/link-brand.test.js
@@@ -0,0 +1,10 @@
++'use strict';
++const assert = require('node:assert/strict');
++const { spawnSync } = require('node:child_process');
++const path = require('node:path');
++const root = path.resolve(__dirname, '..');
++const oldName = ['OpenVibe[ .-]No' + 'de', 'openvibe-' + 'node', 'no' + 'd_', 'node[.]openvibe[.]network', 'node:lnk_', 'openvibe[.](bot|my|network)/mach' + 'ines'].join('|');
++const result = spawnSync('git', ['grep', '-n', '-I', '-i', '-E', oldName, '--', '.', ':!migrations/**', ':!test/link-brand.test.js'], { cwd: root, encoding: 'utf8' });
++assert.ok(result.status === 0 || result.status === 1, result.stderr || 'git grep failed');
++assert.equal(result.status, 1, `Old Link brand or principal returned:\n${(result.stdout || '').split('\n').slice(0, 10).join('\n')}`);
++console.log(' ok old Link brand and principal IDs are absent');
ddiff --git a/test/site.test.js b/test/site.test.js
iindex b5fd81b..c35fea3 100644
---- a/test/site.test.js
++++ b/test/site.test.js
@@@ -14,7 +14,7 @@ const { boot, check, done } = require('./helpers/app');
assert.strictEqual(r.status, 200);
assert.match(r.headers.get('content-type'), /text\/html/);
assert.match(r.text, /<title>OpenVibe\.Run: run jobs on your own machine/);
-- assert.ok(r.text.includes('href="https://openvibe.bot/machines"'), 'it leads with pairing your own machine');
++ assert.ok(r.text.includes('href="https://openvibe.link/machines"'), 'it leads with pairing your own machine');
assert.match(r.text, /<th scope="row">browser<\/th>[\s\S]*?Built, not switched on yet/, 'the class table says what works today');
const faq = [...r.text.matchAll(/<script type="application\/ld\+json">([\s\S]*?)<\/script>/g)].map((m) => JSON.parse(m[1])).find((j) => j['@type'] === 'FAQPage');
assert.ok(faq && faq.mainEntity.length >= 4, 'the catalog\'s questions as FAQPage data');