Skip to content

docs: add operator runbooks and update climate-ref to v0.18.1 - #60

Merged
lewisjared merged 7 commits into
mainfrom
docs/operator-runbooks
Sep 4, 2026
Merged

docs: add operator runbooks and update climate-ref to v0.18.1#60
lewisjared merged 7 commits into
mainfrom
docs/operator-runbooks

Conversation

@lewisjared

@lewisjared lewisjared commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Adds two operator runbooks under docs/runbooks/ and a small example values file they are written against, and moves the pinned climate-ref components to v0.18.1.

  • bootstrap-a-deployment.md takes the chart from helm install to a smoke solve.
  • run-and-triage-a-solve.md covers running a solve, watching it, and the stuck, wedged, OOM and orphan-queue cases.
  • helm/examples/small-values.yaml is a single-node, SQLite, one-worker-per-provider starting point. The chart README now points at it instead of carrying its own copy, and the render tests cover it.

Both runbooks were rehearsed step by step on a fresh release on research-ovh-gra-1 (namespace climate-ref-aft-test).

Summary by CodeRabbit

  • New Features

    • Added operator runbooks for deployment bootstrap and solve execution, monitoring, troubleshooting, and recovery.
    • Added a small single-node Helm configuration example.
    • Updated configuration guidance for shared volumes and read-only cache access.
  • Improvements

    • Updated Climate REF components to v0.18.1 and the frontend to v0.7.1.
    • Added support for observation data using the obs4ref source type.
  • Documentation

    • Expanded the README and changelog with links and details for the new operational guidance.

@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Deployment operations

Layer / File(s) Summary
Component version alignment
docker/docker-compose.yaml, helm/Chart.yaml, helm/README.md, helm/values.yaml, pyproject.toml, versions.toml, changelog/60.improvement.md
Runtime images, package pins, Helm metadata, and changelog entries use Climate REF 0.18.1 and ref-app 0.7.1.
Small deployment configuration
helm/examples/small-values.yaml, helm/README.md, tests/test_helm_render.py
The small Helm example defines shared storage, provider resources, read-only worker cache access, orchestrator mounts, and Dragonfly settings. Helm tests render the example and verify worker mounts.
Deployment bootstrap runbook
docs/runbooks/bootstrap-a-deployment.md, README.md, changelog/60.docs.md
The documentation covers Helm installation, database migration, provider setup, data ingestion, diagnostics, smoke solving, and operation without model data.
Solve execution and triage
docs/runbooks/run-and-triage-a-solve.md
The runbook covers solve execution, monitoring, failure inspection, recovery, troubleshooting, upgrades, and diagnostic reporting.

Merge Risk: 🟡 Moderate · up to ab440

