all:
  children:
    zuul_unreachable:
      hosts: {}
  hosts:
    debian-bookworm:
      ansible_connection: ssh
      ansible_host: 2a13:1a81:8000:3124:f816:3eff:fe8b:b513
      ansible_port: 22
      ansible_python_interpreter: auto
      ansible_user: zuul
      nodepool:
        az: nova
        cloud: regiocloud-a-ci
        external_id: 48b10798-5b77-453d-aa1d-f795592bbf59
        host_id: 82101243836454d7401d5893feae9e2c5df7cc291646d8a99b33b53b
        interface_ip: 2a13:1a81:8000:3124:f816:3eff:fe8b:b513
        label: debian-bookworm
        node_properties: {}
        private_ipv4: 10.128.7.110
        private_ipv6: null
        provider: regiocloud-a
        public_ipv4: 81.163.192.66
        public_ipv6: 2a13:1a81:8000:3124:f816:3eff:fe8b:b513
        region: null
        slot: null
  vars:
    zuul:
      _inheritance_path:
      - '<Job base explicit: None implied: {MatchAny:{ImpliedBranchMatcher:main}}
        source: osism/zuul-config/zuul.d/jobs.yaml@main#2>'
      - '<Job flake8 explicit: None implied: {MatchAny:{ImpliedBranchMatcher:main}}
        source: osism/zuul-jobs/.zuul.yaml@main#32>'
      - '<Job flake8 explicit: None implied: None source: osism/python-osism/.zuul.yaml@main#171>'
      ansible_version: '9'
      attempts: 1
      branch: main
      build: ed36960c44484a84ab8912ed600b7ba0
      build_refs:
      - branch: main
        change: '2532'
        change_message: "SONiC E2E: provision NetBox with docker compose\n\n## Purpose\n\nDraft,
          opened to get a CI timing number for the compose migration. It extends the
          SONiC E2E harness from:\n\n- osism/python-osism#2483\n\nwith four scenario
          commits and then replaces the kind + Helm NetBox fixture with docker compose.
          Not for review yet \u2014 see *Relationship to #2483* below.\n\n## Why\n\n`python-osism-sonic-e2e`
          timed out (buildset [`8ea91237`](https://zuul.services.osism.tech/t/osism/buildset/8ea91237f334425183c7818867cda1f4),
          2457s). It was aborted mid-generation, ~2 minutes short of finishing.\n\nThe
          job did not hang. Zuul's `timeout` is one budget spanning **pre-run + run**,
          and the job normally consumed 80\u201392% of its 2400s: seven successive
          runs of identical code took 1919\u20132212s pre+run. What tipped it over
          was node-local \u2014 `ensure-pip : Update package lists` took **301s**
          instead of the usual 2\u20136s, adding ~409s to the pre-run. Not shared-mirror
          contention: the sibling jobs in the same buildset ran that identical task
          in 5s, 2s and 2s.\n\nThe underlying problem was that ~1650s of a ~2100s
          run was fixed setup: `helm install --wait` 704\u2013792s and seeding 888\u20131011s.\n\n##
          What was measured\n\nKubernetes contributed nothing the test used, while
          the chart's defaults were a large part of the cost: PostgreSQL capped at
          **150m CPU**, and a `netbox-worker` whose `wait-for-backend` init container
          hit `CrashLoopBackOff` and extended `helm --wait`. Image pulls were never
          the issue (netbox, 243 MB, pulled in 20.6s).\n\nComparable phases (provisioning
          + base example seeding), all measured on one 16-core host:\n\n| fixture
          | provisioning | base seeding | total |\n|---|---|---|---|\n| kind + Helm,
          chart defaults (what CI runs today) | 460s | 433s | **893s** |\n| kind +
          Helm, resource caps removed, worker off | 349s | 302s | 651s |\n| **docker
          compose** | **241s** | **272s** | **~504s** |\n\nAlso measured: NetBox's
          expensive startup is one-time per fresh database \u2014 the image's entrypoint
          guards `migrate`/`trace_paths`/`reindex` behind `migrate --check`, so first
          boot took 339s and subsequent boots 50s and 60s.\n\n## Changes\n\n- **`nodeset:
          ubuntu-noble-large`** \u2014 the job ran a Kubernetes control plane, a four-container
          NetBox stack and the Ansible client on `SCS-2V-4-10` (2 vCPU / 4 GB). Node
          size alone was worth 1.53\xD7 on the deploy and 2.19\xD7 on seeding.\n-
          **`tests/e2e/compose.yaml`** \u2014 postgres 17.10 / valkey 8.1 / netbox
          v4.5.10, with healthchecks and `depends_on: service_healthy`. NetBox is
          configured entirely through the environment variables its own baked `configuration.py`
          reads, so no config file is authored; the Helm chart had been *overriding*
          that file. `API_TOKEN_PEPPERS` is deliberately unset, because the image's
          bootstrap only ever creates a v2 token \u2014 which is why a v1 token still
          has to be minted for pynetbox / `netbox.netbox`.\n- **`tests/e2e/deploy_netbox.sh`**
          \u2014 `docker compose up --wait` replaces cluster creation, chart install
          and readiness polling. No port-forward: the API is published on `127.0.0.1:8080`
          directly, removing that process and its liveness guard.\n- **`tests/e2e/run.sh`**
          \u2014 keeps ownership of the lifecycle trap and teardown; diagnostics now
          capture the NetBox *application* log (which was unavailable when diagnosing
          the original failure \u2014 the cause had to be inferred from Kubernetes
          probe events).\n- **`playbooks/pre-sonic-e2e.yml`** \u2014 kind, kubectl
          and Helm installs removed along with their six pinned digests. `ensure-docker`
          already provides `docker-compose-plugin`. The `accept_ra=2` sysctl is retained
          deliberately.\n\n`timeout` stays at 2400.\n\n## Verification\n\nFull local
          run: `make sonic-e2e` exit 0, `OK: exports match the golden files`. **All
          10 device configs byte-identical with no `--regenerate`** \u2014 same NetBox
          version in, same configs out. End to end 9m34s.\n\nWhat this PR is for is
          the CI number: pre+run against the ~2100s baseline. The projection is ~1250\u20131350s,
          extrapolated from 16 cores onto 8 vCPU and therefore unverified.\n\n## Relationship
          to #2483\n\nThis branch contains #2483's commits plus four scenario additions
          plus this migration. It is a draft opened to obtain CI timing; once green,
          the intent is to fold the result back rather than keep two overlapping PRs
          open.\n\n## Not included\n\n- `--parallel 4` seeding (measured 302s \u2192
          167s) \u2014 deferred deliberately, since it is the only change that could
          alter NetBox state non-deterministically, and keeping it separate makes
          a golden mismatch unambiguously attributable.\n- netbox-manager is **untouched**
          and keeps its kind harness, so `netbox-manager-e2e` cannot regress.\n- Removing
          the `accept_ra` workaround, and pinning postgres/valkey by digest.\n\n##
          Known follow-ups\n\n- The harness seeds every file in `tests/e2e/scenario/resources/`,
          tracked or not. Harmless in CI's clean checkout, but local WIP silently
          joins the fixture.\n- `ubuntu-noble-large` has no `min-ready` (`ubuntu-noble`
          has 2), so this job now pays a cold VM boot per run \u2014 queue latency,
          outside the build timeout.\n\n\U0001F916 Generated with [Claude Code](https://claude.com/claude-code)\n"
        change_url: https://github.com/osism/python-osism/pull/2532
        commit_id: 219205b80095bde5ed5d99915f68e530a1832f4b
        patchset: 219205b80095bde5ed5d99915f68e530a1832f4b
        project:
          canonical_hostname: github.com
          canonical_name: github.com/osism/python-osism
          name: osism/python-osism
          short_name: python-osism
        src_dir: src/github.com/osism/python-osism
        topic: null
      buildset: cef96bef6d5745d7960076f86bd00410
      buildset_refs:
      - branch: main
        change: '2532'
        change_message: "SONiC E2E: provision NetBox with docker compose\n\n## Purpose\n\nDraft,
          opened to get a CI timing number for the compose migration. It extends the
          SONiC E2E harness from:\n\n- osism/python-osism#2483\n\nwith four scenario
          commits and then replaces the kind + Helm NetBox fixture with docker compose.
          Not for review yet \u2014 see *Relationship to #2483* below.\n\n## Why\n\n`python-osism-sonic-e2e`
          timed out (buildset [`8ea91237`](https://zuul.services.osism.tech/t/osism/buildset/8ea91237f334425183c7818867cda1f4),
          2457s). It was aborted mid-generation, ~2 minutes short of finishing.\n\nThe
          job did not hang. Zuul's `timeout` is one budget spanning **pre-run + run**,
          and the job normally consumed 80\u201392% of its 2400s: seven successive
          runs of identical code took 1919\u20132212s pre+run. What tipped it over
          was node-local \u2014 `ensure-pip : Update package lists` took **301s**
          instead of the usual 2\u20136s, adding ~409s to the pre-run. Not shared-mirror
          contention: the sibling jobs in the same buildset ran that identical task
          in 5s, 2s and 2s.\n\nThe underlying problem was that ~1650s of a ~2100s
          run was fixed setup: `helm install --wait` 704\u2013792s and seeding 888\u20131011s.\n\n##
          What was measured\n\nKubernetes contributed nothing the test used, while
          the chart's defaults were a large part of the cost: PostgreSQL capped at
          **150m CPU**, and a `netbox-worker` whose `wait-for-backend` init container
          hit `CrashLoopBackOff` and extended `helm --wait`. Image pulls were never
          the issue (netbox, 243 MB, pulled in 20.6s).\n\nComparable phases (provisioning
          + base example seeding), all measured on one 16-core host:\n\n| fixture
          | provisioning | base seeding | total |\n|---|---|---|---|\n| kind + Helm,
          chart defaults (what CI runs today) | 460s | 433s | **893s** |\n| kind +
          Helm, resource caps removed, worker off | 349s | 302s | 651s |\n| **docker
          compose** | **241s** | **272s** | **~504s** |\n\nAlso measured: NetBox's
          expensive startup is one-time per fresh database \u2014 the image's entrypoint
          guards `migrate`/`trace_paths`/`reindex` behind `migrate --check`, so first
          boot took 339s and subsequent boots 50s and 60s.\n\n## Changes\n\n- **`nodeset:
          ubuntu-noble-large`** \u2014 the job ran a Kubernetes control plane, a four-container
          NetBox stack and the Ansible client on `SCS-2V-4-10` (2 vCPU / 4 GB). Node
          size alone was worth 1.53\xD7 on the deploy and 2.19\xD7 on seeding.\n-
          **`tests/e2e/compose.yaml`** \u2014 postgres 17.10 / valkey 8.1 / netbox
          v4.5.10, with healthchecks and `depends_on: service_healthy`. NetBox is
          configured entirely through the environment variables its own baked `configuration.py`
          reads, so no config file is authored; the Helm chart had been *overriding*
          that file. `API_TOKEN_PEPPERS` is deliberately unset, because the image's
          bootstrap only ever creates a v2 token \u2014 which is why a v1 token still
          has to be minted for pynetbox / `netbox.netbox`.\n- **`tests/e2e/deploy_netbox.sh`**
          \u2014 `docker compose up --wait` replaces cluster creation, chart install
          and readiness polling. No port-forward: the API is published on `127.0.0.1:8080`
          directly, removing that process and its liveness guard.\n- **`tests/e2e/run.sh`**
          \u2014 keeps ownership of the lifecycle trap and teardown; diagnostics now
          capture the NetBox *application* log (which was unavailable when diagnosing
          the original failure \u2014 the cause had to be inferred from Kubernetes
          probe events).\n- **`playbooks/pre-sonic-e2e.yml`** \u2014 kind, kubectl
          and Helm installs removed along with their six pinned digests. `ensure-docker`
          already provides `docker-compose-plugin`. The `accept_ra=2` sysctl is retained
          deliberately.\n\n`timeout` stays at 2400.\n\n## Verification\n\nFull local
          run: `make sonic-e2e` exit 0, `OK: exports match the golden files`. **All
          10 device configs byte-identical with no `--regenerate`** \u2014 same NetBox
          version in, same configs out. End to end 9m34s.\n\nWhat this PR is for is
          the CI number: pre+run against the ~2100s baseline. The projection is ~1250\u20131350s,
          extrapolated from 16 cores onto 8 vCPU and therefore unverified.\n\n## Relationship
          to #2483\n\nThis branch contains #2483's commits plus four scenario additions
          plus this migration. It is a draft opened to obtain CI timing; once green,
          the intent is to fold the result back rather than keep two overlapping PRs
          open.\n\n## Not included\n\n- `--parallel 4` seeding (measured 302s \u2192
          167s) \u2014 deferred deliberately, since it is the only change that could
          alter NetBox state non-deterministically, and keeping it separate makes
          a golden mismatch unambiguously attributable.\n- netbox-manager is **untouched**
          and keeps its kind harness, so `netbox-manager-e2e` cannot regress.\n- Removing
          the `accept_ra` workaround, and pinning postgres/valkey by digest.\n\n##
          Known follow-ups\n\n- The harness seeds every file in `tests/e2e/scenario/resources/`,
          tracked or not. Harmless in CI's clean checkout, but local WIP silently
          joins the fixture.\n- `ubuntu-noble-large` has no `min-ready` (`ubuntu-noble`
          has 2), so this job now pays a cold VM boot per run \u2014 queue latency,
          outside the build timeout.\n\n\U0001F916 Generated with [Claude Code](https://claude.com/claude-code)\n"
        change_url: https://github.com/osism/python-osism/pull/2532
        commit_id: 219205b80095bde5ed5d99915f68e530a1832f4b
        patchset: 219205b80095bde5ed5d99915f68e530a1832f4b
        project:
          canonical_hostname: github.com
          canonical_name: github.com/osism/python-osism
          name: osism/python-osism
          short_name: python-osism
        src_dir: src/github.com/osism/python-osism
        topic: null
      change: '2532'
      change_message: "SONiC E2E: provision NetBox with docker compose\n\n## Purpose\n\nDraft,
        opened to get a CI timing number for the compose migration. It extends the
        SONiC E2E harness from:\n\n- osism/python-osism#2483\n\nwith four scenario
        commits and then replaces the kind + Helm NetBox fixture with docker compose.
        Not for review yet \u2014 see *Relationship to #2483* below.\n\n## Why\n\n`python-osism-sonic-e2e`
        timed out (buildset [`8ea91237`](https://zuul.services.osism.tech/t/osism/buildset/8ea91237f334425183c7818867cda1f4),
        2457s). It was aborted mid-generation, ~2 minutes short of finishing.\n\nThe
        job did not hang. Zuul's `timeout` is one budget spanning **pre-run + run**,
        and the job normally consumed 80\u201392% of its 2400s: seven successive runs
        of identical code took 1919\u20132212s pre+run. What tipped it over was node-local
        \u2014 `ensure-pip : Update package lists` took **301s** instead of the usual
        2\u20136s, adding ~409s to the pre-run. Not shared-mirror contention: the
        sibling jobs in the same buildset ran that identical task in 5s, 2s and 2s.\n\nThe
        underlying problem was that ~1650s of a ~2100s run was fixed setup: `helm
        install --wait` 704\u2013792s and seeding 888\u20131011s.\n\n## What was measured\n\nKubernetes
        contributed nothing the test used, while the chart's defaults were a large
        part of the cost: PostgreSQL capped at **150m CPU**, and a `netbox-worker`
        whose `wait-for-backend` init container hit `CrashLoopBackOff` and extended
        `helm --wait`. Image pulls were never the issue (netbox, 243 MB, pulled in
        20.6s).\n\nComparable phases (provisioning + base example seeding), all measured
        on one 16-core host:\n\n| fixture | provisioning | base seeding | total |\n|---|---|---|---|\n|
        kind + Helm, chart defaults (what CI runs today) | 460s | 433s | **893s**
        |\n| kind + Helm, resource caps removed, worker off | 349s | 302s | 651s |\n|
        **docker compose** | **241s** | **272s** | **~504s** |\n\nAlso measured: NetBox's
        expensive startup is one-time per fresh database \u2014 the image's entrypoint
        guards `migrate`/`trace_paths`/`reindex` behind `migrate --check`, so first
        boot took 339s and subsequent boots 50s and 60s.\n\n## Changes\n\n- **`nodeset:
        ubuntu-noble-large`** \u2014 the job ran a Kubernetes control plane, a four-container
        NetBox stack and the Ansible client on `SCS-2V-4-10` (2 vCPU / 4 GB). Node
        size alone was worth 1.53\xD7 on the deploy and 2.19\xD7 on seeding.\n- **`tests/e2e/compose.yaml`**
        \u2014 postgres 17.10 / valkey 8.1 / netbox v4.5.10, with healthchecks and
        `depends_on: service_healthy`. NetBox is configured entirely through the environment
        variables its own baked `configuration.py` reads, so no config file is authored;
        the Helm chart had been *overriding* that file. `API_TOKEN_PEPPERS` is deliberately
        unset, because the image's bootstrap only ever creates a v2 token \u2014 which
        is why a v1 token still has to be minted for pynetbox / `netbox.netbox`.\n-
        **`tests/e2e/deploy_netbox.sh`** \u2014 `docker compose up --wait` replaces
        cluster creation, chart install and readiness polling. No port-forward: the
        API is published on `127.0.0.1:8080` directly, removing that process and its
        liveness guard.\n- **`tests/e2e/run.sh`** \u2014 keeps ownership of the lifecycle
        trap and teardown; diagnostics now capture the NetBox *application* log (which
        was unavailable when diagnosing the original failure \u2014 the cause had
        to be inferred from Kubernetes probe events).\n- **`playbooks/pre-sonic-e2e.yml`**
        \u2014 kind, kubectl and Helm installs removed along with their six pinned
        digests. `ensure-docker` already provides `docker-compose-plugin`. The `accept_ra=2`
        sysctl is retained deliberately.\n\n`timeout` stays at 2400.\n\n## Verification\n\nFull
        local run: `make sonic-e2e` exit 0, `OK: exports match the golden files`.
        **All 10 device configs byte-identical with no `--regenerate`** \u2014 same
        NetBox version in, same configs out. End to end 9m34s.\n\nWhat this PR is
        for is the CI number: pre+run against the ~2100s baseline. The projection
        is ~1250\u20131350s, extrapolated from 16 cores onto 8 vCPU and therefore
        unverified.\n\n## Relationship to #2483\n\nThis branch contains #2483's commits
        plus four scenario additions plus this migration. It is a draft opened to
        obtain CI timing; once green, the intent is to fold the result back rather
        than keep two overlapping PRs open.\n\n## Not included\n\n- `--parallel 4`
        seeding (measured 302s \u2192 167s) \u2014 deferred deliberately, since it
        is the only change that could alter NetBox state non-deterministically, and
        keeping it separate makes a golden mismatch unambiguously attributable.\n-
        netbox-manager is **untouched** and keeps its kind harness, so `netbox-manager-e2e`
        cannot regress.\n- Removing the `accept_ra` workaround, and pinning postgres/valkey
        by digest.\n\n## Known follow-ups\n\n- The harness seeds every file in `tests/e2e/scenario/resources/`,
        tracked or not. Harmless in CI's clean checkout, but local WIP silently joins
        the fixture.\n- `ubuntu-noble-large` has no `min-ready` (`ubuntu-noble` has
        2), so this job now pays a cold VM boot per run \u2014 queue latency, outside
        the build timeout.\n\n\U0001F916 Generated with [Claude Code](https://claude.com/claude-code)\n"
      change_url: https://github.com/osism/python-osism/pull/2532
      child_jobs: []
      commit_id: 219205b80095bde5ed5d99915f68e530a1832f4b
      event_id: 2b6781b0-8bf8-11f1-82dc-dcaf202f13c4
      executor:
        hostname: 521e9411259a
        inventory_file: /var/lib/zuul/builds/ed36960c44484a84ab8912ed600b7ba0/ansible/inventory.yaml
        log_root: /var/lib/zuul/builds/ed36960c44484a84ab8912ed600b7ba0/work/logs
        result_data_file: /var/lib/zuul/builds/ed36960c44484a84ab8912ed600b7ba0/work/results.json
        src_root: /var/lib/zuul/builds/ed36960c44484a84ab8912ed600b7ba0/work/src
        work_root: /var/lib/zuul/builds/ed36960c44484a84ab8912ed600b7ba0/work
      include_vars: []
      items:
      - branch: main
        change: '2532'
        change_message: "SONiC E2E: provision NetBox with docker compose\n\n## Purpose\n\nDraft,
          opened to get a CI timing number for the compose migration. It extends the
          SONiC E2E harness from:\n\n- osism/python-osism#2483\n\nwith four scenario
          commits and then replaces the kind + Helm NetBox fixture with docker compose.
          Not for review yet \u2014 see *Relationship to #2483* below.\n\n## Why\n\n`python-osism-sonic-e2e`
          timed out (buildset [`8ea91237`](https://zuul.services.osism.tech/t/osism/buildset/8ea91237f334425183c7818867cda1f4),
          2457s). It was aborted mid-generation, ~2 minutes short of finishing.\n\nThe
          job did not hang. Zuul's `timeout` is one budget spanning **pre-run + run**,
          and the job normally consumed 80\u201392% of its 2400s: seven successive
          runs of identical code took 1919\u20132212s pre+run. What tipped it over
          was node-local \u2014 `ensure-pip : Update package lists` took **301s**
          instead of the usual 2\u20136s, adding ~409s to the pre-run. Not shared-mirror
          contention: the sibling jobs in the same buildset ran that identical task
          in 5s, 2s and 2s.\n\nThe underlying problem was that ~1650s of a ~2100s
          run was fixed setup: `helm install --wait` 704\u2013792s and seeding 888\u20131011s.\n\n##
          What was measured\n\nKubernetes contributed nothing the test used, while
          the chart's defaults were a large part of the cost: PostgreSQL capped at
          **150m CPU**, and a `netbox-worker` whose `wait-for-backend` init container
          hit `CrashLoopBackOff` and extended `helm --wait`. Image pulls were never
          the issue (netbox, 243 MB, pulled in 20.6s).\n\nComparable phases (provisioning
          + base example seeding), all measured on one 16-core host:\n\n| fixture
          | provisioning | base seeding | total |\n|---|---|---|---|\n| kind + Helm,
          chart defaults (what CI runs today) | 460s | 433s | **893s** |\n| kind +
          Helm, resource caps removed, worker off | 349s | 302s | 651s |\n| **docker
          compose** | **241s** | **272s** | **~504s** |\n\nAlso measured: NetBox's
          expensive startup is one-time per fresh database \u2014 the image's entrypoint
          guards `migrate`/`trace_paths`/`reindex` behind `migrate --check`, so first
          boot took 339s and subsequent boots 50s and 60s.\n\n## Changes\n\n- **`nodeset:
          ubuntu-noble-large`** \u2014 the job ran a Kubernetes control plane, a four-container
          NetBox stack and the Ansible client on `SCS-2V-4-10` (2 vCPU / 4 GB). Node
          size alone was worth 1.53\xD7 on the deploy and 2.19\xD7 on seeding.\n-
          **`tests/e2e/compose.yaml`** \u2014 postgres 17.10 / valkey 8.1 / netbox
          v4.5.10, with healthchecks and `depends_on: service_healthy`. NetBox is
          configured entirely through the environment variables its own baked `configuration.py`
          reads, so no config file is authored; the Helm chart had been *overriding*
          that file. `API_TOKEN_PEPPERS` is deliberately unset, because the image's
          bootstrap only ever creates a v2 token \u2014 which is why a v1 token still
          has to be minted for pynetbox / `netbox.netbox`.\n- **`tests/e2e/deploy_netbox.sh`**
          \u2014 `docker compose up --wait` replaces cluster creation, chart install
          and readiness polling. No port-forward: the API is published on `127.0.0.1:8080`
          directly, removing that process and its liveness guard.\n- **`tests/e2e/run.sh`**
          \u2014 keeps ownership of the lifecycle trap and teardown; diagnostics now
          capture the NetBox *application* log (which was unavailable when diagnosing
          the original failure \u2014 the cause had to be inferred from Kubernetes
          probe events).\n- **`playbooks/pre-sonic-e2e.yml`** \u2014 kind, kubectl
          and Helm installs removed along with their six pinned digests. `ensure-docker`
          already provides `docker-compose-plugin`. The `accept_ra=2` sysctl is retained
          deliberately.\n\n`timeout` stays at 2400.\n\n## Verification\n\nFull local
          run: `make sonic-e2e` exit 0, `OK: exports match the golden files`. **All
          10 device configs byte-identical with no `--regenerate`** \u2014 same NetBox
          version in, same configs out. End to end 9m34s.\n\nWhat this PR is for is
          the CI number: pre+run against the ~2100s baseline. The projection is ~1250\u20131350s,
          extrapolated from 16 cores onto 8 vCPU and therefore unverified.\n\n## Relationship
          to #2483\n\nThis branch contains #2483's commits plus four scenario additions
          plus this migration. It is a draft opened to obtain CI timing; once green,
          the intent is to fold the result back rather than keep two overlapping PRs
          open.\n\n## Not included\n\n- `--parallel 4` seeding (measured 302s \u2192
          167s) \u2014 deferred deliberately, since it is the only change that could
          alter NetBox state non-deterministically, and keeping it separate makes
          a golden mismatch unambiguously attributable.\n- netbox-manager is **untouched**
          and keeps its kind harness, so `netbox-manager-e2e` cannot regress.\n- Removing
          the `accept_ra` workaround, and pinning postgres/valkey by digest.\n\n##
          Known follow-ups\n\n- The harness seeds every file in `tests/e2e/scenario/resources/`,
          tracked or not. Harmless in CI's clean checkout, but local WIP silently
          joins the fixture.\n- `ubuntu-noble-large` has no `min-ready` (`ubuntu-noble`
          has 2), so this job now pays a cold VM boot per run \u2014 queue latency,
          outside the build timeout.\n\n\U0001F916 Generated with [Claude Code](https://claude.com/claude-code)\n"
        change_url: https://github.com/osism/python-osism/pull/2532
        commit_id: 219205b80095bde5ed5d99915f68e530a1832f4b
        patchset: 219205b80095bde5ed5d99915f68e530a1832f4b
        project:
          canonical_hostname: github.com
          canonical_name: github.com/osism/python-osism
          name: osism/python-osism
          short_name: python-osism
          src_dir: src/github.com/osism/python-osism
        topic: null
      job: flake8
      jobtags: []
      max_attempts: 3
      message: U09OaUMgRTJFOiBwcm92aXNpb24gTmV0Qm94IHdpdGggZG9ja2VyIGNvbXBvc2UKCiMjIFB1cnBvc2UKCkRyYWZ0LCBvcGVuZWQgdG8gZ2V0IGEgQ0kgdGltaW5nIG51bWJlciBmb3IgdGhlIGNvbXBvc2UgbWlncmF0aW9uLiBJdCBleHRlbmRzIHRoZSBTT05pQyBFMkUgaGFybmVzcyBmcm9tOgoKLSBvc2lzbS9weXRob24tb3Npc20jMjQ4MwoKd2l0aCBmb3VyIHNjZW5hcmlvIGNvbW1pdHMgYW5kIHRoZW4gcmVwbGFjZXMgdGhlIGtpbmQgKyBIZWxtIE5ldEJveCBmaXh0dXJlIHdpdGggZG9ja2VyIGNvbXBvc2UuIE5vdCBmb3IgcmV2aWV3IHlldCDigJQgc2VlICpSZWxhdGlvbnNoaXAgdG8gIzI0ODMqIGJlbG93LgoKIyMgV2h5CgpgcHl0aG9uLW9zaXNtLXNvbmljLWUyZWAgdGltZWQgb3V0IChidWlsZHNldCBbYDhlYTkxMjM3YF0oaHR0cHM6Ly96dXVsLnNlcnZpY2VzLm9zaXNtLnRlY2gvdC9vc2lzbS9idWlsZHNldC84ZWE5MTIzN2YzMzQ0MjUxODNjNzgxODg2N2NkYTFmNCksIDI0NTdzKS4gSXQgd2FzIGFib3J0ZWQgbWlkLWdlbmVyYXRpb24sIH4yIG1pbnV0ZXMgc2hvcnQgb2YgZmluaXNoaW5nLgoKVGhlIGpvYiBkaWQgbm90IGhhbmcuIFp1dWwncyBgdGltZW91dGAgaXMgb25lIGJ1ZGdldCBzcGFubmluZyAqKnByZS1ydW4gKyBydW4qKiwgYW5kIHRoZSBqb2Igbm9ybWFsbHkgY29uc3VtZWQgODDigJM5MiUgb2YgaXRzIDI0MDBzOiBzZXZlbiBzdWNjZXNzaXZlIHJ1bnMgb2YgaWRlbnRpY2FsIGNvZGUgdG9vayAxOTE54oCTMjIxMnMgcHJlK3J1bi4gV2hhdCB0aXBwZWQgaXQgb3ZlciB3YXMgbm9kZS1sb2NhbCDigJQgYGVuc3VyZS1waXAgOiBVcGRhdGUgcGFja2FnZSBsaXN0c2AgdG9vayAqKjMwMXMqKiBpbnN0ZWFkIG9mIHRoZSB1c3VhbCAy4oCTNnMsIGFkZGluZyB+NDA5cyB0byB0aGUgcHJlLXJ1bi4gTm90IHNoYXJlZC1taXJyb3IgY29udGVudGlvbjogdGhlIHNpYmxpbmcgam9icyBpbiB0aGUgc2FtZSBidWlsZHNldCByYW4gdGhhdCBpZGVudGljYWwgdGFzayBpbiA1cywgMnMgYW5kIDJzLgoKVGhlIHVuZGVybHlpbmcgcHJvYmxlbSB3YXMgdGhhdCB+MTY1MHMgb2YgYSB+MjEwMHMgcnVuIHdhcyBmaXhlZCBzZXR1cDogYGhlbG0gaW5zdGFsbCAtLXdhaXRgIDcwNOKAkzc5MnMgYW5kIHNlZWRpbmcgODg44oCTMTAxMXMuCgojIyBXaGF0IHdhcyBtZWFzdXJlZAoKS3ViZXJuZXRlcyBjb250cmlidXRlZCBub3RoaW5nIHRoZSB0ZXN0IHVzZWQsIHdoaWxlIHRoZSBjaGFydCdzIGRlZmF1bHRzIHdlcmUgYSBsYXJnZSBwYXJ0IG9mIHRoZSBjb3N0OiBQb3N0Z3JlU1FMIGNhcHBlZCBhdCAqKjE1MG0gQ1BVKiosIGFuZCBhIGBuZXRib3gtd29ya2VyYCB3aG9zZSBgd2FpdC1mb3ItYmFja2VuZGAgaW5pdCBjb250YWluZXIgaGl0IGBDcmFzaExvb3BCYWNrT2ZmYCBhbmQgZXh0ZW5kZWQgYGhlbG0gLS13YWl0YC4gSW1hZ2UgcHVsbHMgd2VyZSBuZXZlciB0aGUgaXNzdWUgKG5ldGJveCwgMjQzIE1CLCBwdWxsZWQgaW4gMjAuNnMpLgoKQ29tcGFyYWJsZSBwaGFzZXMgKHByb3Zpc2lvbmluZyArIGJhc2UgZXhhbXBsZSBzZWVkaW5nKSwgYWxsIG1lYXN1cmVkIG9uIG9uZSAxNi1jb3JlIGhvc3Q6Cgp8IGZpeHR1cmUgfCBwcm92aXNpb25pbmcgfCBiYXNlIHNlZWRpbmcgfCB0b3RhbCB8CnwtLS18LS0tfC0tLXwtLS18Cnwga2luZCArIEhlbG0sIGNoYXJ0IGRlZmF1bHRzICh3aGF0IENJIHJ1bnMgdG9kYXkpIHwgNDYwcyB8IDQzM3MgfCAqKjg5M3MqKiB8Cnwga2luZCArIEhlbG0sIHJlc291cmNlIGNhcHMgcmVtb3ZlZCwgd29ya2VyIG9mZiB8IDM0OXMgfCAzMDJzIHwgNjUxcyB8CnwgKipkb2NrZXIgY29tcG9zZSoqIHwgKioyNDFzKiogfCAqKjI3MnMqKiB8ICoqfjUwNHMqKiB8CgpBbHNvIG1lYXN1cmVkOiBOZXRCb3gncyBleHBlbnNpdmUgc3RhcnR1cCBpcyBvbmUtdGltZSBwZXIgZnJlc2ggZGF0YWJhc2Ug4oCUIHRoZSBpbWFnZSdzIGVudHJ5cG9pbnQgZ3VhcmRzIGBtaWdyYXRlYC9gdHJhY2VfcGF0aHNgL2ByZWluZGV4YCBiZWhpbmQgYG1pZ3JhdGUgLS1jaGVja2AsIHNvIGZpcnN0IGJvb3QgdG9vayAzMzlzIGFuZCBzdWJzZXF1ZW50IGJvb3RzIDUwcyBhbmQgNjBzLgoKIyMgQ2hhbmdlcwoKLSAqKmBub2Rlc2V0OiB1YnVudHUtbm9ibGUtbGFyZ2VgKiog4oCUIHRoZSBqb2IgcmFuIGEgS3ViZXJuZXRlcyBjb250cm9sIHBsYW5lLCBhIGZvdXItY29udGFpbmVyIE5ldEJveCBzdGFjayBhbmQgdGhlIEFuc2libGUgY2xpZW50IG9uIGBTQ1MtMlYtNC0xMGAgKDIgdkNQVSAvIDQgR0IpLiBOb2RlIHNpemUgYWxvbmUgd2FzIHdvcnRoIDEuNTPDlyBvbiB0aGUgZGVwbG95IGFuZCAyLjE5w5cgb24gc2VlZGluZy4KLSAqKmB0ZXN0cy9lMmUvY29tcG9zZS55YW1sYCoqIOKAlCBwb3N0Z3JlcyAxNy4xMCAvIHZhbGtleSA4LjEgLyBuZXRib3ggdjQuNS4xMCwgd2l0aCBoZWFsdGhjaGVja3MgYW5kIGBkZXBlbmRzX29uOiBzZXJ2aWNlX2hlYWx0aHlgLiBOZXRCb3ggaXMgY29uZmlndXJlZCBlbnRpcmVseSB0aHJvdWdoIHRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZXMgaXRzIG93biBiYWtlZCBgY29uZmlndXJhdGlvbi5weWAgcmVhZHMsIHNvIG5vIGNvbmZpZyBmaWxlIGlzIGF1dGhvcmVkOyB0aGUgSGVsbSBjaGFydCBoYWQgYmVlbiAqb3ZlcnJpZGluZyogdGhhdCBmaWxlLiBgQVBJX1RPS0VOX1BFUFBFUlNgIGlzIGRlbGliZXJhdGVseSB1bnNldCwgYmVjYXVzZSB0aGUgaW1hZ2UncyBib290c3RyYXAgb25seSBldmVyIGNyZWF0ZXMgYSB2MiB0b2tlbiDigJQgd2hpY2ggaXMgd2h5IGEgdjEgdG9rZW4gc3RpbGwgaGFzIHRvIGJlIG1pbnRlZCBmb3IgcHluZXRib3ggLyBgbmV0Ym94Lm5ldGJveGAuCi0gKipgdGVzdHMvZTJlL2RlcGxveV9uZXRib3guc2hgKiog4oCUIGBkb2NrZXIgY29tcG9zZSB1cCAtLXdhaXRgIHJlcGxhY2VzIGNsdXN0ZXIgY3JlYXRpb24sIGNoYXJ0IGluc3RhbGwgYW5kIHJlYWRpbmVzcyBwb2xsaW5nLiBObyBwb3J0LWZvcndhcmQ6IHRoZSBBUEkgaXMgcHVibGlzaGVkIG9uIGAxMjcuMC4wLjE6ODA4MGAgZGlyZWN0bHksIHJlbW92aW5nIHRoYXQgcHJvY2VzcyBhbmQgaXRzIGxpdmVuZXNzIGd1YXJkLgotICoqYHRlc3RzL2UyZS9ydW4uc2hgKiog4oCUIGtlZXBzIG93bmVyc2hpcCBvZiB0aGUgbGlmZWN5Y2xlIHRyYXAgYW5kIHRlYXJkb3duOyBkaWFnbm9zdGljcyBub3cgY2FwdHVyZSB0aGUgTmV0Qm94ICphcHBsaWNhdGlvbiogbG9nICh3aGljaCB3YXMgdW5hdmFpbGFibGUgd2hlbiBkaWFnbm9zaW5nIHRoZSBvcmlnaW5hbCBmYWlsdXJlIOKAlCB0aGUgY2F1c2UgaGFkIHRvIGJlIGluZmVycmVkIGZyb20gS3ViZXJuZXRlcyBwcm9iZSBldmVudHMpLgotICoqYHBsYXlib29rcy9wcmUtc29uaWMtZTJlLnltbGAqKiDigJQga2luZCwga3ViZWN0bCBhbmQgSGVsbSBpbnN0YWxscyByZW1vdmVkIGFsb25nIHdpdGggdGhlaXIgc2l4IHBpbm5lZCBkaWdlc3RzLiBgZW5zdXJlLWRvY2tlcmAgYWxyZWFkeSBwcm92aWRlcyBgZG9ja2VyLWNvbXBvc2UtcGx1Z2luYC4gVGhlIGBhY2NlcHRfcmE9MmAgc3lzY3RsIGlzIHJldGFpbmVkIGRlbGliZXJhdGVseS4KCmB0aW1lb3V0YCBzdGF5cyBhdCAyNDAwLgoKIyMgVmVyaWZpY2F0aW9uCgpGdWxsIGxvY2FsIHJ1bjogYG1ha2Ugc29uaWMtZTJlYCBleGl0IDAsIGBPSzogZXhwb3J0cyBtYXRjaCB0aGUgZ29sZGVuIGZpbGVzYC4gKipBbGwgMTAgZGV2aWNlIGNvbmZpZ3MgYnl0ZS1pZGVudGljYWwgd2l0aCBubyBgLS1yZWdlbmVyYXRlYCoqIOKAlCBzYW1lIE5ldEJveCB2ZXJzaW9uIGluLCBzYW1lIGNvbmZpZ3Mgb3V0LiBFbmQgdG8gZW5kIDltMzRzLgoKV2hhdCB0aGlzIFBSIGlzIGZvciBpcyB0aGUgQ0kgbnVtYmVyOiBwcmUrcnVuIGFnYWluc3QgdGhlIH4yMTAwcyBiYXNlbGluZS4gVGhlIHByb2plY3Rpb24gaXMgfjEyNTDigJMxMzUwcywgZXh0cmFwb2xhdGVkIGZyb20gMTYgY29yZXMgb250byA4IHZDUFUgYW5kIHRoZXJlZm9yZSB1bnZlcmlmaWVkLgoKIyMgUmVsYXRpb25zaGlwIHRvICMyNDgzCgpUaGlzIGJyYW5jaCBjb250YWlucyAjMjQ4MydzIGNvbW1pdHMgcGx1cyBmb3VyIHNjZW5hcmlvIGFkZGl0aW9ucyBwbHVzIHRoaXMgbWlncmF0aW9uLiBJdCBpcyBhIGRyYWZ0IG9wZW5lZCB0byBvYnRhaW4gQ0kgdGltaW5nOyBvbmNlIGdyZWVuLCB0aGUgaW50ZW50IGlzIHRvIGZvbGQgdGhlIHJlc3VsdCBiYWNrIHJhdGhlciB0aGFuIGtlZXAgdHdvIG92ZXJsYXBwaW5nIFBScyBvcGVuLgoKIyMgTm90IGluY2x1ZGVkCgotIGAtLXBhcmFsbGVsIDRgIHNlZWRpbmcgKG1lYXN1cmVkIDMwMnMg4oaSIDE2N3MpIOKAlCBkZWZlcnJlZCBkZWxpYmVyYXRlbHksIHNpbmNlIGl0IGlzIHRoZSBvbmx5IGNoYW5nZSB0aGF0IGNvdWxkIGFsdGVyIE5ldEJveCBzdGF0ZSBub24tZGV0ZXJtaW5pc3RpY2FsbHksIGFuZCBrZWVwaW5nIGl0IHNlcGFyYXRlIG1ha2VzIGEgZ29sZGVuIG1pc21hdGNoIHVuYW1iaWd1b3VzbHkgYXR0cmlidXRhYmxlLgotIG5ldGJveC1tYW5hZ2VyIGlzICoqdW50b3VjaGVkKiogYW5kIGtlZXBzIGl0cyBraW5kIGhhcm5lc3MsIHNvIGBuZXRib3gtbWFuYWdlci1lMmVgIGNhbm5vdCByZWdyZXNzLgotIFJlbW92aW5nIHRoZSBgYWNjZXB0X3JhYCB3b3JrYXJvdW5kLCBhbmQgcGlubmluZyBwb3N0Z3Jlcy92YWxrZXkgYnkgZGlnZXN0LgoKIyMgS25vd24gZm9sbG93LXVwcwoKLSBUaGUgaGFybmVzcyBzZWVkcyBldmVyeSBmaWxlIGluIGB0ZXN0cy9lMmUvc2NlbmFyaW8vcmVzb3VyY2VzL2AsIHRyYWNrZWQgb3Igbm90LiBIYXJtbGVzcyBpbiBDSSdzIGNsZWFuIGNoZWNrb3V0LCBidXQgbG9jYWwgV0lQIHNpbGVudGx5IGpvaW5zIHRoZSBmaXh0dXJlLgotIGB1YnVudHUtbm9ibGUtbGFyZ2VgIGhhcyBubyBgbWluLXJlYWR5YCAoYHVidW50dS1ub2JsZWAgaGFzIDIpLCBzbyB0aGlzIGpvYiBub3cgcGF5cyBhIGNvbGQgVk0gYm9vdCBwZXIgcnVuIOKAlCBxdWV1ZSBsYXRlbmN5LCBvdXRzaWRlIHRoZSBidWlsZCB0aW1lb3V0LgoK8J+kliBHZW5lcmF0ZWQgd2l0aCBbQ2xhdWRlIENvZGVdKGh0dHBzOi8vY2xhdWRlLmNvbS9jbGF1ZGUtY29kZSkK
      patchset: 219205b80095bde5ed5d99915f68e530a1832f4b
      pipeline: check
      playbook_context:
        playbook_projects:
          trusted/project_0/github.com/osism/zuul-config:
            canonical_name: github.com/osism/zuul-config
            checkout: main
            commit: 71b711c422c10c242a8f785dc6d41ed9d12e9cd3
          trusted/project_1/github.com/osism/openinfra-zuul-jobs:
            canonical_name: github.com/osism/openinfra-zuul-jobs
            checkout: master
            commit: 242732586e2cba04d04867d3e302888c766bc231
          trusted/project_2/github.com/osism/zuul-jobs:
            canonical_name: github.com/osism/zuul-jobs
            checkout: main
            commit: dcb06ea8a3ad422cc9d98b376216617b2daa6a02
          untrusted/project_0/github.com/osism/zuul-jobs:
            canonical_name: github.com/osism/zuul-jobs
            checkout: main
            commit: dcb06ea8a3ad422cc9d98b376216617b2daa6a02
          untrusted/project_1/github.com/osism/zuul-config:
            canonical_name: github.com/osism/zuul-config
            checkout: main
            commit: 71b711c422c10c242a8f785dc6d41ed9d12e9cd3
          untrusted/project_2/github.com/osism/openinfra-zuul-jobs:
            canonical_name: github.com/osism/openinfra-zuul-jobs
            checkout: master
            commit: 242732586e2cba04d04867d3e302888c766bc231
        playbooks:
        - path: untrusted/project_0/github.com/osism/zuul-jobs/playbooks/flake8/run.yaml
          roles:
          - checkout: main
            checkout_description: zuul branch
            link_name: ansible/playbook_0/role_0/zuul-config
            link_target: untrusted/project_1/github.com/osism/zuul-config
            role_path: ansible/playbook_0/role_0/zuul-config/roles
          - checkout: master
            checkout_description: project default branch
            link_name: ansible/playbook_0/role_1/openinfra-zuul-jobs
            link_target: untrusted/project_2/github.com/osism/openinfra-zuul-jobs
            role_path: ansible/playbook_0/role_1/openinfra-zuul-jobs/roles
          - checkout: main
            checkout_description: playbook branch
            link_name: ansible/playbook_0/role_2/zuul-jobs
            link_target: untrusted/project_0/github.com/osism/zuul-jobs
            role_path: ansible/playbook_0/role_2/zuul-jobs/roles
      post_review: false
      post_timeout: 1800
      pre_timeout: null
      project:
        canonical_hostname: github.com
        canonical_name: github.com/osism/python-osism
        name: osism/python-osism
        short_name: python-osism
        src_dir: src/github.com/osism/python-osism
      projects:
        github.com/osism/python-osism:
          canonical_hostname: github.com
          canonical_name: github.com/osism/python-osism
          checkout: main
          checkout_description: zuul branch
          commit: 383b2d8342847d79196417056594c6be3b4300ac
          name: osism/python-osism
          required: false
          short_name: python-osism
          src_dir: src/github.com/osism/python-osism
      ref: refs/pull/2532/head
      resources: {}
      tenant: osism
      timeout: 1800
      topic: null
      voting: true
