Your First Request
A minimal end-to-end example against a running service
This page walks you through making your first successful request to Trilio Share Protection for OpenStack (Abacá) on a running RHOSO 18 control plane. You will authenticate with Keystone, list available backup targets, create a protection policy against a Manila share, request an on-demand backup, and confirm the resulting job reaches the available state. By the end you will have verified that the API, conductor, and worker fleet are all reachable and functioning correctly — giving you confidence that the service is ready for production use.
Before you begin, confirm the following are in place:
- Abacá control plane deployed —
abaca-apiandabaca-conductorpods are running in theabacanamespace on RHOSO 18. Verify with:oc -n abaca get pods -l app.kubernetes.io/part-of=abaca - At least one worker VM registered — the conductor must show at least one worker in
activestate. Check with the CLI (see Usage) or the API. python-abacaclientinstalled — theopenstack share protectionCLI commands come from thepython-abacaclientpackage, which is layered into the operator's environment as part of the RHOSO deployment. Confirm it is available:openstack share protection --help- Valid
clouds.yamlor sourcedopenrc— you need a Keystone token-capable credential for the tenant project you want to protect. The examples below use a named cloudmy-tenant; substitute your own cloud name or exported environment variables. - An existing Manila share — you need the UUID of a Manila share in the tenant project. Retrieve it with:
openstack share list - A registered backup target — a
BackupTarget(an enrolled S3 bucket) must already exist for your Domain. If none exists yet, see Register a Domain and provision backup targets before continuing. - Keystone trusts enabled — required for Abacá to act on your behalf when mounting shares and accessing Barbican secrets. This is a Keystone server-side setting; confirm with your operator if uncertain.
- OpenStack CLI (
openstack) — version compatible with RHOSO 18 (Keystone 2023.1 or later).
The openstack share protection subcommands are provided by python-abacaclient, which is installed as part of the RHOSO 18 Abacá deployment — specifically by deploy/rhoso/08-dashboard.sh for Horizon, and layered into operator tooling by the deployment scripts. You do not install it separately from a package index in a production RHOSO environment.
If you are setting up a local workstation to drive a running RHOSO 18 cluster, install the client package into a Python 3.11+ virtual environment:
-
Create and activate a virtual environment:
python3 -m venv ~/.venv/abaca source ~/.venv/abaca/bin/activate -
Install the OpenStack client and the Abacá plugin (the Abacá plugin distribution is
python-abacaclient):pip install python-openstackclient python-abacaclientNote: In the RHOSO deployment the
python-abacaclientpackage is installed by the deployment scripts into the appropriate environment — do not install it separately on the control plane pods. -
Verify the plugin is loaded:
openstack share protection --helpYou should see a list of
share protectionsubcommands includingtarget,policy,backup,restore,job, andusage. -
Configure your cloud credentials. Create or update
~/.config/openstack/clouds.yamlwith an entry for your tenant:clouds: my-tenant: auth: auth_url: https://keystone.example.com:5000 username: myuser password: mypassword project_name: myproject user_domain_name: Default project_domain_name: Default region_name: RegionOne interface: publicReplace values with those appropriate for your cluster. Abacá registers in the Keystone service catalog under the type
share-protection, so the client discovers the endpoint automatically — no manual URL configuration is required.
Abacá's behavior is controlled by an oslo.config INI file (abaca.conf). On RHOSO 18 this file is rendered into secret/abaca-config-data in the abaca namespace by deploy/rhoso/06-config.sh and mounted read-only into the abaca-api and abaca-conductor pods.
The options most relevant to your first request are listed below. You do not need to change these to follow this guide, but understanding them helps you interpret API behavior.
[api] — REST API server
| Option | Type | Default | Effect |
|---|---|---|---|
bind_host | string | 0.0.0.0 | Interface the API server listens on. |
bind_port | integer | 9797 | TCP port for the API. The Keystone catalog endpoint points here via the OpenShift Route. |
noauth | boolean | false | Disables Keystone token validation. Never set true in production. |
max_limit | integer | 1000 | Maximum number of items returnable in a single list response. |
default_limit | integer | 100 | Default page size when the caller omits ?limit. |
[conductor] — Orchestration and scheduling
| Option | Type | Default | Effect |
|---|---|---|---|
scheduler_interval | integer | 60 | How often (seconds) the conductor checks policies for due backups. |
reconciliation_interval | integer | 300 | How often (seconds) the reconciliation sweep runs to recover stuck jobs. |
worker_heartbeat_deadline_seconds | integer | 60 | A worker is considered dead if no heartbeat is received within this window. |
min_workers | integer | 1 | Minimum number of active worker VMs the conductor will maintain. |
worker_boot_os_cloud | string | abaca-service | Named cloud (from clouds.yaml) used by the conductor to boot worker VMs. |
worker_boot_image | string | abaca-worker-0.23.1 | Glance image name used when booting new worker VMs. |
worker_boot_flavor | string | m1.small | Nova flavor for worker VMs. |
[kopia] — Backup engine
| Option | Type | Default | Effect |
|---|---|---|---|
binary | string | kopia | Path to the Kopia binary inside the worker VM. |
require_fips_profile | boolean | true | Requires repositories to use the FIPS-approved cryptographic profile (AES-256-GCM-HMAC-SHA256). Set false only in non-regulated development environments. |
subprocess_timeout | integer | 3600 | Maximum seconds a single Kopia subprocess may run before the agent kills it. |
executor | string | (required) | How Kopia is invoked. On RHOSO 18 use http (leased-command transport via the worker agent). |
[worker] — Worker agent settings (on worker VMs)
| Option | Type | Default | Effect |
|---|---|---|---|
capacity_slots | integer | (required) | Maximum concurrent jobs this worker VM will accept. The fleet picker skips workers at capacity. |
mount_base | string | /var/lib/abaca/mnt | Directory under which Manila shares are mounted during backup. |
command_timeout_seconds | integer | 300 | Maximum time the agent waits for a command to be acknowledged. |
listener_port | integer | 9798 | Port the worker agent listens on for inbound conductor connections. |
[DEFAULT] — Service discovery
| Option | Type | Default | Effect |
|---|---|---|---|
catalog_type | string | share-protection | Keystone service catalog type used to discover the Abacá endpoint. |
endpoint_type | string | publicURL | Endpoint interface selected from the catalog. Valid values: publicURL, internalURL, adminURL. |
All examples below use the openstack share protection CLI. The same operations are available via the REST API at /v1 and via the Python SDK (abacaclient.client.Client). Three ways to authenticate are shown — pick whichever matches your workflow.
Authenticate
Via named cloud (recommended):
export OS_CLOUD=my-tenant
Via sourced openrc:
source ~/my-tenant.openrc
Via SDK:
from abacaclient.client import Client
client = Client("https://share-protection.example.com", token="<keystone-token>")
1. Confirm the service is reachable
List backup targets visible to your project. An empty list is fine — it means no targets have been registered yet, but it confirms the API answered:
openstack share protection target list
2. View the backup target you will use
A Domain owner must have already enrolled an S3 bucket as a BackupTarget. Find its ID:
openstack share protection target list
openstack share protection target show <target-id>
Note the id field — you will use it when creating a policy.
3. Create a protection policy
A policy binds a Manila share to a backup target, defines a backup schedule, and sets a retention window. The schedule is a standard cron expression (UTC):
openstack share protection policy create daily-policy \
--target <target-id> \
--schedule "0 2 * * *" \
--retention 7
This creates a policy that runs daily at 02:00 UTC and keeps seven recovery points. Note the returned id — you will reference it when requesting an on-demand backup.
4. Request an on-demand backup
Do not wait for the scheduler — trigger a backup immediately:
openstack share protection backup create <share-id> --target <target-id>
This returns a job-id. The job progresses through the state machine: queued → provisioning_network → provisioning_source → connecting_repository → transferring → finalizing → releasing → available.
5. Monitor the job
Poll the job until it reaches a terminal state:
openstack share protection job show <job-id>
List all recent jobs for your project:
openstack share protection job list
6. Restore a share from backup
Once a backup reaches available, you can restore it to an existing share:
openstack share protection restore create <backup-id> --target-share <share-id>
To restore only a sub-path or perform an in-place restore:
openstack share protection restore create <backup-id> \
--in-place --force --sub-path /data/reports
7. Check usage and fleet health (operators)
# Your project's backup usage summary
openstack share protection usage show
# Active worker VMs (operator)
openstack share protection worker list
# Coverage status across shares (operator)
openstack share protection coverage list
Example 1 — Verify the API answers and list targets
export OS_CLOUD=my-tenant
openstack share protection target list
Expected output (no targets yet):
+----+------+--------+-------+
| id | name | status | type |
+----+------+--------+-------+
+----+------+--------+-------+
An empty table with exit code 0 confirms the service catalog lookup succeeded, the token was accepted by Keystone, and the abaca-api pod responded.
Example 2 — Show a registered target
openstack share protection target show d3f1a2b0-7c4e-4a1d-9f88-000000000001
Expected output:
+------------------+----------------------------------------------+
| Field | Value |
+------------------+----------------------------------------------+
| id | d3f1a2b0-7c4e-4a1d-9f88-000000000001 |
| name | primary |
| status | available |
| type | s3 |
| created_at | 2024-11-01T09:00:00Z |
+------------------+----------------------------------------------+
A status of available means the enrollment job completed successfully — the S3 bucket passed preflight conformance checks, a Kopia repository was initialized, and the encryption key is stored in Barbican.
Example 3 — Create a daily backup policy
openstack share protection policy create daily-policy \
--target d3f1a2b0-7c4e-4a1d-9f88-000000000001 \
--schedule "0 2 * * *" \
--retention 7
Expected output:
+------------+----------------------------------------------+
| Field | Value |
+------------+----------------------------------------------+
| id | a1b2c3d4-0000-0000-0000-000000000010 |
| name | daily-policy |
| schedule | 0 2 * * * |
| retention | 7 |
| target_id | d3f1a2b0-7c4e-4a1d-9f88-000000000001 |
| created_at | 2024-11-01T09:05:00Z |
+------------+----------------------------------------------+
Example 4 — Request an on-demand backup and watch the job
# Trigger the backup
openstack share protection backup create b0000000-0000-0000-0000-000000000042 \
--target d3f1a2b0-7c4e-4a1d-9f88-000000000001
Expected output (immediately after):
+----------+----------------------------------------------+
| Field | Value |
+----------+----------------------------------------------+
| id | e5f6a7b8-0000-0000-0000-000000000099 |
| share_id | b0000000-0000-0000-0000-000000000042 |
| status | queued |
| job_id | c9d0e1f2-0000-0000-0000-000000000200 |
+----------+----------------------------------------------+
# Poll until the job is terminal
openstack share protection job show c9d0e1f2-0000-0000-0000-000000000200
Expected output after successful completion:
+-------------------+----------------------------------------------+
| Field | Value |
+-------------------+----------------------------------------------+
| id | c9d0e1f2-0000-0000-0000-000000000200 |
| type | backup |
| state | available |
| worker_id | w1111111-0000-0000-0000-000000000001 |
| started_at | 2024-11-01T09:10:05Z |
| completed_at | 2024-11-01T09:12:47Z |
| error_category | |
+-------------------+----------------------------------------------+
A state of available means Kopia completed the snapshot, the backup catalog was updated in Abacá's database, and the worker VM released its resources. The backup data is now encrypted and stored in your S3 bucket.
Example 5 — Same operations via the Python SDK
from abacaclient.client import Client
import keystoneauth1.session
# Obtain a token from your Keystone session (omitted for brevity)
token = "<keystone-token>"
endpoint = "https://share-protection.example.com"
client = Client(endpoint, token=token)
# List targets
targets = client.target_list()
print(targets)
# Trigger a backup
backup = client.backup_create(
share_id="b0000000-0000-0000-0000-000000000042",
target_id="d3f1a2b0-7c4e-4a1d-9f88-000000000001",
)
print(f"Job ID: {backup['job_id']}")
Non-2xx responses raise abacaclient.exceptions.AbacaClientError, which carries status, code, title, detail, and category (either tenant_action_required or operator_action_required).
openstack share protection commands not found
Symptom: Running openstack share protection target list returns 'share' is not an openstack command.
Cause: The python-abacaclient package is not installed in the Python environment driving the openstack CLI, or the plugin is not being discovered.
Fix:
- Confirm you are in the correct virtual environment:
which openstack. - Install the package into that environment (see Installation).
- Verify discovery:
openstack --versionshould list thepython-abacaclientplugin.
Authentication fails with 401 Unauthorized
Symptom: Every openstack share protection command returns HTTP 401.
Cause: Your Keystone credentials are expired, the wrong project scope is set, or Abacá's service entry is missing from the catalog.
Fix:
- Re-source your openrc or refresh the token in
clouds.yaml. - Confirm the service catalog entry exists:
openstack catalog show share-protection. - If the catalog entry is missing, the operator must rerun
deploy/rhoso/02-catalog.sh.
Backup job stays in queued and never advances
Symptom: openstack share protection job show <job-id> returns state: queued for more than five minutes.
Cause: No worker VM is available (either none are registered, or all are at capacity_slots), or the conductor is not running.
Fix:
- Check registered workers:
openstack share protection worker list. You should see at least one row withstate=activeand a recentlast_heartbeat_at. - If no workers appear, check the conductor:
oc -n abaca logs -l app.kubernetes.io/component=conductor --tail=50. - If workers appear but the job is still queued, check whether all workers are at capacity: compare each worker's running job count against the
[worker] capacity_slotsvalue inabaca.conf. - If the conductor pod itself is not running:
oc -n abaca get pods -l app.kubernetes.io/component=conductor.
Backup job fails with error_category: operator_action_required
Symptom: The job reaches state: error and the error_category field is operator_action_required.
Cause: The failure requires operator intervention — for example, no worker fleet is available, the worker VM could not be reached, or the Kopia binary is missing from the image.
Fix:
- Check the job detail:
openstack share protection job show <job-id>— read thedetailfield. - Check conductor logs for context:
oc -n abaca logs -l app.kubernetes.io/component=conductor --tail=100. - Verify the worker image in Glance has the
abaca_worker_image=1property:openstack image show <image-name>. - If the image is stale, rebuild it with
deploy/rhoso/worker/20-worker-image.shand re-register it.
Backup job fails with error_category: tenant_action_required
Symptom: The job reaches state: error and the error_category field is tenant_action_required.
Cause: The failure is in the tenant's configuration — for example, invalid S3 credentials, the Keystone trust was revoked, or the Manila share does not have a usable export.
Fix:
- Read the
detailfield inopenstack share protection job show <job-id>. - If S3 credentials are invalid, update the secret in Barbican and re-enroll the target.
- If the trust was revoked, the tenant must re-authorize Abacá by recreating the trust.
- Verify the Manila share is in
availablestate:openstack share show <share-id>.
openstack share protection target list returns empty but a target was enrolled
Symptom: You enrolled a target but the list is empty from your project.
Cause: Backup targets are Domain-level resources owned by the Domain owner (abaca_domain_owner role), not individual projects. Your project token may lack the required role, or the target belongs to a different Domain.
Fix:
- Confirm your user holds the
abaca_domain_ownerrole in the relevant Domain. - Re-scope your token to the Domain and retry.
- Ask your Domain owner to confirm the target enrollment job completed with
state: available.
Worker VM boots but never appears in worker list
Symptom: A worker VM is running in Nova but openstack share protection worker list shows nothing.
Cause: The worker agent (abaca-worker-agent) cannot reach the conductor, or the transport URL in the worker's abaca.conf does not match the conductor's.
Fix:
- SSH to the worker VM and check the agent logs:
journalctl -u abaca-worker-agent. - Confirm the
[worker] api_urlin the worker's config points to the conductor's reachable address. - Confirm the VM can reach the conductor's listener port (9798 by default) from within the tenant network.
- If the worker image predates the current agent version, rebuild it with
deploy/rhoso/worker/20-worker-image.sh --forceand re-upload to Glance.