Following the runbooks can produce an incomplete deployment or send operators down incorrect troubleshooting paths. These operational instructions should be corrected before merge.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 1 files. (12 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarises the two main changes: adding operator runbooks and updating climate-ref to v0.18.1.
Full details: Docstring Coverage

Explanation

Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 1 files. (12 skipped: 12 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/operator-runbooks

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@lewisjared lewisjared changed the title docs: add operator runbooks for bootstrapping and running a solve docs: add operator runbooks and update climate-ref to v0.18.1 Sep 4, 2026
Fixes the prose defects in the new operator docs.

- Restores the "Who writes what" heading, because "Volumes" nested under
  "Required volumes" said the same thing twice.
- Rewrites the sentence about `REF_CONFIGURATION`, which had lost a word
  and carried a typo.
- Replaces the truncated obs4MIPs note with what to download and where.
- Uses the `ref-orch` alias for the health check rather than repeating the
  full `kubectl exec` line.
@lewisjared
lewisjared marked this pull request as ready for review September 4, 2026 14:09

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: f37c11ba-3be7-4e8c-a204-2ba617929359

📥 Commits

Reviewing files that changed from the base of the PR and between c760b3a and ab44090.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (13)
  • README.md
  • changelog/60.docs.md
  • changelog/60.improvement.md
  • docker/docker-compose.yaml
  • docs/runbooks/bootstrap-a-deployment.md
  • docs/runbooks/run-and-triage-a-solve.md
  • helm/Chart.yaml
  • helm/README.md
  • helm/examples/small-values.yaml
  • helm/values.yaml
  • pyproject.toml
  • tests/test_helm_render.py
  • versions.toml

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.

After the install every pod should be Running, and the API answers its health check:

```bash
ref-orch python3 -c "import urllib.request as u; print(u.urlopen('http://$RELEASE-climate-ref-aft-api/api/v1/utils/health-check/').read())"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- target excerpt ---'
cat -n docs/runbooks/bootstrap-a-deployment.md | sed -n '60,84p'
printf '%s\n' '--- relevant urllib usage in the runbook ---'
rg -n -C 2 'urlopen|health-check|bootstrap' docs/runbooks/bootstrap-a-deployment.md

Repository: Climate-REF/climate-ref-aft

Length of output: 2134


🤖 get_repo_knowledge executed:

get_repo_knowledge Climate-REF/climate-ref-aft /tmp/coderabbit-repo-knowledge/climate-ref-climate-ref-aft-76c847f7/architecture

Length of output: 23616


Bound the health-check wait.

Pass timeout=10 to urllib.request.urlopen on line 74. Without it, an unresponsive API can block bootstrap indefinitely.

Comment on lines +114 to +115
ref-orch sh -c 'setsid nohup ref datasets fetch-data --registry obs4ref --output-directory /ref/data/obs4ref > /ref/log/fetch-obs4ref.log 2>&1 < /dev/null &'
ref-orch ref datasets ingest --source-type obs4ref /ref/data/obs4ref

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Wait for fetch-data to complete before ingestion.

Line 114 backgrounds fetch-data and returns immediately. Line 115 then walks the same directory without checking fetch completion. The ingest can record only the files copied so far, which can leave the deployment without required observation datasets. Run the fetch in the foreground, or add a durable completion and polling step before starting ingestion.

Comment on lines +69 to +70
A queue that stays non-zero while its worker shows nothing active is the picture to recognise.
The worker is not consuming.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- runbook excerpt ---'
sed -n '60,75p' docs/runbooks/run-and-triage-a-solve.md
printf '%s\n' '--- broker_state.py location ---'
fd -t f 'broker_state\.py$' .
printf '%s\n' '--- broker_state.py excerpt ---'
file=$(fd -t f 'broker_state\.py$' . | head -n 1)
sed -n '1,240p' "$file"
printf '%s\n' '--- related usage ---'
rg -n -C 3 'broker_state|reserved|active' docs scripts tests 2>/dev/null | head -n 240

Repository: Climate-REF/climate-ref-aft

Length of output: 5655


🤖 get_repo_knowledge executed:

get_repo_knowledge Climate-REF/climate-ref-aft /tmp/coderabbit-repo-knowledge/climate-ref-climate-ref-aft-76c847f7/architecture /tmp/coderabbit-repo-knowledge/climate-ref-climate-ref-aft-76c847f7/learnings

Length of output: 25410


🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- Celery dependency pins ---'
rg -n -C 2 'celery|climate-ref-celery' pyproject.toml uv.lock versions.toml 2>/dev/null | head -n 160
printf '%s\n' '--- app binding ---'
rg -n -C 4 'from .* import app|app\s*=|def celery_inspect|inspect\(' scripts pyproject.toml 2>/dev/null | head -n 200

Repository: Climate-REF/climate-ref-aft

Length of output: 3975


🌐 Web query:

Celery documentation inspect active reserved tasks prefetch reserved method

💡 Result:

In Celery, the inspect tool and its associated methods are used to query the status and state of active workers without altering them [1]. Inspecting Tasks To inspect worker tasks, use the celery inspect command line utility [2][3]. Active Tasks: Use the celery inspect active command to list tasks currently being executed by the workers [2][4]. Programmatically, this corresponds to the inspect.active method [1]. Reserved Tasks: Use the celery inspect reserved command to list tasks that have been received (prefetched) by the worker but are still waiting in the queue to be executed [3][5]. This command does not include active tasks or tasks with an ETA/countdown [6][3]. Programmatically, this corresponds to the inspect.reserved method [1][7]. Querying Specific Tasks: Use the celery inspect query_task ... command to retrieve specific information about tasks by their unique identifiers [2][4][3]. Prefetching Concepts Prefetching is the mechanism by which a worker reserves tasks (messages) from the broker before they are explicitly requested for execution [8][9]. Prefetch Limit: This defines how many unacknowledged tasks a worker is allowed to hold in memory [8]. It is controlled by the worker_prefetch_multiplier setting (default is the multiplier multiplied by the concurrency slot count) [8][9]. Custom Inspection/Control: While Celery provides built-in inspect commands, you can extend these by writing custom inspect_command or control_command functions [5]. For example, developers often implement custom commands to inspect the current prefetch count (e.g., via state.consumer.qos.value) or to increment it dynamically [5]. Key Distinctions Active vs. Reserved: Active tasks are currently running. Reserved tasks are prefetched and waiting to run [6][3][5]. Inspect vs. Control: Inspect commands have no side effects and only return information [1]. Control commands perform actions that may change worker behavior (e.g., enabling events or modifying prefetch settings) [1][5].

Citations:


Check reserved tasks before declaring a worker stalled.

If active is empty, inspect reserved before declaring that the worker is not consuming. Celery reports prefetched tasks as reserved while they wait for execution.

Comment on lines +84 to +85
kubectl -n $NS logs deploy/$RELEASE-climate-ref-aft-esmvaltool --tail=200
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Select the log for the failed provider.

This command always reads the ESMValTool deployment. A PMP or ILAMB failure therefore sends the operator to an unrelated worker log. Use the provider from the execution record.

Proposed fix
-kubectl -n $NS logs deploy/$RELEASE-climate-ref-aft-esmvaltool --tail=200
+PROVIDER=esmvaltool  # Set this to esmvaltool, pmp, or ilamb.
+kubectl -n $NS logs deploy/$RELEASE-climate-ref-aft-$PROVIDER --tail=200
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
kubectl -n $NS logs deploy/$RELEASE-climate-ref-aft-esmvaltool --tail=200
```
PROVIDER=esmvaltool # Set this to esmvaltool, pmp, or ilamb.
kubectl -n $NS logs deploy/$RELEASE-climate-ref-aft-$PROVIDER --tail=200

Comment on lines +152 to +153
A queue with a task and no consumer is an orphan.
That happens when `celeryRoutes` names a queue no instance lists under `queues`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Delay orphan classification during KEDA scale-up. When KEDA is enabled, a provider can run with zero replicas and remain without a consumer until the next polling cycle starts a pod. Check the ScaledObject status and wait for the configured pollingInterval before classifying the queue as orphaned.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
A queue with a task and no consumer is an orphan.
That happens when `celeryRoutes` names a queue no instance lists under `queues`.
During KEDA scale-up, a queued task can have no consumer temporarily.
Treat it as orphaned only after the polling interval, or when
`celeryRoutes` names a queue no instance lists under `queues`.

@lewisjared
lewisjared merged commit 5ff627a into main Sep 4, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant