magogi/prod/: mgf-cloud-provision-0.1.0 metadata and description

Simple index Newer version available

Declarative, idempotent provisioning of the Magogi Foundation's self-hosted services (devpi, CI agents, Vault, …) on top of mgf-cloud. plan / apply / destroy over a ServiceSpec. Sibling of mgf-cloud under the mgf.* namespace.

author Bassam Alsanie, mgf-cloud-provision contributors
classifiers
  • Development Status :: 2 - Pre-Alpha
  • Intended Audience :: System Administrators
  • License :: OSI Approved :: MIT License
  • Operating System :: POSIX :: Linux
  • Programming Language :: Python :: 3
  • Programming Language :: Python :: 3.11
  • Programming Language :: Python :: 3.12
  • Programming Language :: Python :: 3.13
  • Topic :: System :: Systems Administration
  • Typing :: Typed
description_content_type text/markdown
keywords cloud, iac, infomaniak, infrastructure, openstack, provisioning
license MIT
license_file
  • LICENSE
project_urls
  • Homepage, https://codeberg.org/magogi-admin/mgf-cloud-provision
  • Issues, https://codeberg.org/magogi-admin/mgf-cloud-provision/issues
  • Changelog, https://codeberg.org/magogi-admin/mgf-cloud-provision/src/branch/main/CHANGELOG.md
requires_dist
  • mgf-cloud<0.2,>=0.1.1
  • mgf-common<0.50,>=0.47
  • pydantic<3,>=2.6
  • import-linter<3.0,>=2.0; extra == 'dev'
  • mgf-standard<0.2,>=0.1.6; extra == 'dev'
  • mgf-test-supervisor<0.2,>=0.1.3; extra == 'dev'
  • mypy>=1.10; extra == 'dev'
  • pytest-cov>=5.0; extra == 'dev'
  • pytest-timeout<3,>=2.3; extra == 'dev'
  • pytest>=8.0; extra == 'dev'
  • ruff<0.16,>=0.4; extra == 'dev'
  • mgf-cloud[infomaniak]<0.2,>=0.1.1; extra == 'infomaniak'
  • mgf-common[standards]<0.50,>=0.47; extra == 'standards'
requires_python >=3.11

Because this project isn't in the mirror_whitelist, no releases from root/pypi are included.

File Tox results History
mgf_cloud_provision-0.1.0-py3-none-any.whl
Size
13 KB
Type
Python Wheel
Python
3
mgf_cloud_provision-0.1.0.tar.gz
Size
40 KB
Type
Source

mgf-cloud-provision

Shape. Magogi Foundation infrastructure library. Declarative, idempotent provisioning of the federation's own self-hosted services on Infomaniak Public Cloud. Status. Pre-0.1.0 skeleton (Phase 1a). The core API + the devpi service spec exist and run end-to-end against mgf-cloud's in-memory FakeProvider; the live provider + cloud-init converge land in Phase 1b.

mgf-cloud-provision sits above mgf-cloud (the OpenStack/Infomaniak adapter). Where mgf-cloud is "talk to OpenStack," this is "declare + converge our services." A ServiceSpec describes the desired state of one service-bearing VM (devpi, a CI agent, Vault, …) as a VM + cloud-init; plan / apply / destroy converge the cloud to it.

from mgf.cloud.providers import get_provider
from mgf.cloud_provision import devpi_service_spec, plan, apply

spec = devpi_service_spec(key_name="woodpecker-key")
print(plan(spec, get_provider("fake")).action)      # Action.CREATE
apply(spec, get_provider("fake"))                    # creates the VM (fake, in-memory)

CLI:

mgf-cloud-provision plan    examples/devpi.toml --provider fake
mgf-cloud-provision apply   examples/devpi.toml --provider fake --yes
mgf-cloud-provision destroy examples/devpi.toml --provider fake --yes

The whole surface runs with no cloud and no credentials (the fake provider), so it is fully testable in CI. The real provider (--provider infomaniak) loads credentials via mgf.cloud.config.load.

First customer — devpi

The reason this library exists now is the self-hosted package index rollout (replacing the Codeberg PyPI registry — closes the dependency-confusion findings of the 2026-06-18 CI audit). devpi_service_spec() / examples/devpi.toml encode the Phase-0-resolved sizing: a2-ram4-disk50-perf1 on ext-net1, reachable at <ip>.sslip.io. See the rollout plan in ~/.claude/plans/plan-self-hosted-pypi-sequencing-2026-06-18.md.

CI host — Woodpecker

Full operator runbook: docs/woodpecker-ci-runbook.md (architecture, hosts/access, secrets, self-healing, operations, failure-mode catalogue, rebuild).

The federation's self-hosted Woodpecker CI runs from examples/woodpecker-compose.yml (server + Postgres + agent + Caddy auto-TLS) — the sanitized live /opt/woodpecker compose, with every secret a ${VAR} sourced from .env (template: examples/woodpecker.env.example). The server was migrated SQLite → Postgres on 2026-06-21 to remove the single-writer "database is locked" ceiling that surfaced under fleet-wide CI bursts.

A second agent on its own VM (examples/woodpecker-agent.toml + examples/woodpecker-agent-cloud-init.yml) removes the single-agent / single-Docker-daemon ceiling — it connects to the server's gRPC over TLS (a Caddy h2c proxy at grpc.<server-domain>:443; WOODPECKER_GRPC_SECURE=true). The shared WOODPECKER_AGENT_SECRET and the netrc are injected post-provision over SSH, never committed. Fleet capacity is now 2 agents × MAX_WORKFLOWS=2 = 4 concurrent workflows.

Two self-healing crons keep the agents honest: self-heal.sh (every 5 min, reaps leaked wp_* Docker debris from daemon-teardown timeouts) and examples/agent-reconciler.py (every 3 min on the server host) — the reconciler recovers the "connected but not scheduling" state (an agent whose server-side worker slots were orphaned, sitting idle while work pends) by restarting that agent (local docker compose, or agent2 over SSH). It reads its API token + agent2 SSH key from root-600 files on the host (/opt/woodpecker/reconciler.token, /opt/woodpecker/agent2_id), never committed; cron: */3 * * * * python3 /opt/woodpecker/agent-reconciler.py.

Four green gates

ruff check src tests
mypy src
pytest --cov --cov-fail-under=80
lint-imports

Roadmap

License

MIT.