Skip to content

Headless sync — proxbox_sync management command

The proxbox_sync Django management command triggers a full Proxmox→NetBox sync from the NetBox shell. It is the headless equivalent of clicking the Full Update button on the plugin home page and is the supported entry point for cron jobs, systemd timers, Kubernetes CronJobs, CI smoke tests, and runbook automation.

What it does

proxbox_sync enqueues the same ProxboxSyncJob that the UI's Full Update button enqueues:

  • Queue: NetBox's default RQ queue (default).
  • Sync types: [SyncTypeChoices.ALL] — all stages.
  • Endpoints: every configured ProxmoxEndpoint.
  • Job timeout: PROXBOX_SYNC_JOB_TIMEOUT (7200 seconds).

The job appears under Background Jobs in NetBox identical to a UI-triggered sync, so the existing job-detail page, log stream, and Cancel job / Run now controls all work unchanged.

Usage

python manage.py proxbox_sync

Common variants:

# Block until the job finishes; exit code mirrors the job's terminal status.
python manage.py proxbox_sync --wait

# Run as a specific user (overrides the default oldest active superuser).
python manage.py proxbox_sync --user automation

# Bound the wait loop (default: 7200s).
python manage.py proxbox_sync --wait --timeout 1800

# Poll less aggressively while waiting (default: 2.0s).
python manage.py proxbox_sync --wait --poll-interval 5

# Fail fast if no RQ worker is consuming the default queue (default: 30s).
python manage.py proxbox_sync --wait --worker-grace 10

Flags

Flag Default Purpose
--user USERNAME oldest active superuser Username to attribute the job to. Used for audit and job ownership.
--wait off Block until the job reaches a terminal state; exit code mirrors the job's status.
--timeout SECONDS 7200 Upper bound on the --wait loop. Matches PROXBOX_SYNC_JOB_TIMEOUT.
--poll-interval SECONDS 2.0 Seconds between job-status polls while --wait is set.
--worker-grace SECONDS 30.0 Maximum seconds the job may stay pending before the command checks for an active RQ worker and fast-fails if none is found.
--enqueue-once off Route through JobRunner.enqueue_once() so the command reuses an already-pending recurring schedule instead of duplicating it. Designed for the proxbox-scheduler container so it coexists with the NetBox-side Schedule Sync form.

Exit codes

Exit code Condition
0 Job enqueued (and, with --wait, finished with status completed).
non-zero Any of: no FastAPIEndpoint configured · proxbox-api unreachable on /health · no usable user · ProxboxSyncJob.enqueue raised · with --wait, job ended in errored / failed or timed out / no worker available.

All failure paths emit an actionable message to stderr via Django's CommandError so cron / systemd capture useful logs.

RQ worker requirement

proxbox_sync only enqueues the job. An RQ worker on the default queue must be running for the job to actually execute. With --wait, the command probes django_rq.get_queue("default").workers after --worker-grace seconds and fails fast if no worker is consuming the queue — useful in CI and during deployment-window automation.

Without --wait, the command returns the moment the job is enqueued. A long-pending job in the Background Jobs UI usually means the worker is not running.

See the Backend integration notes in the top-level CLAUDE.md for the full RQ queue / timeout model.

Example: cron

Run a full sync every six hours:

0 */6 * * * cd /opt/netbox && /opt/netbox/venv/bin/python manage.py proxbox_sync --wait --timeout 7200

Example: systemd timer

/etc/systemd/system/proxbox-sync.service:

[Unit]
Description=ProxBox full sync (headless)
After=netbox-rq.service

[Service]
Type=oneshot
WorkingDirectory=/opt/netbox
ExecStart=/opt/netbox/venv/bin/python manage.py proxbox_sync --wait --timeout 7200

/etc/systemd/system/proxbox-sync.timer:

[Unit]
Description=Run proxbox-sync every 6 hours

[Timer]
OnCalendar=0/6:00
Persistent=true

[Install]
WantedBy=timers.target

Enable:

systemctl daemon-reload
systemctl enable --now proxbox-sync.timer
  • UI equivalent: Full Update button on the plugin home page (SyncFullUpdateView in netbox_proxbox/views/sync.py).
  • Token-status diagnostics: python manage.py proxbox_fix_tokens.
  • Sync internals: netbox_proxbox/jobs.py.
  • Container-based scheduler with cron/continuous modes: docs/scheduler/README.md (issue #372).