diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 51cc282..db0e438 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: name: YAML lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - run: pip install yamllint --quiet - run: yamllint -c .yamllint.yml . @@ -22,7 +22,7 @@ jobs: name: Secrets detection runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: fetch-depth: 0 - name: Install gitleaks @@ -38,7 +38,7 @@ jobs: name: Kubernetes manifest validation runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Install kubeconform run: | @@ -58,7 +58,7 @@ jobs: name: Helm lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Install Helm uses: azure/setup-helm@v4 @@ -98,7 +98,7 @@ jobs: name: API deprecation check runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Read target Kubernetes version id: k8s @@ -130,9 +130,9 @@ jobs: name: Markdown lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 with: - node-version: "20" + node-version: "24" - run: npm install -g markdownlint-cli2 - run: markdownlint-cli2 "**/*.md" "#node_modules" diff --git a/.github/workflows/talos-image-update.yml b/.github/workflows/talos-image-update.yml new file mode 100644 index 0000000..2a9ddb6 --- /dev/null +++ b/.github/workflows/talos-image-update.yml @@ -0,0 +1,41 @@ +name: Update Talos image + +on: + repository_dispatch: + types: [talos-image-update] + +jobs: + update: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + + steps: + - uses: actions/checkout@v6 + + - name: Update omni/talos-image.yaml + env: + TALOS_VERSION: ${{ github.event.client_payload.talos_version }} + run: | + sed -i "s|^talos_version:.*|talos_version: ${TALOS_VERSION}|" omni/talos-image.yaml + sed -i "s|^updated_at:.*|updated_at: \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"|" omni/talos-image.yaml + + - name: Open pull request + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TALOS_VERSION: ${{ github.event.client_payload.talos_version }} + run: | + BRANCH="talos-image-update/${TALOS_VERSION}" + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git checkout -b "${BRANCH}" + git add omni/talos-image.yaml + git diff --cached --quiet && echo "No changes" && exit 0 + git commit -m "chore: update Talos installer image to ${TALOS_VERSION}" + git push origin "${BRANCH}" + gh pr create \ + --title "chore: update Talos installer image to ${TALOS_VERSION}" \ + --body "Auto-generated by talos-images build workflow." \ + --base main \ + --head "${BRANCH}" diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 0000000..ea3cc5e --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1 @@ +MD013: false # line-length: URLs and long paths make this impractical diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9b4985b..4683c6d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,14 +10,6 @@ repos: hooks: - id: gitleaks - - repo: https://github.com/yannh/kubeconform - rev: v0.6.7 - hooks: - - id: kubeconform - args: - - -strict - - -ignore-missing-schemas - - -summary - repo: https://github.com/igorshubovych/markdownlint-cli rev: v0.44.0 diff --git a/omni/cluster-templates/talos.yaml b/omni/cluster-templates/talos.yaml index 28e4538..0b1b255 100644 --- a/omni/cluster-templates/talos.yaml +++ b/omni/cluster-templates/talos.yaml @@ -3,9 +3,13 @@ name: oci-talos labels: environment: oci kubernetes: + # Not touched by the talos-images upgrade workflow — bump deliberately, one + # minor at a time. Talos 1.13.x supports k8s 1.31–1.36 (SupportedKubernetesVersions=6 + # counting back from its 1.36.2 default), so this is valid as-is. version: v1.32.3 talos: - version: v1.12.5 + # Keep in step with installImage in omni/machine-classes/*.yaml. + version: v1.13.5 patches: - file: ../patches/cni-none.yaml - file: ../patches/disable-kube-proxy.yaml diff --git a/omni/machine-classes/control-plane.yaml b/omni/machine-classes/control-plane.yaml index 31071a0..e48c50e 100644 --- a/omni/machine-classes/control-plane.yaml +++ b/omni/machine-classes/control-plane.yaml @@ -4,7 +4,7 @@ metadata: id: oci-cp spec: - installImage: ghcr.io/syscode-labs/talos-images/installer:v1.9.0 + installImage: ghcr.io/syscode-labs/talos-images/installer:v1.13.5 matchLabels: # Applied manually in Omni UI after OCI nodes connect via SideroLink. # omnictl machine set-labels role=oci-cp diff --git a/omni/machine-classes/worker.yaml b/omni/machine-classes/worker.yaml index ebdfc54..2ee0294 100644 --- a/omni/machine-classes/worker.yaml +++ b/omni/machine-classes/worker.yaml @@ -4,7 +4,7 @@ metadata: id: oci-worker spec: - installImage: ghcr.io/syscode-labs/talos-images/installer:v1.9.0 + installImage: ghcr.io/syscode-labs/talos-images/installer:v1.13.5 matchLabels: # Applied manually in Omni UI after OCI nodes connect via SideroLink. # omnictl machine set-labels role=oci-worker diff --git a/omni/scripts/generate-manifests.sh b/omni/scripts/generate-manifests.sh index df68ec9..f53e38b 100755 --- a/omni/scripts/generate-manifests.sh +++ b/omni/scripts/generate-manifests.sh @@ -8,6 +8,17 @@ set -euo pipefail CILIUM_VERSION="${CILIUM_VERSION:-1.17.2}" ARGOCD_VERSION="${ARGOCD_VERSION:-v2.14.4}" +# Argo topology selector. +# hub : omit in-cluster Argo — a central hub Argo (on the Omni VM k8s) manages +# this cluster as a spoke (default for this homelab). +# in-cluster : bootstrap Argo CD + root App-of-Apps inside this cluster. +# Cilium is always in-cluster (it is the CNI). +ARGO_MODE="${ARGO_MODE:-hub}" +case "$ARGO_MODE" in + in-cluster|hub) ;; + *) echo "ARGO_MODE must be 'in-cluster' or 'hub', got '${ARGO_MODE}'" >&2; exit 1 ;; +esac + SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PATCH_FILE="${SCRIPT_DIR}/../patches/inline-manifests.yaml" TMPDIR=$(mktemp -d) @@ -29,23 +40,26 @@ helm template cilium cilium/cilium \ --set hubble.ui.enabled=true \ > "${TMPDIR}/cilium.yaml" -echo "==> Downloading Argo CD ${ARGOCD_VERSION}..." -curl -sL "https://raw.githubusercontent.com/argoproj/argo-cd/${ARGOCD_VERSION}/manifests/install.yaml" \ - > "${TMPDIR}/argocd.yaml" +if [ "$ARGO_MODE" = "in-cluster" ]; then + echo "==> Downloading Argo CD ${ARGOCD_VERSION}..." + curl -sL "https://raw.githubusercontent.com/argoproj/argo-cd/${ARGOCD_VERSION}/manifests/install.yaml" \ + > "${TMPDIR}/argocd.yaml" + ARGOCD_CONTENT=$(sed 's/^/ /' "${TMPDIR}/argocd.yaml") +fi CILIUM_CONTENT=$(sed 's/^/ /' "${TMPDIR}/cilium.yaml") -ARGOCD_CONTENT=$(sed 's/^/ /' "${TMPDIR}/argocd.yaml") -echo "==> Writing ${PATCH_FILE}..." +echo "==> Writing ${PATCH_FILE} (ARGO_MODE=${ARGO_MODE})..." cat > "${PATCH_FILE}" <> "${PATCH_FILE}" <> "${PATCH_FILE}" <<'EOF' + + # ARGO_MODE=hub — no in-cluster Argo. A central hub Argo (on the Omni VM k8s) manages + # this cluster as a spoke. This block ships the ServiceAccount the hub authenticates as, + # so the token exists from first boot. Registration (read token → sops → commit) is the + # single manual step, documented once in: + # syscode-ai-internal-plans/projects/imp/docs/plans/2026-07-11-argo-hub-spoke-registration-runbook.md + - name: argocd-manager + contents: | + apiVersion: v1 + kind: ServiceAccount + metadata: + name: argocd-manager + namespace: kube-system + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRoleBinding + metadata: + name: argocd-manager + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin + subjects: + - kind: ServiceAccount + name: argocd-manager + namespace: kube-system + --- + # Non-expiring legacy SA token (auto-token Secrets removed in k8s 1.24). Deliberate: + # a bound short-lived token can't be pre-committed for GitOps registration. + apiVersion: v1 + kind: Secret + metadata: + name: argocd-manager-token + namespace: kube-system + annotations: + kubernetes.io/service-account.name: argocd-manager + type: kubernetes.io/service-account-token +EOF +fi -echo "==> Done. Commit omni/patches/inline-manifests.yaml." +echo "==> Done (ARGO_MODE=${ARGO_MODE}). Commit omni/patches/inline-manifests.yaml." diff --git a/omni/talos-image.yaml b/omni/talos-image.yaml index 9d8cc88..5e77ee7 100644 --- a/omni/talos-image.yaml +++ b/omni/talos-image.yaml @@ -1,6 +1,6 @@ # Auto-updated by talos-images workflow — do not edit manually -talos_version: v1.9.0 -kubernetes_version: v1.32.3 -schematic_id: "" -oci_image_ocid: "" -updated_at: "" +talos_version: v1.13.5 +kubernetes_version: v1.36.2 +schematic_id: 4a0d65c669d46663f377e7161e50cfd570c401f26fd9e7bda34a0216b6f1922b +oci_image_ocid: ocid1.image.oc1.uk-london-1.aaaaaaaadheaqve6ikpx5nqn637zmaudgq6dt67tnv7z2t7dnju5tyu6l2ta +updated_at: 2026-07-05T05:59:40Z