Provisioning from the Shell
Table of Contents
Everything the browser's setup journeys do, the shell can do too. This
chapter covers the same ground from the command line, where a complete
system can be set up with three commands — or with one script, run end
to end from a file. It sets out the bootstrap setup, provision
tenant and provision party commands, the supporting commands they
are built from, the script library that ties them together, and two
complete worked examples — the fast Acme Corporation path and the
GLEIF path — showing that scripted provisioning is repeatable: the
same script against a fresh installation always produces the same
system.
1. Overview
The chapter advances the argument that provisioning a complete system from the command line means understanding the client that runs the commands, then each provisioning command in the order it must be run, then the smaller commands they are built from, and finally how to tie them together into a repeatable script — and it proceeds in that order. It begins by establishing the client and the rules it enforces in The shell and provisioning, which explains how the shell speaks to the backend and why provisioning follows a fixed sequence; this is the premise the rest of the chapter builds on. From there it walks the sequence one stage at a time — Setting up the system, then Provisioning a tenant, then Provisioning a party — each command sending one provision request and following the run that request starts. It then opens up the machinery in The supporting commands, the smaller commands a run can be inspected or recovered with, before showing in Scripts how the shell runs those commands unattended from a file. Finally A complete example runs the fast Acme Corporation path from a single shipped script, and A custom example: your own organisation points to the equivalent script for building your own house instead, before the Conclusion draws these steps together.
2. The shell and provisioning
ores.shell is ORE Studio's interactive command-line client. Like
the browser it speaks to the backend services over the message bus, so
anything it does respects the same validation, audit trail, and
permissions. Start it, connect, and type help to see the available
commands; every command described here also explains its own arguments
through the shell's built-in help.
Provisioning from the shell follows the same sequence as the browser's setup journeys — system, then tenant, then party. The session is refreshed by a logout and a login between the stages where the administrator changes, because a session created before a tenant exists does not see it. Each stage is one command: the command sends one provision request, which answers with a workflow instance id, and then follows the run through the same progress read the browser's journey renders. The command holds no sequence of its own beyond the order the two clients share, and the starting point it runs from is a flag naming a registered row rather than a profile the shell knows anything about.
3. Setting up the system
bootstrap setup is the first-run act. It is registered in the
generated bootstrap menu, beside status and
create-initial-admin, because it is what brings the installation to
life. It requires bootstrap mode and no login.
bootstrap setup super_admin Secure-Password-123 super_admin@localhost.com --tenant-admin-password Secure-Password-123 --tenant-code default --tenant-name "Default Tenant" --tenant-hostname localhost --profile empty_operational --param counterparty_size=small logout exit
The administrator's password is the only value the command requires: it offers no default it could invent. It reads the installation's bootstrap answer, creates the system administrator, signs in as it, and accepts the terms of every public source as they stand, printing one line a source. It then sends one provision request for the first tenant and follows the run to its end.
A new system fetches no public rates until each public source's terms
are accepted. The shell does not show the terms' text: running the
command accepts each source's terms as they stand at that moment. The
acceptance is recorded under the administrator's account, with the time
the server records it. To leave the terms for the
administrator to read and accept, add --no-accept-terms; accept them
later on the Public rates screen, or all at once with
provider_terms_operations accept-all.
Tenant code default, name Default Tenant, hostname localhost and
administrator tenant_admin are the tenant defaults; the
administrator's e-mail address defaults to admin@<code>.com.
Override any of them with --tenant-code, --tenant-name,
--tenant-hostname, --tenant-description, --tenant-admin and
--tenant-admin-email. --profile names the starting point (default
empty_operational) and --param name=value supplies one parameter
the starting point declares; the flag is repeatable. --timeout is
how long the command follows the run (default 3600 seconds).
The command refuses to run when you are already logged in or the system is not in bootstrap mode, and on success prints the login for the next stage:
./projects/ores.compass/compass.sh shell << 'EOF' <<shellprov-setup>> EOF
✓ Connected to nats://localhost:42222 ⚠ WARNING: System is in BOOTSTRAP MODE ores-shell> [1/3] Creating initial admin account 'super_admin'... Account created (ID: b88d04ec-ac25-4137-981a-ddefb1d92592). [2/3] Logging in as 'super_admin'... ✓ Login successful! [3/3] Provisioning tenant 'default' from 'empty_operational'... Run started: 7c059b7f-... [1/3] publish_bundle: completed [2/3] import_lei_hierarchy: completed [3/3] provision_party: completed ✓ All 3 step(s) completed. ✓ System provisioned. Tenant 'Default Tenant'. Next: logout, then: login tenant_admin@localhost <password> — the tenant is ready to work in. ores-shell> ✓ Logged out successfully. ores-shell> Bye!
Note the login principal is the username at the tenant's hostname
(tenant_admin@localhost above), not its display name.
4. Provisioning a tenant
provision tenant creates a tenant under the tenant the signed-in
administrator works in. Every tenant is created the same way, the
first included; the only difference from bootstrap setup is that the
administrator and the session already exist. Log in as an
administrator and run:
login super_admin Secure-Password-123 provision tenant --tenant-code example --tenant-name "Example Corp" --tenant-hostname example --tenant-admin-password Secure-Password-123 --profile empty_operational --param counterparty_size=small logout exit
./projects/ores.compass/compass.sh shell << 'EOF' <<shellprov-tenant>> EOF
ores-shell> ✓ Login successful! ores-shell> Provisioning tenant 'example' from 'empty_operational'... Run started: 3a9d2c1e-... [1/3] publish_bundle: completed [2/3] import_lei_hierarchy: completed [3/3] provision_party: completed ✓ All 3 step(s) completed. ✓ Tenant 'Example Corp' provisioned. Next: logout, then: login tenant_admin@example <password> — the tenant is ready to work in. ores-shell> ✓ Logged out successfully. ores-shell> Bye!
The new tenant administrator's password is the only value the command requires. The command prints the login for the new tenant when the run completes.
A starting point ("seed profile") is registered data: a row naming the tenant's type, the ordered steps, and the parameters its form declares. The shell holds no profile of its own, so a new starting point is a row rather than a shell change. Three starting points ship today:
empty_operational(the default) — the production starting point. It publishes the base reference data and the counterparty set, takes a GLEIF root LEI, and creates no test data.gleif_entity— a tenant built around a public registry hierarchy. The root LEI names the parent legal entity whose hierarchy becomes the tenant's parties.acme_demo— the demonstration, the Acme Corporation holding group with its legal entities, staff, books and market data.northwindis a second demonstration tenant, the fictional Northwind Traders. It has one legal entity, nine staff, six portfolios and seven books, and its own report documents. It is lighter thanacme_demo. A deployment uses it to exercise more than one tenant at once.
--profile names the starting point and --param name=value supplies
one parameter it declares, for example --param root_lei=<lei> or
--param counterparty_size=small. The flag is repeatable. The
counterparty set is published once for the tenant. --timeout is how
long the command follows the run (default 3600 seconds).
The request answers with a workflow instance id at once, and the command follows the run through the progress read the browser's journey renders. On failure the run stops on the failing step, and the workflow commands read it by the instance id the command prints.
After the run completes, log out and back in as the new tenant's administrator so the session picks up the now-active tenant.
5. Provisioning a party
provision party runs the party stage against one party of the
signed-in tenant. It publishes the bundles the starting point orders
for a party, activates the party, marks its onboarding complete, and
joins the administrator who asked to it. The party is named by its
identifier or its exact full name; parties list shows the
candidates:
login tenant_admin@barclays_plc Secure-Password-123 provision party "BARCLAYS PLC" logout exit
./projects/ores.compass/compass.sh shell << 'EOF' <<shellprov-party>> EOF
ores-shell> ✓ Login successful! ores-shell> Provisioning party 'BARCLAYS PLC' from 'empty_operational'... Run started: 5f6e1b02-... [1/1] provision_party: completed ✓ All 1 step(s) completed. ✓ Party 'BARCLAYS PLC' provisioned. Next: accounts set-default-party "BARCLAYS PLC" to work in it. ores-shell> ✓ Logged out successfully. ores-shell> Bye!
--profile names the starting point (default empty_operational) and
--timeout is how long the command follows the run (default 3600
seconds). The counterparties a party works against are the tenant's,
published once by the tenant's starting point and not here. The run's
last step marks the party's onboarding complete.
6. The supporting commands
The provision commands send one request each, and the server orchestrates the work, so these smaller commands are not steps the provision commands call in sequence. They remain useful on their own — to inspect the system, to recover when a step fails, or to assemble a custom flow. A failed run names the step it stopped on, and the workflow commands read that run by the instance id the provision command printed.
| Command | Purpose |
|---|---|
dataset_bundles list |
The reference data catalogues available for publication. |
bundles publish <code> [--wait] |
Publish a catalogue; --wait blocks until the backend finishes. |
workflow wait <instance_id> [--timeout <seconds>] [--expect-steps <n>] [--expect-state <state>] |
Follow a run, or assert the terminal state a run that is meant to fail must reach. |
workflow_steps by-workflow-id <id> |
Read a run's steps by the instance id the provision command printed. |
lei countries / lei_entity_summary search-lei-entities <text> [--country_filter <code>] |
Browse the GLEIF registry for a root LEI. |
parties list |
List the parties of the signed-in tenant. |
accounts set-default-party <party-uuid-or-full-name> |
Set the logged-in account's default party. |
report_definition_template list-dq-report-definition-templates [--bundle_code <code>] |
The standard report definitions seeded in a bundle. |
The reads that come from generated units print their response as JSON, where the
hand-written commands they replace printed aligned rows. search-lei-entities
<text> matches a legal name anywhere in it, or an LEI from its start, and states
for each match how many parties importing its hierarchy would create. It
replaces both the old cross-country search and the per-country name filter.
7. Scripts
The shell runs scripts with the load command: one command per line,
# starts a comment, and blank lines are ignored. A script stops at
the first command that fails — so a run that reaches the end has
genuinely succeeded — and reports the failing line and command.
When you want a script to press on regardless, for example while
exploring, pass --continue-on-error:
load my_script.ores load my_script.ores --continue-on-error
ORE Studio ships a small library of provisioning scripts in
projects/ores.shell/scripts/library/provisioning/. Each .ores
script in the library is generated from a recipe under
doc/recipes/shell/provisioning/ that explains, step by step, what the
script does and what it expects of the system — read that file before
running a script for the first time. Treat the shipped scripts as
templates: copy one and adjust the copy rather than editing the
original, which the build regenerates.
8. A complete example
The library's
how_do_i_provision_the_system_with_acme_corporation_holding_group.ores
sets up a complete system from a fresh installation. It runs
bootstrap setup with the demonstration starting point, acme_demo,
which imports the Acme Corporation hierarchy, publishes each party's
data, attaches the staff photographs and starts the market feeds,
server-side in one run. The script then publishes the vendored compute
packages and logs out. It is the quickest way to a fully populated
installation and the recommended starting point for exploring ORE
Studio; see the Acme Corporation chapter for what it produces. It
expects a fresh installation in bootstrap mode, all services running,
and a connected, logged-out session.
load projects/ores.shell/scripts/library/provisioning/how_do_i_provision_the_system_with_acme_corporation_holding_group.ores exit
An error-free run ends with all four legal entities active:
./projects/ores.compass/compass.sh shell << 'EOF' <<shellprov-acme>> EOF
ores-shell> Loading script: .../how_do_i_provision_the_system_with_acme_corporation_holding_group.ores > connect $ORES_NATS_URL > bootstrap setup super_admin Secure-Password-123 super_admin@localhost.com --tenant-admin-password Secure-Password-123 --tenant-code acme_corporation --tenant-name "Acme Corporation" --tenant-hostname acme_corporation --profile acme_demo [1/3] Creating initial admin account 'super_admin'... Account created (ID: ...). [2/3] Logging in as 'super_admin'... ✓ Login successful! [3/3] Provisioning tenant 'acme_corporation' from 'acme_demo'... Run started: ... [1/6] publish_bundle: completed [2/6] import_lei_hierarchy: completed [3/6] provision_party: completed [4/6] load_staff: completed [5/6] attach_photos: completed [6/6] subscribe_market_data: completed ✓ All 6 step(s) completed. ✓ System provisioned. Tenant 'Acme Corporation'. Next: logout, then: login tenant_admin@acme_corporation <password> — the tenant is ready to work in. > compute publish-package ORE ... > compute publish-package ORE ... > logout ✓ Logged out successfully. Script complete: 5 commands executed.
The starting point handles every one of Acme's four legal entities inside its own run — there is no per-party stage to call separately — and the same script against a fresh installation always produces the same system.
Log in — from the shell or the browser — as
tenant_admin@acme_corporation, select one of the four operating
companies, and daily use begins, just as at the end of the previous
chapter.
9. A custom example: your own organisation
Where the Acme Corporation script above is the fast path, building your
own house from scratch — modelling a real organisation — uses the
generic sequence Setting up the system through Provisioning a
party set out earlier: bootstrap setup with the GLEIF starting
point, then provision party for each party that needs its own
reference data. The library's barclays_system_provision.ores is the
worked example of this path — a tenant built around a real GLEIF
hierarchy — and follows the same load=/logout/login shape as the Acme
example above, just with a party stage for the hierarchy's root after
the tenant stage. The library's =tenant_provision.ores covers the
tenant stage on its own, for adding a tenant to a system that is
already set up, and party_provision.ores covers the party stage on
its own.
10. Conclusion
The chapter set out to show that a complete system can be provisioned
from the command line by understanding the client, the provisioning
commands in sequence, the supporting commands beneath them, and the
scripts that tie them together, and it has traced exactly that path.
The shell speaks to the same backend services as the browser, so it
enforces the same validation, audit trail, and permissions, and
provisioning follows the same sequence — system, then tenant, then
party — with the logout and login between stages that refresh the
session's view of the system. bootstrap setup sets up an empty
installation, provision tenant creates every tenant after the first,
and provision party runs the party stage; each sends one provision
request and follows the run through the progress read the browser's
journey renders. A starting point is registered data, so the shell
holds no profile of its own, and the shipped script library showed
both paths executing end to end from a fresh installation: acme_demo
for the fast, fully populated Acme Corporation tenant, and
gleif_entity for building a house around a real GLEIF hierarchy.
Because the same script against the same starting point always
produces the same system, scripted provisioning is the natural tool
for development environments, testing, and automation — everything the
browser's setup journeys do, reproducibly and without the browser.