Distributed (cloud) runs
Generating geometry for a large collection is CPU-bound and embarrassingly parallel across volumes. Two families of console scripts handle this:
Worker scripts — run the engine locally in parallel (no GCP account needed):
metadata-index-worker HOST_ID [options] volume_tree metadata_tree output_tree
metadata-geometry-worker HOST_ID [options] metadata_tree output_tree
metadata-cumulative-worker HOST_ID [options] output_dir
Cloud scripts — dispatch work to GCP (--config defaults to the host’s
cloud/<HOST>/gcp_*_config.yml):
metadata-index-cloud HOST_ID [options] volume_tree metadata_tree output_tree
metadata-geometry-cloud HOST_ID [options] metadata_tree output_tree
metadata-cumulative-cloud HOST_ID [options] output_dir
Both families require the cloud optional dependency group:
pip install -e ".[cloud]"
How it works
The worker and cloud scripts reuse the same engine entry points
(process_index(),
process_tables()) but run them
inside a rms-cloud-tasks Worker.
Worker scripts start a local Worker directly. Cloud scripts shell out to
cloud_tasks run, which provisions GCP instances, generates and delivers a
startup script to each VM, and monitors progress. The startup script
pip-installs rms-metadata-tools from PyPI (or clones a specific git branch
when --debug-branch / $GCP_DEBUG_BRANCH is set) and then runs the
appropriate worker command.
Local parallel runs
Run a worker script just like its plain counterpart, with the additional
--num-simultaneous-tasks option to process volumes in parallel:
metadata-index-worker GO_0xxx "$RMS_VOLUMES/GO_0xxx/" "$RMS_METADATA/GO_0xxx/" \
"$RMS_METADATA_TEST/GO_0xxx/" --num-simultaneous-tasks 12
You can also restrict to specific volumes with --volumes:
metadata-geometry-worker GO_0xxx "$RMS_METADATA/GO_0xxx/" \
"$RMS_METADATA_TEST/GO_0xxx/" --volumes GO_0017 GO_0018
GCP runs
For a GCP run, pass the same path arguments as a local run and add --config.
When --config is omitted, each dispatch command defaults to the conventional
cloud/<HOST>/gcp_<index|geometry|cumulative>_config.yml if that file exists.
The GCP instance startup script is generated automatically from those arguments
at dispatch time, so no personal bucket paths ever appear in committed files.
The recommended workflow is one directory per dispatch, outside the repository:
generate the task file there, then dispatch from it, so the task DB and any
status dumps land beside the task list. --task-file defaults to
./tasks.json, so no flags are needed:
gcloud auth application-default login # if necessary
mkdir -p ~/metadata-runs/2026-08-21-GO-index && cd ~/metadata-runs/2026-08-21-GO-index
# Generate the task file into the run directory (default output: ./tasks.json)
metadata-task-list GO_0xxx "$RMS_VOLUMES_GCP/GO_0xxx/"
# Dispatch to GCP (--config and --task-file use their defaults)
metadata-index-cloud GO_0xxx "$RMS_VOLUMES_GCP/GO_0xxx/" "$RMS_METADATA_GCP/GO_0xxx/" \
"$RMS_METADATA_TEST_GCP/GO_0xxx/" --use-spot
Or pass --volumes directly and let the cloud script generate the task file
automatically:
metadata-index-cloud GO_0xxx "$RMS_VOLUMES_GCP/GO_0xxx/" "$RMS_METADATA_GCP/GO_0xxx/" \
"$RMS_METADATA_TEST_GCP/GO_0xxx/" --use-spot --volumes GO_0022 GO_0016
Both flags can always be given explicitly (taking precedence over the defaults),
e.g. --config my_gcp_config.yml --task-file ./retry_tasks.json.
The gcp_*_config.yml machine/queue configuration files live in
cloud/<HOST>/ at the repository root (not inside the installed package).
The instance startup script is generated at dispatch time and delivered to
cloud_tasks via the config YAML; it is not stored on disk.
Previewing the startup script
To see exactly what startup script would be sent to a GCP instance without
actually dispatching, use --create-startup-file:
metadata-index-cloud GO_0xxx "$RMS_VOLUMES_GCP/GO_0xxx/" "$RMS_METADATA_GCP/GO_0xxx/" \
"$RMS_METADATA_TEST_GCP/GO_0xxx/" --create-startup-file startup.sh
This writes the startup script to startup.sh and exits immediately. The
--config flag is not required when --create-startup-file is used.
Worker options
Worker scripts accept all options of their non-cloud counterpart, plus:
Option |
Description |
|---|---|
|
Path to a task file (JSON). Passed automatically when using
|
|
Number of volumes to process in parallel. |
Cloud options
Cloud scripts accept all options of their non-cloud counterpart, plus the
following. Options in the first group are forwarded to cloud_tasks run;
options in the second group are consumed before dispatch and never reach
cloud_tasks or the worker.
Dispatch options (forwarded to cloud_tasks run):
Option |
Description |
|---|---|
|
GCP configuration YAML. Defaults to the conventional
|
|
Path to a task file (JSON). Defaults to |
|
Request spot (preemptible) GCP instances. |
Cloud-only overrides (consumed before dispatch):
Option |
Description |
|---|---|
|
Write the generated startup script to |
|
Use |
|
Name of the persistent GCP disk to attach as OOPS resources on each VM.
Overrides |
|
GCP service account to use for dispatch. Overrides |
|
Git branch to clone on GCP VMs instead of pip-installing from PyPI.
Overrides |
Environment variables
Cloud-related settings can be provided via environment variables, which are
loaded from a .env file at the repository root at import time (shell
environment takes precedence over .env). The file is git-ignored so it
never contains committed credentials.
Variable |
Description |
|---|---|
|
GCP service account passed to |
|
Name of the persistent disk to attach on each GCP VM for OOPS resources.
Injected as |
|
Path to a custom startup script template to use instead of
|
|
Git branch to clone on GCP VMs. When unset and |
A typical .env file:
# GCP service account to pass to cloud_tasks run (--service-account).
GCP_SERVICE_ACCOUNT=rms-metadata-tools-154@rms-metadata.iam.gserviceaccount.com
# Name of the persistent disk to attach on each GCP VM for OOPS resources.
OOPS_RESOURCES_DISK=standard-oops-resources-central1-a-1
# Custom startup template (leave blank to use the default).
GCP_STARTUP_TEMPLATE=
# Git branch to clone on GCP VMs (leave blank to pip-install from PyPI).
GCP_DEBUG_BRANCH=
The metadata-task-list script
metadata-task-list generates a task file without doing any processing. It
supports two modes:
Scan mode — walk a volume tree and create one task per discovered volume:
metadata-task-list HOST_ID tree [--output FILE]
Argument / option |
Description |
|---|---|
|
Host identifier (e.g. |
|
Path to the top of the volume or metadata tree to scan. |
|
Output JSON task file path, relative to the current directory. Defaults
to |
Explicit mode — list volumes directly (no HOST_ID):
metadata-task-list --volumes VOL [VOL ...] --output FILE
The output file is always a JSON array with one object per volume; see “Task file schema” below.
Task file schema
The task file is JSON: a list of task objects, one per volume. Each object has a
unique task_id and a data payload carrying the volume ID that the worker
passes back to the engine:
[
{
"task_id": "geometry-task-GO_0017",
"data": { "volume_id": "GO_0017" }
},
{
"task_id": "geometry-task-GO_0018",
"data": { "volume_id": "GO_0018" }
}
]
The task_id prefix identifies the stage that produced the file. The worker
reads each entry, invokes the engine for data.volume_id, and reports success
or failure back to rms-cloud-tasks.