Trilio Share Protection Backup and Recovery as a Service for OpenStack Manila shares
Guide

Configuration

All environment variables, config files, and feature flags


Overview

This page describes every configuration option, environment variable, and feature flag that controls Trilio Share Protection (Abacá). Configuration is managed through a single oslo.config file (abaca.conf) shared by all Abacá services — abaca-api, abaca-conductor, and abaca-worker-agent — with a small set of environment variable overrides for container and Docker Compose deployments that do not mount a config file. Understanding these settings lets you tune API server binding, database and message-broker connectivity, the conductor's scheduling and reconciliation cadence, the Kopia execution model, and the worker fleet warm-pool behaviour. If any option's default is wrong for your environment, this page tells you exactly what to change and why.


Prerequisites

Before configuring Abacá, make sure you have:

  • Abacá installed (services abaca-api, abaca-conductor, abaca-worker-agent, and the CLI tools abaca-manage and abaca-dev)
  • OpenStack ≥ 2023.1 (Antelope) or RHOSO 18, with Keystone, Manila, and Barbican reachable
  • OpenShift ≥ 4.12 (control-plane deployment target)
  • MariaDB ≥ 10.x or MySQL accessible from the services
  • RabbitMQ accessible from all services
  • S3-compatible object storage (AWS S3, MinIO, Ceph RGW, ODF, or Wasabi)
  • Python ≥ 3.11 (required by abaca-manage and python-abacaclient)
  • Docker or Podman — only needed for the local Docker Compose development stack
  • oslo-config-generator installed (pip install oslo-config-generator) if you intend to regenerate the sample config
  • The admin OpenStack credentials (openrc) available when using the Kolla deployment scripts

Installation

1. Obtain the sample configuration file

The sample file etc/abaca.conf.sample ships with the Abacá source tree. Every supported option is listed there with its type, default value, and description. Copy it to the conventional system path:

cp etc/abaca.conf.sample /etc/abaca/abaca.conf

Set ownership and permissions so the service user can read it but unprivileged users cannot:

chown root:abaca /etc/abaca/abaca.conf
chmod 0640 /etc/abaca/abaca.conf

2. Edit the file

Open /etc/abaca/abaca.conf and uncomment the options you need to change. Every option that keeps its default value can remain commented out — oslo.config applies the default automatically.

At a minimum you almost certainly need to set:

[DEFAULT]
transport_url = rabbit://abaca:RABBIT_PASSWORD@RABBIT_HOST:5672/abaca

[database]
connection = mysql+pymysql://abaca:DB_PASSWORD@DB_HOST/abaca?charset=utf8mb4

[keystone_authtoken]
www_authenticate_uri = http://KEYSTONE_HOST:5000
auth_url             = http://KEYSTONE_HOST:5000
auth_type            = password
project_domain_name  = Default
user_domain_name     = Default
project_name         = service
username             = abaca
password             = ABACA_SERVICE_PASSWORD

[abaca]
service_user_id   = <uuid from `openstack user show abaca -f value -c id`>
service_user_name = abaca

3. Pass the config file to each service

Every Abacá console script accepts --config-file:

abaca-api --config-file /etc/abaca/abaca.conf
abaca-conductor --config-file /etc/abaca/abaca.conf
abaca-worker-agent --config-file /etc/abaca/abaca.conf
abaca-manage --config-file /etc/abaca/abaca.conf db_sync

When deploying on OpenShift or with Kolla, the config file is mounted into each container at /etc/abaca/abaca.conf; oslo.config discovers it automatically via the project=abaca convention, so no --config-file flag is needed in those environments.

4. Run database migrations

After writing a valid [database] section, initialise or migrate the schema:

abaca-manage --config-file /etc/abaca/abaca.conf db_sync

5. (Optional) Regenerate the sample after code changes

If you modify option definitions in abaca/common/config.py, regenerate the checked-in sample so CI does not fail:

tox -e sample-config          # regenerate in-place
tox -e sample-config-check    # verify the checked-in copy is current

Configuration

Abacá's options are organised into named groups that correspond directly to ini-file sections. The table format below lists each option as [section] option_name, its type and default, and what it controls.


[DEFAULT] — logging and messaging

This section is provided by oslo.log and oslo.messaging. The most important option for production is transport_url.

