feat(deploy): railiance01 consistency sweep host mount and hostname override
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 2m3s

Add git/ssh to the runtime image, mount /home/tegwick into the state-hub pod,
resolve host_paths via STATE_HUB_SWEEP_HOSTNAME, and fall back to the
railiance01 the-custodian canon path for classification validation.
This commit is contained in:
tegwick 2026-07-06 19:24:28 +02:00
parent ae14fc3e49
commit 16201ac918
6 changed files with 62 additions and 11 deletions

View file

@ -7,7 +7,7 @@ ENV PYTHONDONTWRITEBYTECODE=1 \
WORKDIR /app
RUN apt-get update \
&& apt-get install -y --no-install-recommends curl ca-certificates \
&& apt-get install -y --no-install-recommends curl ca-certificates git openssh-client \
&& rm -rf /var/lib/apt/lists/* \
&& pip install --no-cache-dir uv

View file

@ -11,10 +11,13 @@ from pathlib import Path
import yaml
# Primary path (sibling checkout); fallback relative to state-hub repo root.
# Workstation checkout, railiance01 fleet checkout, then state-hub sibling fallback.
_PRIMARY_ALLOWED = Path(
"/home/worsch/the-custodian/canon/standards/repo-classification.allowed.yaml"
)
_RAILIANCE_ALLOWED = Path(
"/home/tegwick/the-custodian/canon/standards/repo-classification.allowed.yaml"
)
_FALLBACK_ALLOWED = (
Path(__file__).resolve().parent.parent.parent
/ "the-custodian"
@ -67,13 +70,12 @@ class ClassificationData:
def _allowed_path() -> Path:
if _PRIMARY_ALLOWED.is_file():
return _PRIMARY_ALLOWED
if _FALLBACK_ALLOWED.is_file():
return _FALLBACK_ALLOWED
for candidate in (_PRIMARY_ALLOWED, _RAILIANCE_ALLOWED, _FALLBACK_ALLOWED):
if candidate.is_file():
return candidate
raise FileNotFoundError(
"repo-classification.allowed.yaml not found at "
f"{_PRIMARY_ALLOWED} or {_FALLBACK_ALLOWED}"
f"{_PRIMARY_ALLOWED}, {_RAILIANCE_ALLOWED}, or {_FALLBACK_ALLOWED}"
)

View file

@ -20,6 +20,17 @@ spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets: {{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.sweep.enabled }}
volumes:
- name: sweep-repos
hostPath:
path: {{ .Values.sweep.hostPath | quote }}
type: Directory
- name: sweep-ssh
hostPath:
path: {{ .Values.sweep.sshHostPath | quote }}
type: DirectoryOrCreate
{{- end }}
containers:
- name: state-hub
image: {{ include "statehub.image" . | quote }}
@ -29,6 +40,26 @@ spec:
- name: http
containerPort: {{ .Values.service.targetPort }}
protocol: TCP
{{- if .Values.sweep.enabled }}
lifecycle:
postStart:
exec:
command:
- /bin/sh
- -c
- git config --global --add safe.directory '*'
volumeMounts:
- name: sweep-repos
mountPath: {{ .Values.sweep.hostPath | quote }}
- name: sweep-ssh
mountPath: /root/.ssh
readOnly: true
env:
- name: STATE_HUB_SWEEP_HOSTNAME
value: {{ .Values.sweep.hostname | quote }}
- name: GIT_SSH_COMMAND
value: "ssh -o StrictHostKeyChecking=accept-new -F /root/.ssh/config"
{{- end }}
envFrom:
{{- if .Values.config.enabled }}
- configMapRef:

View file

@ -64,4 +64,11 @@ securityContext: {}
nodeSelector: {}
tolerations: []
affinity: {}
affinity: {}
# Consistency sweep: mount railiance01 clone tree and match host_paths hostname.
sweep:
enabled: false
hostname: ""
hostPath: /home/tegwick
sshHostPath: /home/tegwick/.ssh

View file

@ -10,3 +10,9 @@ image:
ingress:
enabled: false
sweep:
enabled: true
hostname: 239.62.205.92.host.secureserver.net
hostPath: /home/tegwick
sshHostPath: /home/tegwick/.ssh

View file

@ -70,6 +70,11 @@ _REPO_ROOT = Path(__file__).resolve().parent.parent
if str(_REPO_ROOT) not in sys.path:
sys.path.insert(0, str(_REPO_ROOT))
def _sweep_hostname() -> str:
"""Hostname for host_paths resolution; override when pod hostname != fleet FQDN."""
return os.environ.get("STATE_HUB_SWEEP_HOSTNAME", "").strip() or socket.gethostname()
from api.workplan_status import ( # noqa: E402
CANONICAL_WORKSTREAM_STATUSES,
CLOSED_WORKSTREAM_STATUSES,
@ -617,7 +622,7 @@ def resolve_repo_path(repo: dict, override: str | None = None) -> str:
"""
if override:
return override
hostname = socket.gethostname()
hostname = _sweep_hostname()
host_paths = repo.get("host_paths") or {}
return host_paths.get(hostname) or repo.get("local_path") or ""
@ -1692,7 +1697,7 @@ def fix_repo(
if repo_path:
repo_record = _api_get(api_base, f"/repos/{repo_slug}")
if repo_record:
hostname = socket.gethostname()
hostname = _sweep_hostname()
if (repo_record.get("host_paths") or {}).get(hostname) != repo_path:
result = _api_post(
api_base, f"/repos/{repo_slug}/paths",
@ -2491,7 +2496,7 @@ def main() -> None:
sys.exit(0)
else:
# Resolve repo list
hostname = socket.gethostname()
hostname = _sweep_hostname()
repo_slugs: list[str] = []
if args.all:
repos = _api_get(args.api_base, "/repos")