Skip to content

Make targets

The Makefile is the operator contract. Everything below exists in it today.

Lab lifecycle

Target What it does
make local-lab-up Depends on build-docker. Generates the containerlab topology + device configs from topology.json, brings up the base stack plus the worker and lab_bootstrap (creating lab-net), waits for workflow registration, containerlab deploys the 15 devices, waits for the worker’s function blocks, then waits for every device’s SSH. Refuses to run without cms_api_key.env.
make local-lab-discover Waits for the discovery function block and for device SSH, then POSTs a workflow execution and polls to a terminal state (15-minute ceiling). Override DISCOVER_PARAMS to change targeting.
make local-lab-logs docker compose logs -f worker lab_bootstrap.
make local-lab-down containerlab destroy --cleanup (removes the devices and generated/clab-neops-lab/), then docker compose down. Volumes survive.

All four export COMPOSE_FILE=docker-compose.yml:docker-compose.worker.yml, so they see the worker overlay; the local-env-* targets do not.

Variables

Variable Default Purpose
DISCOVER_PARAMS workflow-execution-parameters/discover-params.json Which parameter file local-lab-discover sends
DISCOVER_FB fb.base.neops.io/global_discover_network:0.1.0 The function block wait_ready blocks on
CLAB_TOPO generated/neops-lab.clab.json The generated containerlab topology
make local-lab-discover \
  DISCOVER_PARAMS=workflow-execution-parameters/discover-params-autodetect.json

Environment lifecycle

Target What it does
make lab-jwt Mints cms/jwt/{private,public}.pem with openssl if absent. Idempotent. A prerequisite of both local-env-init and local-env-up.
make local-env-init One-time per environment: pull + start the base stack, mint the CMS API key into cms_api_key.env, run apply_cms_config, then force-recreate the engine so it picks up the token.
make local-env-up Start the base stack again later. Fails with a clear message if cms_api_key.env is missing.
make local-env-down docker compose down — stops the base stack, keeps the volumes.
make local-env-prune docker compose down -v — the true reset; drops the Elasticsearch and Postgres volumes.
make apply-cms-config Runs ./apply_cms_config on its own. Idempotent, and worth re-running after a CMS restart (see below).

Re-run apply-cms-config after a CMS restart

The CMS image seeds a scope named Global on every startup with always_update_on_restart=True, so a restart resets its columns and filters to the image defaults. dashboard_configuration is not reset — init_scopes never writes it. Re-run make apply-cms-config to reapply the lab’s columns and drill-down.

What apply_cms_config does

It grants the neops user a full-permission role (lab-admin, default_permission=7) and configures the Global scope from the JSON files under scope/Global/ — table columns for devices, interfaces, clients and groups, a location drill-down schema, and a dashboard configuration.

It is bash, not Python, and it uses manage.py shell rather than GraphQL for the seeding steps: roleUpsert / scopesUpsert / roleScopeUpsert all gate on permissions the freshly-bootstrapped neops user does not yet have. Table columns and drill-down are written through GraphQL, deliberately last, because the CMS’s init_scopes runs on every manage.py invocation and would otherwise overwrite a shell write.

If you reorder anything in that script, read its header comment first.

Images

Target What it does
make build-docker Builds neops-lab-frr:latest from devices/frr/ and neops-lab-bootstrap:latest from bootstrap/. Local tags only — nothing is pushed. A prerequisite of local-lab-up.

See Images.

Quality gates

Target What it runs
make lint ruff format --check . then ruff check .
make format ruff format . then ruff check --fix .
make typeCheck pyrefly check
make test pytest tests — the generator unit tests
make check lint typeCheck test — the one to run before pushing

Documentation

Contributed by the vendored mkdocs-documentation tooling in .make_scripts/mkdocs-documentation/:

Target What it does
make doc-serve Live-preview server; regenerates mkdocs.yml when mkdocs_custom.yml or mkdocs_base.yml change
make doc-build Regenerate mkdocs.yml, mkdocs build, then clean the site dir
make doc-build-docker / make doc-run-docker Build and run the docs as an NGINX image
make doc-create-mkdocs Regenerate mkdocs.yml and refresh the docs CI workflow
make doc-update-assets Pull the latest tooling release into .make_scripts/

mkdocs.yml is autogenerated — never edit it

It is produced by setup_documentation.py from this repo’s mkdocs_custom.yml deep-merged over the shared mkdocs_base.yml. Edit mkdocs_custom.yml. Note that dicts merge but lists concatenate, so re-declaring hooks: or plugins: entries that the base already has registers them twice.

Release and infrastructure

Contributed by the vendored release-management and project-infrastructure tooling:

Target What it does
make tag-patch / tag-minor / tag-major (+ -beta) Create a local annotated SemVer tag
make tag-latest-beta, make check-for-releases, make hard-reset-tags, make tag-major-minor-ruleset Tag helpers
make sync-release-assets, make sync-infrastructure-assets Re-vendor the tooling scripts (destructive by design — they rm -rf the vendored dir first)
make github-set-branch-protections, make github-set-default-branch, make github-autodelete-merged-branches Repository settings

Tagging this repo publishes nothing

neops-lab is not a distributable package — no wheel, no npm package, no registry image. make tag-* creates a local annotated tag; the separate git push --tags is what triggers downstream pipelines in repos that have them. This one has none.

Full reset

make local-lab-down local-env-prune
make local-env-init && make local-lab-up && make local-lab-discover