OptionTypeDefaultDescription
debugboolfalseSet to true to emit DEBUG-level log lines. Hot-reloadable (no restart needed).
log_filestring(stderr)Path for log output. Omit to write to stderr (recommended in containers).
use_jsonboolfalseEmit structured JSON log lines — recommended for log aggregators such as Elasticsearch or Loki.
use_journalboolfalseSend logs to systemd-journald using the native protocol. Useful on RHEL hosts.
transport_urlstringrabbit://Full RabbitMQ (or other oslo.messaging backend) URL. Required — the bare default connects to localhost with no credentials. Override with ABACA_TRANSPORT_URL in container environments.
rpc_response_timeoutint60Seconds to wait for a synchronous RPC response. Increase on slow or high-latency networks.

[abaca] — service identity

These values are served on the unauthenticated /v1/service_info endpoint so tenants can create Keystone trusts to the correct trustee without needing user-list privileges.

OptionTypeDefaultEnv overrideDescription
service_user_idstring(none)ABACA_SERVICE_USER_IDKeystone UUID of the Abacá service account. Populated by the deploy pipeline; tenants read it via /v1/service_info. Required in production.
service_user_namestringabacaABACA_SERVICE_USER_NAMEKeystone username of the service account.
worker_project_idstring(none)ABACA_WORKER_PROJECT_IDKeystone project UUID where worker VMs run. Advertised on /v1/service_info.
worker_project_namestringabacaABACA_WORKER_PROJECT_NAMEKeystone project name for worker VMs.

[api] — HTTP server

OptionTypeDefaultDescription
bind_hoststring0.0.0.0IP address the API server binds to. Set to 127.0.0.1 to restrict to localhost (e.g., behind an ingress proxy).
bind_portport (int)9797TCP port the API server listens on.
noauthboolfalseDevelopment only. Bypasses keystonemiddleware and injects a fake admin context. Never enable in production. The enrollment.dispatch=inline mode also refuses to start unless noauth=true, providing a second safety lock.
max_limitint1000Hard upper bound on the limit query parameter for list endpoints.
default_limitint100Page size used when the caller omits limit.

[database] — persistence

OptionTypeDefaultEnv overrideDescription
connectionstringsqlite:///abaca.sqliteABACA_DATABASE_CONNECTIONSQLAlchemy connection URL. The SQLite default lets you run a dev stack with no external database; always set a real MySQL/MariaDB URL in production. Marked secret=True so oslo.config redacts it from log output.

For production, use:

[database]
connection = mysql+pymysql://abaca:PASSWORD@DB_HOST/abaca?charset=utf8mb4

[conductor] — scheduling, reconciliation, and worker fleet

Scheduling and reconciliation

OptionTypeDefaultDescription
scheduler_intervalint60Seconds between passes over protection policies to trigger scheduled backups. Lower values reduce scheduling latency; higher values reduce database load.
reconciliation_intervalint300Seconds between reconciliation loop passes. The loop heals stuck jobs, orphaned workers, and database drift. See also queued_job_deadline_seconds.
maintenance_interval_secondsint604800 (7 days)How often the conductor enqueues a kopia maintenance run --full job per enrolled backup target. This is the only way Kopia reclaims S3 storage from blobs orphaned by retention pruning. Safe to run concurrently with backups.
usage_sample_interval_secondsint21600 (6 h)How often the conductor samples kopia content stats per enrolled target and persists the result as post-dedup, post-compression bytes on S3. This number is more accurate than summing Backup.size_bytes because it accounts for cross-snapshot deduplication. Read-only against the repository; safe to run concurrently.
queued_job_deadline_secondsint300Seconds a job may sit in the queued state with no assigned worker before the reconciliation loop re-dispatches it. Guards against dropped RPC casts caused by broker hiccups.

Heartbeat

OptionTypeDefaultDescription
worker_heartbeat_interval_secondsint10How often a running abaca-worker-agent sends a heartbeat RPC cast to the conductor. Must be comfortably less than worker_heartbeat_deadline_seconds.
worker_heartbeat_deadline_secondsint60Seconds after the last heartbeat before the conductor marks a worker DEAD and reassigns its in-flight job. Increase this only if your network regularly drops heartbeat cycles.
worker_agent_topicstringabaca-workeroslo.messaging topic used to address worker agents. Change only if you have a custom RabbitMQ topology.

Worker warm-pool (autoscale floor)

By default (min_workers = 0) the warm-pool sweep is disabled and operators must boot workers manually using abaca-dev worker-boot. When you set min_workers > 0, the conductor's reconciliation loop boots new VMs until the ACTIVE worker count reaches the floor.

