infralink-ops 0.2.67__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- infralink_ops-0.2.67/.github/workflows/publish-pypi.yml +91 -0
- infralink_ops-0.2.67/.gitignore +5 -0
- infralink_ops-0.2.67/.woodpecker.yml +56 -0
- infralink_ops-0.2.67/Dockerfile +18 -0
- infralink_ops-0.2.67/Dockerfile.controller +60 -0
- infralink_ops-0.2.67/Dockerfile.ops +11 -0
- infralink_ops-0.2.67/PKG-INFO +158 -0
- infralink_ops-0.2.67/README.md +143 -0
- infralink_ops-0.2.67/docs/controller-runtime-guide.md +72 -0
- infralink_ops-0.2.67/docs/superpowers/plans/2026-08-22-static-config-trees.md +255 -0
- infralink_ops-0.2.67/docs/superpowers/plans/2026-08-23-public-firewall-runtime.md +48 -0
- infralink_ops-0.2.67/docs/superpowers/plans/2026-08-25-declared-template-sources.md +30 -0
- infralink_ops-0.2.67/docs/superpowers/plans/2026-08-26-independent-artifact-renderer-source.md +49 -0
- infralink_ops-0.2.67/docs/superpowers/specs/2026-08-26-independent-artifact-renderer-source-design.md +17 -0
- infralink_ops-0.2.67/gitea-hooks/entrypoint +5 -0
- infralink_ops-0.2.67/gitea-hooks/install-receive-gate +11 -0
- infralink_ops-0.2.67/gitea-hooks/pre-receive-gitleaks +25 -0
- infralink_ops-0.2.67/pyproject.toml +58 -0
- infralink_ops-0.2.67/src/infralink_ops/__init__.py +60 -0
- infralink_ops-0.2.67/src/infralink_ops/artifact_installer.py +127 -0
- infralink_ops-0.2.67/src/infralink_ops/artifact_renderer_source.py +94 -0
- infralink_ops-0.2.67/src/infralink_ops/artifact_target_install.py +187 -0
- infralink_ops-0.2.67/src/infralink_ops/assets/infralink +73 -0
- infralink_ops-0.2.67/src/infralink_ops/assets/infralink-host +112 -0
- infralink_ops-0.2.67/src/infralink_ops/assets/infralink-host-reconcile.service +8 -0
- infralink_ops-0.2.67/src/infralink_ops/assets/infralink-host-reconcile.timer +11 -0
- infralink_ops-0.2.67/src/infralink_ops/bounded_process.py +409 -0
- infralink_ops-0.2.67/src/infralink_ops/canonical_json.py +57 -0
- infralink_ops-0.2.67/src/infralink_ops/cli.py +34 -0
- infralink_ops-0.2.67/src/infralink_ops/compose_binds.py +67 -0
- infralink_ops-0.2.67/src/infralink_ops/compose_state_protocol.py +656 -0
- infralink_ops-0.2.67/src/infralink_ops/config_trees.py +478 -0
- infralink_ops-0.2.67/src/infralink_ops/controller_adapter.py +86 -0
- infralink_ops-0.2.67/src/infralink_ops/controller_adapter_runnable.py +85 -0
- infralink_ops-0.2.67/src/infralink_ops/controller_artifacts.py +220 -0
- infralink_ops-0.2.67/src/infralink_ops/controller_bootstrap.py +406 -0
- infralink_ops-0.2.67/src/infralink_ops/controller_config_consumers.py +328 -0
- infralink_ops-0.2.67/src/infralink_ops/controller_doctor.py +333 -0
- infralink_ops-0.2.67/src/infralink_ops/controller_firewall.py +136 -0
- infralink_ops-0.2.67/src/infralink_ops/controller_host_interface.py +234 -0
- infralink_ops-0.2.67/src/infralink_ops/controller_images.py +184 -0
- infralink_ops-0.2.67/src/infralink_ops/controller_metrics.py +161 -0
- infralink_ops-0.2.67/src/infralink_ops/controller_protected_transitions.py +244 -0
- infralink_ops-0.2.67/src/infralink_ops/controller_reconcile_evidence.py +223 -0
- infralink_ops-0.2.67/src/infralink_ops/controller_registry_checkout.py +103 -0
- infralink_ops-0.2.67/src/infralink_ops/controller_render_secrets.py +174 -0
- infralink_ops-0.2.67/src/infralink_ops/controller_runtime_directories.py +210 -0
- infralink_ops-0.2.67/src/infralink_ops/dashboards.py +186 -0
- infralink_ops-0.2.67/src/infralink_ops/declared_file_destination.py +61 -0
- infralink_ops-0.2.67/src/infralink_ops/egress_snat.py +241 -0
- infralink_ops-0.2.67/src/infralink_ops/firewall.py +293 -0
- infralink_ops-0.2.67/src/infralink_ops/host_interface_assets.py +23 -0
- infralink_ops-0.2.67/src/infralink_ops/image_resolution.py +253 -0
- infralink_ops-0.2.67/src/infralink_ops/observation.py +47 -0
- infralink_ops-0.2.67/src/infralink_ops/registry_checkout.py +146 -0
- infralink_ops-0.2.67/src/infralink_ops/registry_transport_trust.py +96 -0
- infralink_ops-0.2.67/src/infralink_ops/stable_regular_file.py +66 -0
- infralink_ops-0.2.67/src/infralink_ops/template_dependencies.py +133 -0
- infralink_ops-0.2.67/src/infralink_ops/template_renderer.py +492 -0
- infralink_ops-0.2.67/src/infralink_ops/template_source_dependencies.py +148 -0
- infralink_ops-0.2.67/src/infralink_ops/template_sources.py +99 -0
- infralink_ops-0.2.67/src/infralink_ops/typed_artifact_materializer.py +294 -0
- infralink_ops-0.2.67/tests/receive-gate.sh +44 -0
- infralink_ops-0.2.67/tests/runtime-image.sh +46 -0
- infralink_ops-0.2.67/tests/test_artifact_installer.py +71 -0
- infralink_ops-0.2.67/tests/test_artifact_renderer_source.py +90 -0
- infralink_ops-0.2.67/tests/test_artifact_target_install.py +137 -0
- infralink_ops-0.2.67/tests/test_bounded_process.py +693 -0
- infralink_ops-0.2.67/tests/test_canonical_json.py +29 -0
- infralink_ops-0.2.67/tests/test_compose_binds.py +88 -0
- infralink_ops-0.2.67/tests/test_compose_state_protocol.py +243 -0
- infralink_ops-0.2.67/tests/test_config_trees.py +476 -0
- infralink_ops-0.2.67/tests/test_controller_adapter_runnable.py +209 -0
- infralink_ops-0.2.67/tests/test_controller_adapter_transport.py +176 -0
- infralink_ops-0.2.67/tests/test_controller_artifacts.py +271 -0
- infralink_ops-0.2.67/tests/test_controller_bootstrap.py +313 -0
- infralink_ops-0.2.67/tests/test_controller_config_consumers.py +381 -0
- infralink_ops-0.2.67/tests/test_controller_doctor.py +413 -0
- infralink_ops-0.2.67/tests/test_controller_firewall.py +161 -0
- infralink_ops-0.2.67/tests/test_controller_host_interface.py +135 -0
- infralink_ops-0.2.67/tests/test_controller_image_recipe.py +25 -0
- infralink_ops-0.2.67/tests/test_controller_images.py +199 -0
- infralink_ops-0.2.67/tests/test_controller_metrics.py +164 -0
- infralink_ops-0.2.67/tests/test_controller_protected_transitions.py +78 -0
- infralink_ops-0.2.67/tests/test_controller_reconcile_evidence.py +267 -0
- infralink_ops-0.2.67/tests/test_controller_registry_checkout.py +110 -0
- infralink_ops-0.2.67/tests/test_controller_render_secrets.py +94 -0
- infralink_ops-0.2.67/tests/test_controller_runtime_directories.py +193 -0
- infralink_ops-0.2.67/tests/test_dashboard_catalog.py +161 -0
- infralink_ops-0.2.67/tests/test_declared_file_destination.py +43 -0
- infralink_ops-0.2.67/tests/test_direct_projection.py +85 -0
- infralink_ops-0.2.67/tests/test_docs_contract.py +134 -0
- infralink_ops-0.2.67/tests/test_egress_snat.py +397 -0
- infralink_ops-0.2.67/tests/test_firewall.py +224 -0
- infralink_ops-0.2.67/tests/test_github_pypi_publish_policy.py +84 -0
- infralink_ops-0.2.67/tests/test_host_interface_assets.py +67 -0
- infralink_ops-0.2.67/tests/test_image_resolution.py +140 -0
- infralink_ops-0.2.67/tests/test_registry_checkout.py +217 -0
- infralink_ops-0.2.67/tests/test_registry_transport_trust.py +46 -0
- infralink_ops-0.2.67/tests/test_stable_regular_file.py +66 -0
- infralink_ops-0.2.67/tests/test_template_dependencies.py +153 -0
- infralink_ops-0.2.67/tests/test_template_renderer.py +473 -0
- infralink_ops-0.2.67/tests/test_template_source_dependencies.py +124 -0
- infralink_ops-0.2.67/tests/test_typed_artifact_materializer.py +389 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
name: Publish Python package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
tag:
|
|
7
|
+
description: Existing Infralink Ops release tag to publish to TestPyPI
|
|
8
|
+
required: true
|
|
9
|
+
type: string
|
|
10
|
+
release:
|
|
11
|
+
types: [published]
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
build:
|
|
18
|
+
name: Build distributions
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
steps:
|
|
21
|
+
- name: Check out repository
|
|
22
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
23
|
+
with:
|
|
24
|
+
persist-credentials: false
|
|
25
|
+
ref: refs/tags/${{ github.event.release.tag_name || inputs.tag }}
|
|
26
|
+
- name: Set up Python
|
|
27
|
+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
28
|
+
with:
|
|
29
|
+
python-version: "3.12"
|
|
30
|
+
- name: Install release dependencies
|
|
31
|
+
env:
|
|
32
|
+
PIP_EXTRA_INDEX_URL: ${{ github.event_name == 'workflow_dispatch' && 'https://test.pypi.org/simple' || '' }}
|
|
33
|
+
run: python -m pip install --disable-pip-version-check "twine>=6.0" -e ".[dev]"
|
|
34
|
+
- name: Verify release tag
|
|
35
|
+
env:
|
|
36
|
+
RELEASE_TAG: ${{ github.event.release.tag_name || inputs.tag }}
|
|
37
|
+
run: >-
|
|
38
|
+
python -c "import os, tomllib;
|
|
39
|
+
version = tomllib.load(open('pyproject.toml', 'rb'))['project']['version'];
|
|
40
|
+
actual = os.environ['RELEASE_TAG']; expected = f'v{version}';
|
|
41
|
+
assert actual == expected, f'release tag {actual!r} must equal {expected!r}'"
|
|
42
|
+
- name: Build distributions
|
|
43
|
+
run: python -m build
|
|
44
|
+
- name: Validate distribution metadata
|
|
45
|
+
run: python -m twine check dist/*
|
|
46
|
+
- name: Store distributions
|
|
47
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
48
|
+
with:
|
|
49
|
+
name: python-package-distributions
|
|
50
|
+
path: dist/
|
|
51
|
+
if-no-files-found: error
|
|
52
|
+
|
|
53
|
+
publish-testpypi:
|
|
54
|
+
name: Publish to TestPyPI
|
|
55
|
+
if: github.event_name == 'workflow_dispatch'
|
|
56
|
+
needs: build
|
|
57
|
+
runs-on: ubuntu-latest
|
|
58
|
+
environment:
|
|
59
|
+
name: testpypi
|
|
60
|
+
url: https://test.pypi.org/p/infralink-ops
|
|
61
|
+
permissions:
|
|
62
|
+
id-token: write
|
|
63
|
+
steps:
|
|
64
|
+
- name: Retrieve distributions
|
|
65
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
66
|
+
with:
|
|
67
|
+
name: python-package-distributions
|
|
68
|
+
path: dist/
|
|
69
|
+
- name: Publish distributions
|
|
70
|
+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
|
|
71
|
+
with:
|
|
72
|
+
repository-url: https://test.pypi.org/legacy/
|
|
73
|
+
|
|
74
|
+
publish-pypi:
|
|
75
|
+
name: Publish to PyPI
|
|
76
|
+
if: github.event_name == 'release'
|
|
77
|
+
needs: build
|
|
78
|
+
runs-on: ubuntu-latest
|
|
79
|
+
environment:
|
|
80
|
+
name: pypi
|
|
81
|
+
url: https://pypi.org/p/infralink-ops
|
|
82
|
+
permissions:
|
|
83
|
+
id-token: write
|
|
84
|
+
steps:
|
|
85
|
+
- name: Retrieve distributions
|
|
86
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
87
|
+
with:
|
|
88
|
+
name: python-package-distributions
|
|
89
|
+
path: dist/
|
|
90
|
+
- name: Publish distributions
|
|
91
|
+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
steps:
|
|
2
|
+
docs-contract:
|
|
3
|
+
image: python:3.12-slim-bookworm
|
|
4
|
+
commands:
|
|
5
|
+
- python -m pip install --disable-pip-version-check pytest
|
|
6
|
+
- python -m pytest -q tests/test_docs_contract.py
|
|
7
|
+
|
|
8
|
+
test-python:
|
|
9
|
+
image: python:3.12-slim-bookworm
|
|
10
|
+
commands:
|
|
11
|
+
- sed -i 's|http://deb.debian.org|https://deb.debian.org|g' /etc/apt/sources.list.d/debian.sources
|
|
12
|
+
- apt-get update && apt-get install --yes --no-install-recommends git && rm -rf /var/lib/apt/lists/*
|
|
13
|
+
# Infralink is distributed from GitHub rather than a package index. Keep this
|
|
14
|
+
# CI fixture deterministic while the package declaration admits 0.6.x.
|
|
15
|
+
- python -m pip install --disable-pip-version-check 'infralink @ https://github.com/cyberstorm-dev/infralink/releases/download/v0.6.14/infralink-0.6.14-py3-none-any.whl#sha256=e41e16e082df50d7506785feb40dc3ea48087d46c391e31f2bd77e3ef81ce0e3'
|
|
16
|
+
- python -m pip install --disable-pip-version-check -e '.[dev]'
|
|
17
|
+
- python -m ruff check src tests
|
|
18
|
+
- python -m ruff format --check src tests
|
|
19
|
+
- python -m pytest -q
|
|
20
|
+
- python -m build
|
|
21
|
+
- python -m venv /tmp/infralink-ops-wheel
|
|
22
|
+
- /tmp/infralink-ops-wheel/bin/pip install --disable-pip-version-check 'infralink @ https://github.com/cyberstorm-dev/infralink/releases/download/v0.6.14/infralink-0.6.14-py3-none-any.whl#sha256=e41e16e082df50d7506785feb40dc3ea48087d46c391e31f2bd77e3ef81ce0e3'
|
|
23
|
+
- /tmp/infralink-ops-wheel/bin/pip install --disable-pip-version-check dist/*.whl
|
|
24
|
+
- cd /tmp && /tmp/infralink-ops-wheel/bin/python -c 'import infralink_ops'
|
|
25
|
+
|
|
26
|
+
build-infralink-ops-controller:
|
|
27
|
+
image: woodpeckerci/plugin-docker-buildx
|
|
28
|
+
settings:
|
|
29
|
+
registry: ghcr.io
|
|
30
|
+
repo: ghcr.io/cyberstorm-dev/infralink-ops-controller
|
|
31
|
+
dockerfile: Dockerfile.controller
|
|
32
|
+
context: .
|
|
33
|
+
dry_run: true
|
|
34
|
+
tags:
|
|
35
|
+
- local-test-${CI_COMMIT_SHA:0:7}
|
|
36
|
+
|
|
37
|
+
publish-infralink-ops-controller:
|
|
38
|
+
image: woodpeckerci/plugin-docker-buildx
|
|
39
|
+
depends_on:
|
|
40
|
+
- build-infralink-ops-controller
|
|
41
|
+
when:
|
|
42
|
+
- event: push
|
|
43
|
+
branch: main
|
|
44
|
+
settings:
|
|
45
|
+
registry: ghcr.io
|
|
46
|
+
repo: ghcr.io/cyberstorm-dev/infralink-ops-controller
|
|
47
|
+
dockerfile: Dockerfile.controller
|
|
48
|
+
context: .
|
|
49
|
+
tags:
|
|
50
|
+
- head
|
|
51
|
+
- main
|
|
52
|
+
- sha-${CI_COMMIT_SHA:0:7}
|
|
53
|
+
username:
|
|
54
|
+
from_secret: ghcr_username
|
|
55
|
+
password:
|
|
56
|
+
from_secret: ghcr_token
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
ARG GITEA_IMAGE=gitea/gitea:1.27.2
|
|
2
|
+
ARG GITLEAKS_IMAGE=zricethezav/gitleaks:v8.30.0
|
|
3
|
+
|
|
4
|
+
FROM ${GITLEAKS_IMAGE} AS gitleaks
|
|
5
|
+
|
|
6
|
+
FROM ${GITEA_IMAGE}
|
|
7
|
+
|
|
8
|
+
USER root
|
|
9
|
+
COPY --from=gitleaks /usr/bin/gitleaks /usr/local/bin/gitleaks
|
|
10
|
+
COPY gitea-hooks/pre-receive-gitleaks /usr/local/lib/infralink-gitea-hooks/pre-receive-gitleaks
|
|
11
|
+
COPY gitea-hooks/install-receive-gate /usr/local/lib/infralink-gitea-hooks/install-receive-gate
|
|
12
|
+
COPY gitea-hooks/entrypoint /usr/local/bin/infralink-gitea-entrypoint
|
|
13
|
+
RUN chmod 0755 /usr/local/lib/infralink-gitea-hooks/* \
|
|
14
|
+
/usr/local/bin/infralink-gitea-entrypoint \
|
|
15
|
+
&& mkdir -p /usr/local/share/infralink-gitea/git-template/hooks/pre-receive.d \
|
|
16
|
+
&& cp /usr/local/lib/infralink-gitea-hooks/pre-receive-gitleaks /usr/local/share/infralink-gitea/git-template/hooks/pre-receive.d/20-infralink-gitleaks \
|
|
17
|
+
&& git config --system init.templateDir /usr/local/share/infralink-gitea/git-template
|
|
18
|
+
ENTRYPOINT ["/usr/local/bin/infralink-gitea-entrypoint"]
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
FROM python@sha256:57cd7c3a7a273101a6485ba99423ee568157882804b1124b4dd04266317710de
|
|
2
|
+
|
|
3
|
+
ARG BWS_VERSION=1.0.0
|
|
4
|
+
|
|
5
|
+
ENV DEBIAN_FRONTEND=noninteractive \
|
|
6
|
+
PYTHONDONTWRITEBYTECODE=1 \
|
|
7
|
+
PYTHONUNBUFFERED=1
|
|
8
|
+
|
|
9
|
+
RUN sed -i 's|http://deb.debian.org|https://deb.debian.org|g' /etc/apt/sources.list.d/debian.sources \
|
|
10
|
+
&& apt-get update -qq \
|
|
11
|
+
&& apt-get install -y -qq --no-install-recommends \
|
|
12
|
+
ca-certificates \
|
|
13
|
+
curl \
|
|
14
|
+
git \
|
|
15
|
+
gnupg \
|
|
16
|
+
iptables \
|
|
17
|
+
jq \
|
|
18
|
+
lsb-release \
|
|
19
|
+
nftables \
|
|
20
|
+
openssh-client \
|
|
21
|
+
unzip \
|
|
22
|
+
util-linux \
|
|
23
|
+
yq \
|
|
24
|
+
&& install -m 0755 -d /etc/apt/keyrings \
|
|
25
|
+
&& curl -fsSL https://download.docker.com/linux/debian/gpg \
|
|
26
|
+
| gpg --dearmor -o /etc/apt/keyrings/docker.gpg \
|
|
27
|
+
&& chmod a+r /etc/apt/keyrings/docker.gpg \
|
|
28
|
+
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(. /etc/os-release && echo \"$VERSION_CODENAME\") stable" \
|
|
29
|
+
> /etc/apt/sources.list.d/docker.list \
|
|
30
|
+
&& apt-get update -qq \
|
|
31
|
+
&& apt-get install -y -qq --no-install-recommends docker-ce-cli docker-compose-plugin \
|
|
32
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
33
|
+
|
|
34
|
+
RUN curl -fsSL "https://github.com/bitwarden/sdk/releases/download/bws-v${BWS_VERSION}/bws-x86_64-unknown-linux-gnu-${BWS_VERSION}.zip" \
|
|
35
|
+
-o /tmp/bws.zip \
|
|
36
|
+
&& unzip -q /tmp/bws.zip -d /tmp \
|
|
37
|
+
&& install -m 0755 /tmp/bws /usr/local/bin/bws \
|
|
38
|
+
&& rm -f /tmp/bws.zip /tmp/bws
|
|
39
|
+
|
|
40
|
+
WORKDIR /app
|
|
41
|
+
|
|
42
|
+
COPY pyproject.toml README.md ./
|
|
43
|
+
COPY src ./src
|
|
44
|
+
# Infralink is not published to a package index; pin the controller build input
|
|
45
|
+
# while pyproject.toml expresses the supported 0.6.x compatibility range.
|
|
46
|
+
RUN python -m pip install --disable-pip-version-check --no-cache-dir \
|
|
47
|
+
'infralink @ https://github.com/cyberstorm-dev/infralink/releases/download/v0.6.14/infralink-0.6.14-py3-none-any.whl#sha256=e41e16e082df50d7506785feb40dc3ea48087d46c391e31f2bd77e3ef81ce0e3' \
|
|
48
|
+
&& python -m pip install --disable-pip-version-check --no-cache-dir . \
|
|
49
|
+
&& command -v infralink-controller-registry-checkout \
|
|
50
|
+
&& command -v infralink-controller-config-consumers \
|
|
51
|
+
&& command -v infralink-controller-adapter \
|
|
52
|
+
&& command -v infralink-controller-runtime-directories \
|
|
53
|
+
&& command -v infralink-controller-host-interface \
|
|
54
|
+
&& command -v infralink-controller-doctor \
|
|
55
|
+
&& command -v infralink-controller-firewall \
|
|
56
|
+
&& command -v infralink-controller-image-resolution \
|
|
57
|
+
&& command -v infralink-controller-reference \
|
|
58
|
+
&& command -v infralink-controller-template-dependencies
|
|
59
|
+
|
|
60
|
+
CMD ["infralink-ops", "--help"]
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
FROM python:3.12-slim-bookworm
|
|
2
|
+
|
|
3
|
+
WORKDIR /app
|
|
4
|
+
RUN apt-get update \
|
|
5
|
+
&& apt-get install --yes --no-install-recommends git \
|
|
6
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
7
|
+
COPY pyproject.toml README.md ./
|
|
8
|
+
COPY src ./src
|
|
9
|
+
RUN python -m pip install --disable-pip-version-check .
|
|
10
|
+
|
|
11
|
+
ENTRYPOINT ["infralink-ops"]
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: infralink-ops
|
|
3
|
+
Version: 0.2.67
|
|
4
|
+
Summary: Operational runtime for direct Infralink registry projections
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Requires-Dist: infralink<0.7,>=0.6
|
|
7
|
+
Requires-Dist: jinja2>=3.0
|
|
8
|
+
Requires-Dist: pyyaml>=6.0
|
|
9
|
+
Provides-Extra: dev
|
|
10
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
11
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
12
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
13
|
+
Requires-Dist: twine>=6.0; extra == 'dev'
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# Infralink Ops
|
|
17
|
+
|
|
18
|
+
## BLUF
|
|
19
|
+
|
|
20
|
+
This repo packages the public controller runtime for managed hosts. Deployment
|
|
21
|
+
intent, private templates, and secret aliases remain in the environment
|
|
22
|
+
registry; live-service acceptance remains environment-owned operational state.
|
|
23
|
+
|
|
24
|
+
Use it when you need bounded host primitives for registry checkout, template
|
|
25
|
+
rendering, config projection, Docker image retention, Compose consumer
|
|
26
|
+
activation, firewall verification, secret rendering, or host doctor evidence.
|
|
27
|
+
|
|
28
|
+
Do not use this repo to select fleet desired state. Registry revisions, service
|
|
29
|
+
definitions, image pins, hostnames, and secret bindings come from the
|
|
30
|
+
environment registry.
|
|
31
|
+
|
|
32
|
+
## Reader Paths
|
|
33
|
+
|
|
34
|
+
| Goal | Start here |
|
|
35
|
+
| --- | --- |
|
|
36
|
+
| Understand the runtime boundary | [Controller runtime guide](docs/controller-runtime-guide.md) |
|
|
37
|
+
| Debug a stale RelayOS staging rollout | [Controller runtime guide](docs/controller-runtime-guide.md#triage-a-stale-host) |
|
|
38
|
+
| Check available CLIs | [`pyproject.toml`](pyproject.toml) |
|
|
39
|
+
| Inspect host-installed launcher assets | [`src/infralink_ops/assets/`](src/infralink_ops/assets/) |
|
|
40
|
+
| Review controller behavior | [`src/infralink_ops/`](src/infralink_ops/) and [`tests/`](tests/) |
|
|
41
|
+
|
|
42
|
+
## How It Fits
|
|
43
|
+
|
|
44
|
+
```mermaid
|
|
45
|
+
flowchart LR
|
|
46
|
+
registry["configured registry revision"] --> checkout["/var/lib/infralink/registry"]
|
|
47
|
+
checkout --> render["template render and static config projection"]
|
|
48
|
+
render --> consumers["Compose consumer validate/activate"]
|
|
49
|
+
consumers --> evidence["doctor, metrics, and logs"]
|
|
50
|
+
evidence --> operator["environment-owned acceptance"]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
This repo implements the bounded primitives in the middle of the flow. It does
|
|
54
|
+
not own the registry data model or the environment-specific acceptance result.
|
|
55
|
+
|
|
56
|
+
## Main CLIs
|
|
57
|
+
|
|
58
|
+
| Command | Purpose |
|
|
59
|
+
| --- | --- |
|
|
60
|
+
| `infralink-controller-registry-checkout fetch` | Fetch a declared registry ref into an existing clean checkout. |
|
|
61
|
+
| `infralink-controller-template-render` | Render registry-declared templates from explicit inputs. |
|
|
62
|
+
| `infralink-controller-config-consumers validate\|activate` | Validate or recreate services affected by rendered config changes. |
|
|
63
|
+
| `infralink-controller-images retain-and-prune` | Keep selected immutable Docker images and prune stale cache images. |
|
|
64
|
+
| `infralink-controller-render-secrets` | Resolve registry-declared render-secret bindings through BWS. |
|
|
65
|
+
| `infralink-controller-firewall render\|verify` | Render or verify declared nftables policy. |
|
|
66
|
+
| `infralink-controller-doctor` | Read-only host-runtime check for registry, reconcile, Compose, firewall, and metrics evidence. |
|
|
67
|
+
| `infralink-host doctor\|reconcile\|bootstrap --apply` | Host launcher installed from [`src/infralink_ops/assets/infralink-host`](src/infralink_ops/assets/infralink-host). |
|
|
68
|
+
|
|
69
|
+
Each command is intentionally narrow. Commands receive explicit inputs and
|
|
70
|
+
return bounded machine-readable envelopes where possible.
|
|
71
|
+
|
|
72
|
+
## Authority Boundary
|
|
73
|
+
|
|
74
|
+
| This repo owns | This repo does not own |
|
|
75
|
+
| --- | --- |
|
|
76
|
+
| Controller image build recipe. | Which registry revision a host should run. |
|
|
77
|
+
| Host launcher and systemd unit assets. | Service definitions, hostnames, DNS, certificates, or image pins. |
|
|
78
|
+
| Runtime primitives with bounded inputs and outputs. | Tenant or application policy. |
|
|
79
|
+
| Doctor and evidence helpers. | Live-service acceptance criteria. |
|
|
80
|
+
| BWS resolution primitive. | BWS secret values or registry secret declarations. |
|
|
81
|
+
|
|
82
|
+
For RelayOS IRC, source/config/image repos feed the registry first:
|
|
83
|
+
|
|
84
|
+
```mermaid
|
|
85
|
+
flowchart LR
|
|
86
|
+
deploy["relayos-deploy docs and deploy contract"]
|
|
87
|
+
config["relayos-irc-config"]
|
|
88
|
+
modules["custom-modules"]
|
|
89
|
+
images["relayos-irc-containers"]
|
|
90
|
+
registry["infra-registry"]
|
|
91
|
+
ops["infralink-ops controller"]
|
|
92
|
+
host["managed host"]
|
|
93
|
+
|
|
94
|
+
config --> registry
|
|
95
|
+
modules --> images
|
|
96
|
+
images --> deploy
|
|
97
|
+
deploy --> registry
|
|
98
|
+
registry --> ops
|
|
99
|
+
ops --> host
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## GHCR and BWS
|
|
103
|
+
|
|
104
|
+
The controller image publishes to
|
|
105
|
+
[cyberstorm-dev packages](https://github.com/orgs/cyberstorm-dev/packages) as
|
|
106
|
+
`ghcr.io/cyberstorm-dev/infralink-ops-controller`.
|
|
107
|
+
|
|
108
|
+
BWS access is runtime-only. This repo contains the resolver and tests for the
|
|
109
|
+
resolver contract; the token and secret object names belong to the environment
|
|
110
|
+
registry and host runtime.
|
|
111
|
+
|
|
112
|
+
## Verify Changes
|
|
113
|
+
|
|
114
|
+
Run the same checks Woodpecker runs:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
python -m pip install --disable-pip-version-check \
|
|
118
|
+
'infralink @ https://github.com/cyberstorm-dev/infralink/releases/download/v0.6.14/infralink-0.6.14-py3-none-any.whl#sha256=e41e16e082df50d7506785feb40dc3ea48087d46c391e31f2bd77e3ef81ce0e3'
|
|
119
|
+
python -m pip install --disable-pip-version-check -e '.[dev]'
|
|
120
|
+
python -m ruff check src tests
|
|
121
|
+
python -m ruff format --check src tests
|
|
122
|
+
python -m pytest -q
|
|
123
|
+
python -m build
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Infralink Ops declares compatibility with Infralink `>=0.6,<0.7`. Until
|
|
127
|
+
Infralink is published to PyPI, bootstrap a released, checksum-pinned wheel
|
|
128
|
+
before installing Ops so a clean environment does not attempt an unavailable
|
|
129
|
+
index resolution.
|
|
130
|
+
|
|
131
|
+
The controller image publish step runs only on `main` pushes. Pull requests use
|
|
132
|
+
Docker buildx dry-run validation.
|
|
133
|
+
|
|
134
|
+
## Triage A Stale Host
|
|
135
|
+
|
|
136
|
+
Check in this order:
|
|
137
|
+
|
|
138
|
+
1. Confirm the environment selected the intended registry revision.
|
|
139
|
+
2. Confirm `/var/lib/infralink/registry` has the expected checkout.
|
|
140
|
+
3. Run `infralink-host doctor` for read-only host evidence.
|
|
141
|
+
4. Inspect `/var/lib/infralink/reconcile-result.yml` as the last reconcile
|
|
142
|
+
result, not as desired state.
|
|
143
|
+
5. Check whether `infralink-host-reconcile.timer` ran after the registry change.
|
|
144
|
+
6. Check rendered files under `/opt/services/config`.
|
|
145
|
+
7. Check the affected Compose service or application-specific behavior.
|
|
146
|
+
|
|
147
|
+
Do not repair desired-state drift by editing `/opt/services` directly. Fix the
|
|
148
|
+
registry or source repo that owns the value, then let the controller reconcile.
|
|
149
|
+
|
|
150
|
+
## Development Contract
|
|
151
|
+
|
|
152
|
+
- Keep commands agent-friendly: explicit inputs, bounded output, stable exit
|
|
153
|
+
behavior, and machine-readable evidence.
|
|
154
|
+
- Keep provider-specific policy out of generic primitives unless the command
|
|
155
|
+
name says it is provider-specific.
|
|
156
|
+
- Add tests for every command contract, runtime boundary, and failure mode.
|
|
157
|
+
- Keep README-level docs focused on operator entrypoints; put command-specific
|
|
158
|
+
details in focused guides or tests.
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Infralink Ops
|
|
2
|
+
|
|
3
|
+
## BLUF
|
|
4
|
+
|
|
5
|
+
This repo packages the public controller runtime for managed hosts. Deployment
|
|
6
|
+
intent, private templates, and secret aliases remain in the environment
|
|
7
|
+
registry; live-service acceptance remains environment-owned operational state.
|
|
8
|
+
|
|
9
|
+
Use it when you need bounded host primitives for registry checkout, template
|
|
10
|
+
rendering, config projection, Docker image retention, Compose consumer
|
|
11
|
+
activation, firewall verification, secret rendering, or host doctor evidence.
|
|
12
|
+
|
|
13
|
+
Do not use this repo to select fleet desired state. Registry revisions, service
|
|
14
|
+
definitions, image pins, hostnames, and secret bindings come from the
|
|
15
|
+
environment registry.
|
|
16
|
+
|
|
17
|
+
## Reader Paths
|
|
18
|
+
|
|
19
|
+
| Goal | Start here |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| Understand the runtime boundary | [Controller runtime guide](docs/controller-runtime-guide.md) |
|
|
22
|
+
| Debug a stale RelayOS staging rollout | [Controller runtime guide](docs/controller-runtime-guide.md#triage-a-stale-host) |
|
|
23
|
+
| Check available CLIs | [`pyproject.toml`](pyproject.toml) |
|
|
24
|
+
| Inspect host-installed launcher assets | [`src/infralink_ops/assets/`](src/infralink_ops/assets/) |
|
|
25
|
+
| Review controller behavior | [`src/infralink_ops/`](src/infralink_ops/) and [`tests/`](tests/) |
|
|
26
|
+
|
|
27
|
+
## How It Fits
|
|
28
|
+
|
|
29
|
+
```mermaid
|
|
30
|
+
flowchart LR
|
|
31
|
+
registry["configured registry revision"] --> checkout["/var/lib/infralink/registry"]
|
|
32
|
+
checkout --> render["template render and static config projection"]
|
|
33
|
+
render --> consumers["Compose consumer validate/activate"]
|
|
34
|
+
consumers --> evidence["doctor, metrics, and logs"]
|
|
35
|
+
evidence --> operator["environment-owned acceptance"]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
This repo implements the bounded primitives in the middle of the flow. It does
|
|
39
|
+
not own the registry data model or the environment-specific acceptance result.
|
|
40
|
+
|
|
41
|
+
## Main CLIs
|
|
42
|
+
|
|
43
|
+
| Command | Purpose |
|
|
44
|
+
| --- | --- |
|
|
45
|
+
| `infralink-controller-registry-checkout fetch` | Fetch a declared registry ref into an existing clean checkout. |
|
|
46
|
+
| `infralink-controller-template-render` | Render registry-declared templates from explicit inputs. |
|
|
47
|
+
| `infralink-controller-config-consumers validate\|activate` | Validate or recreate services affected by rendered config changes. |
|
|
48
|
+
| `infralink-controller-images retain-and-prune` | Keep selected immutable Docker images and prune stale cache images. |
|
|
49
|
+
| `infralink-controller-render-secrets` | Resolve registry-declared render-secret bindings through BWS. |
|
|
50
|
+
| `infralink-controller-firewall render\|verify` | Render or verify declared nftables policy. |
|
|
51
|
+
| `infralink-controller-doctor` | Read-only host-runtime check for registry, reconcile, Compose, firewall, and metrics evidence. |
|
|
52
|
+
| `infralink-host doctor\|reconcile\|bootstrap --apply` | Host launcher installed from [`src/infralink_ops/assets/infralink-host`](src/infralink_ops/assets/infralink-host). |
|
|
53
|
+
|
|
54
|
+
Each command is intentionally narrow. Commands receive explicit inputs and
|
|
55
|
+
return bounded machine-readable envelopes where possible.
|
|
56
|
+
|
|
57
|
+
## Authority Boundary
|
|
58
|
+
|
|
59
|
+
| This repo owns | This repo does not own |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| Controller image build recipe. | Which registry revision a host should run. |
|
|
62
|
+
| Host launcher and systemd unit assets. | Service definitions, hostnames, DNS, certificates, or image pins. |
|
|
63
|
+
| Runtime primitives with bounded inputs and outputs. | Tenant or application policy. |
|
|
64
|
+
| Doctor and evidence helpers. | Live-service acceptance criteria. |
|
|
65
|
+
| BWS resolution primitive. | BWS secret values or registry secret declarations. |
|
|
66
|
+
|
|
67
|
+
For RelayOS IRC, source/config/image repos feed the registry first:
|
|
68
|
+
|
|
69
|
+
```mermaid
|
|
70
|
+
flowchart LR
|
|
71
|
+
deploy["relayos-deploy docs and deploy contract"]
|
|
72
|
+
config["relayos-irc-config"]
|
|
73
|
+
modules["custom-modules"]
|
|
74
|
+
images["relayos-irc-containers"]
|
|
75
|
+
registry["infra-registry"]
|
|
76
|
+
ops["infralink-ops controller"]
|
|
77
|
+
host["managed host"]
|
|
78
|
+
|
|
79
|
+
config --> registry
|
|
80
|
+
modules --> images
|
|
81
|
+
images --> deploy
|
|
82
|
+
deploy --> registry
|
|
83
|
+
registry --> ops
|
|
84
|
+
ops --> host
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## GHCR and BWS
|
|
88
|
+
|
|
89
|
+
The controller image publishes to
|
|
90
|
+
[cyberstorm-dev packages](https://github.com/orgs/cyberstorm-dev/packages) as
|
|
91
|
+
`ghcr.io/cyberstorm-dev/infralink-ops-controller`.
|
|
92
|
+
|
|
93
|
+
BWS access is runtime-only. This repo contains the resolver and tests for the
|
|
94
|
+
resolver contract; the token and secret object names belong to the environment
|
|
95
|
+
registry and host runtime.
|
|
96
|
+
|
|
97
|
+
## Verify Changes
|
|
98
|
+
|
|
99
|
+
Run the same checks Woodpecker runs:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
python -m pip install --disable-pip-version-check \
|
|
103
|
+
'infralink @ https://github.com/cyberstorm-dev/infralink/releases/download/v0.6.14/infralink-0.6.14-py3-none-any.whl#sha256=e41e16e082df50d7506785feb40dc3ea48087d46c391e31f2bd77e3ef81ce0e3'
|
|
104
|
+
python -m pip install --disable-pip-version-check -e '.[dev]'
|
|
105
|
+
python -m ruff check src tests
|
|
106
|
+
python -m ruff format --check src tests
|
|
107
|
+
python -m pytest -q
|
|
108
|
+
python -m build
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Infralink Ops declares compatibility with Infralink `>=0.6,<0.7`. Until
|
|
112
|
+
Infralink is published to PyPI, bootstrap a released, checksum-pinned wheel
|
|
113
|
+
before installing Ops so a clean environment does not attempt an unavailable
|
|
114
|
+
index resolution.
|
|
115
|
+
|
|
116
|
+
The controller image publish step runs only on `main` pushes. Pull requests use
|
|
117
|
+
Docker buildx dry-run validation.
|
|
118
|
+
|
|
119
|
+
## Triage A Stale Host
|
|
120
|
+
|
|
121
|
+
Check in this order:
|
|
122
|
+
|
|
123
|
+
1. Confirm the environment selected the intended registry revision.
|
|
124
|
+
2. Confirm `/var/lib/infralink/registry` has the expected checkout.
|
|
125
|
+
3. Run `infralink-host doctor` for read-only host evidence.
|
|
126
|
+
4. Inspect `/var/lib/infralink/reconcile-result.yml` as the last reconcile
|
|
127
|
+
result, not as desired state.
|
|
128
|
+
5. Check whether `infralink-host-reconcile.timer` ran after the registry change.
|
|
129
|
+
6. Check rendered files under `/opt/services/config`.
|
|
130
|
+
7. Check the affected Compose service or application-specific behavior.
|
|
131
|
+
|
|
132
|
+
Do not repair desired-state drift by editing `/opt/services` directly. Fix the
|
|
133
|
+
registry or source repo that owns the value, then let the controller reconcile.
|
|
134
|
+
|
|
135
|
+
## Development Contract
|
|
136
|
+
|
|
137
|
+
- Keep commands agent-friendly: explicit inputs, bounded output, stable exit
|
|
138
|
+
behavior, and machine-readable evidence.
|
|
139
|
+
- Keep provider-specific policy out of generic primitives unless the command
|
|
140
|
+
name says it is provider-specific.
|
|
141
|
+
- Add tests for every command contract, runtime boundary, and failure mode.
|
|
142
|
+
- Keep README-level docs focused on operator entrypoints; put command-specific
|
|
143
|
+
details in focused guides or tests.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Infralink Ops controller runtime guide
|
|
2
|
+
|
|
3
|
+
## BLUF
|
|
4
|
+
|
|
5
|
+
Use this guide to understand what the host controller can do and what
|
|
6
|
+
evidence it can produce.
|
|
7
|
+
|
|
8
|
+
The controller applies a registry revision that another layer selected. It does
|
|
9
|
+
not choose tenant config, image digests, secrets, DNS, or service policy.
|
|
10
|
+
|
|
11
|
+
## Runtime Lifecycle
|
|
12
|
+
|
|
13
|
+
```mermaid
|
|
14
|
+
sequenceDiagram
|
|
15
|
+
participant Registry as Registry declaration
|
|
16
|
+
participant Host as infralink-host-reconcile.timer
|
|
17
|
+
participant Checkout as /var/lib/infralink/registry
|
|
18
|
+
participant Render as Template and config projection
|
|
19
|
+
participant Compose as Compose consumers
|
|
20
|
+
participant Evidence as Doctor and metrics
|
|
21
|
+
|
|
22
|
+
Registry->>Host: configured revision and controller image
|
|
23
|
+
Host->>Checkout: fetch explicit ref
|
|
24
|
+
Host->>Render: render templates and materialize config trees
|
|
25
|
+
Render->>Compose: validate affected consumers
|
|
26
|
+
Compose->>Compose: activate changed services
|
|
27
|
+
Compose->>Evidence: publish reconcile result
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Controller Primitives
|
|
31
|
+
|
|
32
|
+
| Primitive | Command | Evidence |
|
|
33
|
+
| --- | --- | --- |
|
|
34
|
+
| Registry checkout | `infralink-controller-registry-checkout fetch` | Detached registry revision. |
|
|
35
|
+
| Template rendering | `infralink-controller-template-render` | Rendered files from explicit inputs. |
|
|
36
|
+
| Static config trees | `materialize_config_tree` | Changed paths below the declared target. |
|
|
37
|
+
| Compose consumers | `infralink-controller-config-consumers validate\|activate` | Affected consumers and services. |
|
|
38
|
+
| Image retention | `infralink-controller-images retain-and-prune` | Selected immutable image retained; stale cache images pruned. |
|
|
39
|
+
| Secrets | `infralink-controller-render-secrets` | BWS-backed rendered values without committing secrets. |
|
|
40
|
+
| Firewall | `infralink-controller-firewall render\|verify` | Declared nftables table or runtime drift result. |
|
|
41
|
+
| Doctor | `infralink-controller-doctor` | Read-only host consistency envelope. |
|
|
42
|
+
|
|
43
|
+
## BWS Contract
|
|
44
|
+
|
|
45
|
+
The controller can resolve registry-declared BWS bindings at runtime. It must
|
|
46
|
+
not commit secret values, print tokens, or infer undeclared secret names.
|
|
47
|
+
|
|
48
|
+
Failure to resolve BWS is a registry/runtime failure. Do not fix it by hardcoding
|
|
49
|
+
a value into source, rendered config, or a Compose file.
|
|
50
|
+
|
|
51
|
+
## GHCR Contract
|
|
52
|
+
|
|
53
|
+
Woodpecker publishes the controller image to
|
|
54
|
+
[cyberstorm-dev packages](https://github.com/orgs/cyberstorm-dev/packages) as
|
|
55
|
+
`ghcr.io/cyberstorm-dev/infralink-ops-controller` on `main` pushes.
|
|
56
|
+
|
|
57
|
+
Use immutable `sha-<short-sha>` tags or digests for evidence. Do not use `head` or `main` as acceptance evidence.
|
|
58
|
+
|
|
59
|
+
## Triage A Stale Host
|
|
60
|
+
|
|
61
|
+
1. Confirm the registry revision that the environment intended to run.
|
|
62
|
+
2. Confirm `/var/lib/infralink/registry` resolved to that revision.
|
|
63
|
+
3. Run `infralink-host doctor`.
|
|
64
|
+
4. Check `systemctl status infralink-host-reconcile.timer`.
|
|
65
|
+
5. Inspect `/var/lib/infralink/reconcile-result.yml` for the last reconcile
|
|
66
|
+
evidence.
|
|
67
|
+
6. Inspect rendered files under `/opt/services/config`.
|
|
68
|
+
7. Check the live service using environment-owned acceptance criteria.
|
|
69
|
+
|
|
70
|
+
If evidence points to a wrong source value, fix the owning source repository or
|
|
71
|
+
registry declaration. If evidence points to controller behavior, fix this repo
|
|
72
|
+
with tests and publish a new controller image.
|