From 5e4b9412ed8b96eb27228060e7747a20971888ee Mon Sep 17 00:00:00 2001 From: Ruslan Koliada Date: Fri, 24 Apr 2026 07:02:14 -0400 Subject: [PATCH 1/2] docs: add build instructions to CLAUDE.md --- CLAUDE.md | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000000..93b066cffa --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,136 @@ +# node_exporter (CloudLinux fork) + +This repository is CloudLinux's fork of the upstream +[prometheus/node_exporter](https://github.com/prometheus/node_exporter). It is +packaged as `cl-node-exporter` (RPM) and `cl-node-exporter` (deb) and is +consumed internally by the `cl_plus` telemetry stack. Upstream `master` is +merged in periodically; all CloudLinux-specific changes live on top of the +upstream history. + +## What the fork adds + +The fork is deliberately small. Out of the box upstream, plus: + +1. A unix-socket transport for `/metrics` (`--web.socket-path`, + `--web.socket-permissions`). +2. CloudLinux packaging recipes (`node_exporter.spec`, `debian/`). +3. A versioned tests subpackage at `/opt/node_exporter_tests/` used by the + CloudLinux QA pipeline. +4. A `/usr/share/cloudlinux/cl-node-exporter` version file, read by Sentry + for package-version tagging. +5. A Makefile change that runs `test-e2e` twice (TCP + unix-socket) so the + fork-local feature is exercised on every build. + +Everything else in this repo — collectors, metric semantics, command-line +flags, build targets — is upstream and should be understood by reading +upstream documentation, not by treating this repo as authoritative. + +## Design Specifications + +This project maintains design specs for the features where business rules, +invariants, and CloudLinux-specific decisions are not obvious from source +code. Check the index below before starting work — read any spec that +relates to your task. If your changes affect behavior described in a spec, +update the spec in the same commit. + +- [Unix Socket Listener](docs/design/unix-socket-listener.md) — `--web.socket-path`, `--web.socket-permissions`, unix domain socket, cl_plus scraping, socket cleanup, SIGTERM shutdown, e2e `-s` flag, `node_exporter.go` main +- [CloudLinux Packaging](docs/design/cloudlinux-packaging.md) — `cl-node-exporter` RPM, deb, `node_exporter.spec`, `debian/rules`, `/usr/share/cloudlinux/cl_plus/`, version file, Sentry tagging, tests subpackage, pinned Go toolchain, amd64-only + +## Working on this fork + +- **Before changing CloudLinux-specific code** (unix socket, RPM/deb + recipes, `/usr/share/cloudlinux/*` layout): read the relevant design + spec first, and update it in the same commit as your code change. +- **Before changing upstream-owned files** (anything under `collector/`, + `node_exporter.go` outside the unix-socket block, Makefile targets not + listed above): prefer forwarding the change upstream. Fork-local diffs + make the next upstream sync harder. +- **Upstream syncs:** history from upstream is merged periodically (see + commits tagged `Sync ... with upstream`). When resolving conflicts, + preserve every CloudLinux-specific invariant listed in the design + specs; if upstream has reimplemented something equivalent (e.g. unix + socket support), prefer deleting the fork-local copy and documenting + the change. + +## Creating a Build + +This project ships as an RPM package (Build System name: `node_exporter`). Builds are submitted to the CloudLinux Build System via its CLI. + +### Step 1 — Generate the build plan + +```bash +cd /root/ai-workspace/node_exporter +git checkout # branch, tag, or detached HEAD +uv run /root/ai-workspace/cl-aiworkspaces/workspace-side/scripts/build-plan.py +``` + +The script reads `cl-aiworkspaces/.agents/skills/build-create/projects-catalog.yaml` to map this workspace directory to its Build System name(s) and emits a JSON plan on stdout (warnings/errors on stderr; exit 1 on fatal errors such as uncommitted changes). + +The plan contains: +- `build_type_id` — build-type for the payload +- `build_platforms` — target platforms (e.g. CL7, CL8, CL9) +- `build_flavors` — flavor IDs +- `projects` — project names, build refs, testing config +- `jenkins_jobs` — Jenkins job IDs and definitions + +### Step 2 — Filter the plan to this project only + +The plan may include unrelated workspace projects. **Strip all entries from `projects` except `node_exporter`**, and keep only the Jenkins jobs relevant to it. One project per build — do not submit a multi-project payload. + +### Step 3 — Submit the build + +```bash +/root/ai-workspace/cl-aiworkspaces/workspace-side/mcps/mcp-cli-wrapper.sh build-system \ + create-build --raw '' +``` + +Minimum payload shape: + +```json +{ + "build_type_id": "", + "build_platforms": [], + "build_flavors": [""], + "target_channel": "beta", + "projects": [ + { + "name": "node_exporter", + "build_ref": { "name": "", "type": "git_branch" }, + "testing": { "qa_ref": "" } + } + ], + "jenkins_jobs": [] +} +``` + +`build_ref.type` options: `git_branch`, `git_tag`, or `gerrit_change` (for `refs/changes/XX/NNNNN/PS` refs — the `qa_ref` should then be `NNNNN/PS`). + +The CLI returns a build ID. Build URL: `https://build.cloudlinux.com/#/build/`. + +### Step 4 — Monitor + +```bash +/root/ai-workspace/cl-aiworkspaces/workspace-side/mcps/mcp-cli-wrapper.sh build-system \ + get-build --build-id +``` + +### Step 5 — Debug failures + +Search logs for errors: + +```bash +/root/ai-workspace/cl-aiworkspaces/workspace-side/mcps/mcp-cli-wrapper.sh build-system \ + search-build-logs --build-id --query "error" +``` + +Common failure patterns: + +| Symptom | Likely cause | Fix | +|---|---|---| +| `FAILED` in test output | Test regression | Update the test — do not revert the code fix | +| `ModuleNotFoundError` / `ImportError` | New dependency not declared | Add to the `.spec` `Requires`/`BuildRequires` (or equivalent) | +| `SyntaxError` in build log | Source typo | Fix the source | +| `%files`/`%install` mismatch | Spec file vs installed layout drift | Update the spec stanzas | +| Dependency-resolution errors | `Requires` constraint wrong | Check spec file version constraints | + +After fixing, push to the same branch and re-run steps 1–3. From 1fcfdd0acfea2f39eb774c8a2cf28fd31fd2b61d Mon Sep 17 00:00:00 2001 From: Ruslan Koliada Date: Mon, 27 Apr 2026 12:35:48 -0400 Subject: [PATCH 2/2] docs: rework build section to xray MR 19 layout --- CLAUDE.md | 101 ++++++++++++++++++------------------------------------ 1 file changed, 33 insertions(+), 68 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 93b066cffa..d43f198b4f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -52,85 +52,50 @@ update the spec in the same commit. socket support), prefer deleting the fork-local copy and documenting the change. -## Creating a Build +## AI Workspace Required -This project ships as an RPM package (Build System name: `node_exporter`). Builds are submitted to the CloudLinux Build System via its CLI. +Both the local-test and Build System workflows below assume you are inside an [AI Workspace](https://gitlab.corp.cloudlinux.com/clos/ci-tools/cl-aiworkspaces) VM at `/root/ai-workspace/`. They depend on: -### Step 1 — Generate the build plan +- the workspace's CloudLinux OS toolchain and any project-specific runtime (Python venv, Node, Docker, …) — needed by the local-build and unit-test targets; +- the workspace's `mcp-cli-wrapper.sh` and provisioned Build System / Jenkins tokens — needed by the BS payload helper. -```bash -cd /root/ai-workspace/node_exporter -git checkout # branch, tag, or detached HEAD -uv run /root/ai-workspace/cl-aiworkspaces/workspace-side/scripts/build-plan.py -``` +Outside an AI Workspace these commands will not work as documented. Spin up a workspace via `cl-aiworkspaces` first. -The script reads `cl-aiworkspaces/.agents/skills/build-create/projects-catalog.yaml` to map this workspace directory to its Build System name(s) and emits a JSON plan on stdout (warnings/errors on stderr; exit 1 on fatal errors such as uncommitted changes). +## Local Tests -The plan contains: -- `build_type_id` — build-type for the payload -- `build_platforms` — target platforms (e.g. CL7, CL8, CL9) -- `build_flavors` — flavor IDs -- `projects` — project names, build refs, testing config -- `jenkins_jobs` — Jenkins job IDs and definitions +Run from the repo root (`/root/ai-workspace/node_exporter/`): -### Step 2 — Filter the plan to this project only +| Command | What it does | +| --- | --- | +| `make build` | Build the `node_exporter` binary | +| `make test` | Run the upstream Go unit-test suite | +| `make test-e2e` | Run the e2e harness (downloads collector fixtures on first run) | +| `make checkmetrics && make checkrules` | Validate metric and rule schemas | -The plan may include unrelated workspace projects. **Strip all entries from `projects` except `node_exporter`**, and keep only the Jenkins jobs relevant to it. One project per build — do not submit a multi-project payload. +## Build System -### Step 3 — Submit the build +This repo ships as an RPM/DEB package: `node_exporter`. **Use the `/build-create` skill to submit builds** — it runs `build-plan.py` and submits the payload via the Build System CLI. The tables below are the project-specific overrides on top of that generic flow. -```bash -/root/ai-workspace/cl-aiworkspaces/workspace-side/mcps/mcp-cli-wrapper.sh build-system \ - create-build --raw '' -``` +### Parameters -Minimum payload shape: +Most fields come from `build-plan.py`; the table records what should end up in the final payload for a `node_exporter`-only build. -```json -{ - "build_type_id": "", - "build_platforms": [], - "build_flavors": [""], - "target_channel": "beta", - "projects": [ - { - "name": "node_exporter", - "build_ref": { "name": "", "type": "git_branch" }, - "testing": { "qa_ref": "" } - } - ], - "jenkins_jobs": [] -} -``` +| Field | Value | +| --- | --- | +| BS project name | `node_exporter` | +| `build_type_id` | `5ac2787bdf7e526d4a5f0259` (CloudLinux OS packages) | +| `build_platforms` | `CL7`, `CL8`, `CL9`, `CL10`, `ubuntu22_04_ext_cpanel` | +| `build_flavors` | `alt-php-els` (id `68b1ad89aa0264b2618434c8`) | +| `target_channel` | `beta` | +| `build_ref.name` | **Branch (or tag) to build.** `build-plan.py` reads this from the current `git` checkout in the workspace — confirm you are on the intended branch (your feature branch, not `master`) before generating the plan. | +| `build_ref.type` | `git_branch` or `git_tag`. | +| `testing.qa_ref` (per project) and top-level `qa_ref` | **Branch checked out in the QA repo for Jenkins jobs.** `build-plan.py` defaults both to `"master"` regardless of `build_ref.name` — override to your feature branch if the QA side has matching changes. | -`build_ref.type` options: `git_branch`, `git_tag`, or `gerrit_change` (for `refs/changes/XX/NNNNN/PS` refs — the `qa_ref` should then be `NNNNN/PS`). +### Jenkins jobs (node_exporter-relevant) -The CLI returns a build ID. Build URL: `https://build.cloudlinux.com/#/build/`. +`build-plan.py` emits the workspace-wide plan covering every project in the workspace. For a `node_exporter`-only build, filter `projects[]` down to `node_exporter` and keep **only** these jobs in `jenkins_jobs[]`: -### Step 4 — Monitor - -```bash -/root/ai-workspace/cl-aiworkspaces/workspace-side/mcps/mcp-cli-wrapper.sh build-system \ - get-build --build-id -``` - -### Step 5 — Debug failures - -Search logs for errors: - -```bash -/root/ai-workspace/cl-aiworkspaces/workspace-side/mcps/mcp-cli-wrapper.sh build-system \ - search-build-logs --build-id --query "error" -``` - -Common failure patterns: - -| Symptom | Likely cause | Fix | -|---|---|---| -| `FAILED` in test output | Test regression | Update the test — do not revert the code fix | -| `ModuleNotFoundError` / `ImportError` | New dependency not declared | Add to the `.spec` `Requires`/`BuildRequires` (or equivalent) | -| `SyntaxError` in build log | Source typo | Fix the source | -| `%files`/`%install` mismatch | Spec file vs installed layout drift | Update the spec stanzas | -| Dependency-resolution errors | `Requires` constraint wrong | Check spec file version constraints | - -After fixing, push to the same branch and re-run steps 1–3. +| Job name | Build System `_id` | +| --- | --- | +| `CMT-end-server-tools` | `635b962c2afd3e1feec603bd` | +| `clpro-ubuntu-tests` | `677e40a2f1b69faa0d69baf6` |