OptionTypeDefaultDescription
min_workersint0Minimum number of ACTIVE worker VMs to keep running. 0 disables automatic booting.
worker_boot_cooldown_secondsint180Minimum gap between consecutive boot attempts. Cloud-init typically finishes in 30–90 s; 180 s prevents double-booting when the loop ticks before the previous VM registers.
worker_boot_os_cloudstringabaca-serviceclouds.yaml entry the conductor uses to authenticate against Nova when booting workers. The file must be mounted at /etc/openstack/clouds.yaml inside the conductor container.
worker_boot_imagestringabaca-worker-0.23.1Glance image to boot. Must carry the abaca_worker_image=1 property; the fleet manager enforces this.
worker_boot_flavorstringm1.smallNova flavor for automatically booted workers.
worker_boot_networkstring(none)Neutron network ID or name the warm-pool worker attaches to. Must be reachable from Manila share networks and the RabbitMQ broker. Required when min_workers > 0; the conductor logs a WARNING and skips booting when unset.
worker_boot_key_namestring(none)Nova keypair injected into automatically booted workers. Required when min_workers > 0.

[kopia] — backup engine

OptionTypeDefaultEnv overrideDescription
binarystringkopiaPath to the Kopia CLI binary inside the worker image. Override if your image places kopia outside $PATH.
require_fips_profilebooltrueRefuse to create a Kopia repository unless the FIPS 140-approved cryptographic profile can be applied. This is a supported, validated production configuration; do not set to false unless you have explicitly accepted the compliance implications.
subprocess_timeoutint3600Maximum seconds a single Kopia subprocess may run before the agent kills it. Increase for very large shares or slow S3 endpoints.
executorstringworker_rpcABACA_KOPIA_EXECUTORHow Kopia commands are executed. worker_rpc (production) dispatches to a worker VM via oslo.messaging — the conductor never holds tenant credentials. ephemeral_container is a development-only mode that runs Kopia in a throwaway container on the conductor host; in this mode the conductor briefly holds tenant credentials. Do not use ephemeral_container in production.
imagestringabaca-kopia:0.23.1ABACA_KOPIA_IMAGEContainer image used when executor=ephemeral_container. Always pin to an explicit version tag; never use :latest.
container_enginestringdockerABACA_KOPIA_CONTAINER_ENGINEContainer engine (docker or podman) for the ephemeral executor. The argument vector is podman-compatible.
container_networkstringhostABACA_KOPIA_CONTAINER_NETWORKDocker/Podman network for ephemeral containers. Use host on Kolla controllers. On a Compose stack, use the Compose network name so MinIO is reachable by service DNS.

[worker] — worker-agent runtime

OptionTypeDefaultDescription
mount_basestring/var/lib/abaca/mntBase directory inside a worker VM under which Manila shares are mounted during a job. Each job gets a subdirectory under this path; the directory is cleaned up when the job completes.

[enrollment] — target enrollment behaviour

OptionTypeDefaultEnv overrideDescription
dispatchstringrpcABACA_ENROLLMENT_DISPATCHHow enrollment jobs are dispatched. rpc (production and functional tests) creates the job row and casts to the conductor via oslo.messaging. inline is a unit-test harness only — it drives the state machine in-process with no broker. The API refuses to start with dispatch=inline unless api.noauth=true, preventing accidental use on real clusters.

[keystone_authtoken] — Keystone middleware

This section is provided by keystonemiddleware. The options most commonly set in Abacá deployments are:

[keystone_authtoken]
www_authenticate_uri         = http://KEYSTONE_VIP:5000
auth_url                     = http://KEYSTONE_VIP:5000
memcached_servers            = MEMCACHE_HOST:11211
auth_type                    = password
project_domain_name          = Default
user_domain_name             = Default
project_name                 = service
username                     = abaca
password                     = ABACA_SERVICE_PASSWORD
service_token_roles          = service
service_token_roles_required = true
region_name                  = RegionOne

Refer to the keystonemiddleware documentation for the full option reference.


Environment variable overrides

A subset of options can be set via environment variables, which is the intended mechanism for Docker Compose and other container deployments that do not mount a config file.

Environment variableOverridesNotes
ABACA_DATABASE_CONNECTION[database] connectionFull SQLAlchemy URL
ABACA_TRANSPORT_URL[DEFAULT] transport_urlFull oslo.messaging URL
ABACA_SERVICE_USER_ID[abaca] service_user_idKeystone user UUID
ABACA_SERVICE_USER_NAME[abaca] service_user_nameKeystone username
ABACA_WORKER_PROJECT_ID[abaca] worker_project_idKeystone project UUID
ABACA_WORKER_PROJECT_NAME[abaca] worker_project_nameKeystone project name
ABACA_KOPIA_EXECUTOR[kopia] executorworker_rpc or ephemeral_container
ABACA_KOPIA_IMAGE[kopia] imageContainer image for ephemeral executor
ABACA_KOPIA_CONTAINER_ENGINE[kopia] container_enginedocker or podman
ABACA_KOPIA_CONTAINER_NETWORK[kopia] container_networkNetwork name/mode
ABACA_ENROLLMENT_DISPATCH[enrollment] dispatchrpc or inline

When a config file is present, its values take precedence over environment variables for all options except transport_url, where the environment variable is set as the oslo.config default before file parsing and is therefore overridden by an explicit transport_url = line in the file.


Usage

Production: config file on OpenShift or Kolla

In a production deployment the config file lives at /etc/abaca/abaca.conf and is mounted into each container. The Kolla deploy script deploy/kolla/06-config.sh renders and installs separate files for the API and conductor:

  • /etc/kolla/abaca-api/abaca.conf — includes the [api] section
  • /etc/kolla/abaca-conductor/abaca.conf — includes the [conductor] section

Both files share the same [DEFAULT], [database], [keystone_authtoken], [abaca], [enrollment], and [kopia] sections. You do not need to pass --config-file when oslo.config can find the file via the project=abaca convention.

Development: Docker Compose without a config file

The Docker Compose development stack uses environment variables instead of a mounted config file. Set them in your shell or in a .env file that Compose picks up automatically:

export ABACA_DATABASE_CONNECTION="mysql+pymysql://abaca:dev@localhost/abaca?charset=utf8mb4"
export ABACA_TRANSPORT_URL="rabbit://abaca:dev@localhost:5672/abaca"
export ABACA_KOPIA_EXECUTOR="ephemeral_container"
export ABACA_KOPIA_IMAGE="abaca-kopia:0.23.1"
export ABACA_KOPIA_CONTAINER_ENGINE="docker"
export ABACA_KOPIA_CONTAINER_NETWORK="abaca_default"

Also set [api] noauth = true (via the file) or pass it on the command line when you want to bypass Keystone during local development:

abaca-api --config-file /etc/abaca/abaca.conf --config-option api.noauth=true

Warning: noauth=true disables all authentication. Never run this in an environment that handles real tenant data.

Tuning the conductor's scheduling cadence

If you have many protection policies and the scheduler is consuming noticeable database CPU, increase scheduler_interval. If you need backups to start more promptly after their scheduled time, decrease it. The reconciliation loop interval (reconciliation_interval) should remain at or below the worker_heartbeat_deadline_seconds value so that dead workers are detected within one loop pass.

A safe starting set of conductor values for a medium-sized deployment:

[conductor]
scheduler_interval              = 60
reconciliation_interval         = 300
worker_heartbeat_deadline_seconds = 60
worker_heartbeat_interval_seconds = 10
queued_job_deadline_seconds     = 300
maintenance_interval_seconds    = 604800
usage_sample_interval_seconds   = 21600

Enabling the warm-pool autoscale floor

To keep a standing pool of worker VMs ready (rather than relying on manual abaca-dev worker-boot):

[conductor]
min_workers                  = 2
worker_boot_cooldown_seconds = 180
worker_boot_os_cloud         = abaca-service
worker_boot_image            = abaca-worker-0.23.1
worker_boot_flavor           = m1.small
worker_boot_network          = abaca-worker-net
worker_boot_key_name         = abaca-deploy-key

Make sure /etc/openstack/clouds.yaml is mounted into the conductor container with an entry named abaca-service that has credentials sufficient to call Nova.

FIPS mode

FIPS 140 compliance is the default ([kopia] require_fips_profile = true). Worker VMs run RHEL in FIPS mode and Kopia is configured to use only FIPS-approved algorithms. You do not need to set any additional option to enable FIPS — it is on unless you explicitly disable it. Do not disable it in regulated environments.


Examples

Example 1 — Minimal production config (API service)

A complete, working config for the abaca-api service on a Kolla-managed controller. Replace placeholder values with your actual hosts and passwords.

[DEFAULT]
debug         = false
use_stderr    = true
transport_url = rabbit://abaca:RABBIT_PASSWORD@rabbit.internal:5672/abaca

[database]
connection = mysql+pymysql://abaca:DB_PASSWORD@db.internal/abaca?charset=utf8mb4

[keystone_authtoken]
www_authenticate_uri         = http://keystone.internal:5000
auth_url                     = http://keystone.internal:5000
memcached_servers            = keystone.internal:11211
auth_type                    = password
project_domain_name          = Default
user_domain_name             = Default
project_name                 = service
username                     = abaca
password                     = ABACA_SERVICE_PASSWORD
service_token_roles          = service
service_token_roles_required = true
region_name                  = RegionOne

[abaca]
service_user_id     = a1b2c3d4-e5f6-7890-abcd-ef1234567890
service_user_name   = abaca
worker_project_id   = f0e1d2c3-b4a5-6789-fedc-ba0987654321
worker_project_name = abaca

[api]
bind_host = 0.0.0.0
bind_port = 9797
noauth    = false

[enrollment]
dispatch = rpc

[kopia]
executor           = worker_rpc
require_fips_profile = true

Start the API:

abaca-api --config-file /etc/abaca/abaca.conf

Expected: the service logs startup at INFO level and binds to 0.0.0.0:9797.


Example 2 — Conductor config with warm-pool enabled

[DEFAULT]
debug         = false
use_stderr    = true
transport_url = rabbit://abaca:RABBIT_PASSWORD@rabbit.internal:5672/abaca

[database]
connection = mysql+pymysql://abaca:DB_PASSWORD@db.internal/abaca?charset=utf8mb4

[keystone_authtoken]
www_authenticate_uri = http://keystone.internal:5000
auth_url             = http://keystone.internal:5000
auth_type            = password
project_domain_name  = Default
user_domain_name     = Default
project_name         = service
username             = abaca
password             = ABACA_SERVICE_PASSWORD
service_token_roles          = service
service_token_roles_required = true

[abaca]
service_user_id     = a1b2c3d4-e5f6-7890-abcd-ef1234567890
service_user_name   = abaca
worker_project_id   = f0e1d2c3-b4a5-6789-fedc-ba0987654321
worker_project_name = abaca

[enrollment]
dispatch = rpc

[conductor]
scheduler_interval               = 60
reconciliation_interval          = 300
worker_heartbeat_deadline_seconds = 60
worker_heartbeat_interval_seconds = 10
queued_job_deadline_seconds      = 300
maintenance_interval_seconds     = 604800
usage_sample_interval_seconds    = 21600
min_workers                      = 2
worker_boot_cooldown_seconds     = 180
worker_boot_os_cloud             = abaca-service
worker_boot_image                = abaca-worker-0.23.1
worker_boot_flavor               = m1.small
worker_boot_network              = abaca-worker-net
worker_boot_key_name             = abaca-deploy-key

[kopia]
executor             = worker_rpc
require_fips_profile = true

Start the conductor:

abaca-conductor --config-file /etc/abaca/abaca.conf

Expected: the conductor logs that it is starting the scheduler loop (every 60 s), the reconciliation loop (every 300 s), and the warm-pool sweep. Within one reconciliation cycle it boots worker VMs until the ACTIVE count reaches 2.


Example 3 — Local Docker Compose dev stack (environment variables only)

No config file is needed. Export environment variables, then start the services:

export ABACA_DATABASE_CONNECTION="sqlite:///abaca-dev.sqlite"
export ABACA_TRANSPORT_URL="rabbit://guest:guest@localhost:5672/"
export ABACA_SERVICE_USER_NAME="abaca"
export ABACA_KOPIA_EXECUTOR="ephemeral_container"
export ABACA_KOPIA_IMAGE="abaca-kopia:0.23.1"
export ABACA_KOPIA_CONTAINER_ENGINE="docker"
export ABACA_KOPIA_CONTAINER_NETWORK="host"
export ABACA_ENROLLMENT_DISPATCH="rpc"

# Run the database migration first
abaca-manage db_sync

# Start the API with noauth for local testing
abaca-api --config-option api.noauth=true

Expected: the API starts on 0.0.0.0:9797 and accepts unauthenticated requests with a fake admin context injected. All Kopia commands run in ephemeral Docker containers on the local host.


Example 4 — Regenerating the sample config after adding an option

After editing abaca/common/config.py to add or modify an option:

# Regenerate in-place
tox -e sample-config

# Verify the checked-in copy matches (CI runs this step)
tox -e sample-config-check

Expected output of sample-config-check when the sample is current:

sample-config-check: commands succeeded

If the check fails, it means the checked-in etc/abaca.conf.sample has drifted from the code — run tox -e sample-config and commit the result.


Troubleshooting

Issue 1 — Service fails to start: NoValidConnection or OperationalError connecting to the database

Symptom: abaca-api or abaca-conductor exits immediately with a SQLAlchemy OperationalError or a connection refused error referencing sqlite:///abaca.sqlite (or your configured URL).

Likely cause: The [database] connection option is unset (falling back to the SQLite default) or points to a host/port that is not reachable from the container.

Fix:

  1. Check the effective value: abaca-manage --config-file /etc/abaca/abaca.conf config_file (or inspect the [database] section of your config).
  2. Set connection to the correct MySQL/MariaDB URL, or export ABACA_DATABASE_CONNECTION.
  3. Make sure the database host is reachable from within the container and that the credentials are correct.
  4. Run abaca-manage --config-file /etc/abaca/abaca.conf db_sync to confirm connectivity before starting the service.

Issue 2 — Service fails to start: MessagingTimeout or kombu.exceptions.OperationalError for RabbitMQ

Symptom: The conductor or API logs a RabbitMQ connection error and exits, or hangs at startup.

Likely cause: [DEFAULT] transport_url is the bare default rabbit:// (connects to localhost with no credentials) or points to a host that is not reachable.

Fix:

  1. Set transport_url in [DEFAULT] to the full URL: rabbit://USER:PASSWORD@HOST:5672/VHOST.
  2. Alternatively, export ABACA_TRANSPORT_URL before starting the service.
  3. Verify connectivity: python3 -c "import kombu; kombu.Connection('amqp://USER:PASSWORD@HOST:5672/VHOST').ensure_connection()".

Issue 3 — API returns 401 Unauthorized for all requests

Symptom: Every API call returns 401 Unauthorized with a WWW-Authenticate header pointing at Keystone.

Likely cause: The [keystone_authtoken] section is missing or has incorrect auth_url, username, or password values, causing keystonemiddleware to reject the service token validation.

Fix:

  1. Confirm the abaca service user exists in Keystone and its password matches [keystone_authtoken] password.
  2. Check www_authenticate_uri and auth_url point to a reachable Keystone endpoint.
  3. If you are running a local dev stack and want to skip Keystone, set [api] noauth = true — but never in production.

Issue 4 — noauth=true is set but enrollment fails with dispatch=inline refused

Symptom: The API starts with noauth=true but enrollment calls return an error saying dispatch=inline is refused.

Likely cause: [enrollment] dispatch is set to inline (the unit-test harness), but this mode is only permitted when api.noauth=true. Check whether both are set consistently.

Fix: For a real development stack, use dispatch = rpc (the default) and make sure RabbitMQ and the conductor are running. Only set dispatch = inline in pure unit-test contexts where no broker or conductor exists.


Issue 5 — Kopia repository creation fails: FIPS profile cannot be applied

Symptom: Enrollment jobs fail with an error indicating the FIPS cryptographic profile cannot be applied.

Likely cause: The worker VM is not running in RHEL FIPS mode, or the Kopia binary in the worker image does not support the FIPS profile.

Fix:

  1. Verify the worker image was built with FIPS mode enabled (RHEL FIPS mode, Kopia ≥ 0.23.1).
  2. Confirm the Glance image carries the abaca_worker_image=1 property.
  3. If you are in a non-regulated environment and deliberately want to skip FIPS, set [kopia] require_fips_profile = false — but document and approve this exception explicitly.

Issue 6 — Warm-pool sweep boots no workers despite min_workers > 0

Symptom: The conductor logs a WARNING and the worker count does not rise to min_workers.

Likely cause: worker_boot_network or worker_boot_key_name is unset; the sweep no-ops and logs a warning when either is missing.

Fix:

  1. Set [conductor] worker_boot_network to the Neutron network ID or name that is reachable from Manila share networks and the RabbitMQ broker.
  2. Set [conductor] worker_boot_key_name to a valid Nova keypair name.
  3. Confirm [conductor] worker_boot_os_cloud matches an entry in /etc/openstack/clouds.yaml that is mounted into the conductor container.
  4. Confirm the Glance image named in worker_boot_image exists and has the abaca_worker_image=1 property.

Issue 7 — The sample config file is out of date in CI

Symptom: The sample-config-check CI job fails with a diff showing the checked-in etc/abaca.conf.sample does not match a fresh generation.

Likely cause: Someone added or modified an option in abaca/common/config.py without regenerating the sample.

Fix:

tox -e sample-config
git add etc/abaca.conf.sample
git commit -m "regen sample config"