Imported from NVIDIA/nvmesh-management (
AGENTS.md). Install upstream withnpx skills add NVIDIA/nvmesh-management. Copyright stays with the author.
AGENTS.md
Guidance for AI coding agents working in the NVMesh Management repo. Optimized for what an agent needs to be useful here. Human-facing docs live in README.md, public/introduction.md, and public/docs/.
Overview
Management server for NVMesh (NVIDIA's distributed block storage). Express-based Node.js app that exposes the REST/Websocket API, persists configuration in MongoDB, communicates with cluster nodes (target/client) via Kafka, and ships a server-rendered + React frontend out of public/.
Related repos
This codebase references and coordinates with several other NVMesh components. When the task requires reading or modifying their code, fetch them from:
| Component | Repo |
|---|---|
interop-db (required sibling, must live at ../interop-db) |
https://gitlab-master.nvidia.com/excelero/interop-db/ |
client, target, TOMA, managementAgent, MCS |
https://gitlab-master.nvidia.com/excelero/nvmesh |
upgrader / UpgradeAgent |
https://gitlab-master.nvidia.com/excelero/upgrader |
Don't guess their behavior from names referenced in this repo — read the source in the appropriate repo when correctness depends on it.
Stack
- Runtime: Node.js
>=17 <19(seepackage.jsonengines). - Web: Express 5, EJS layouts (
views/), Passport (local + client-cert). - DB: MongoDB (
mongodb-legacy,winston-mongodb). Sibling repo../interop-dbis a hard dependency (preinstallchecks for it). - Messaging: Kafka via
kafkajs. Topics + routing inmodules/kafka.js,modules/kafkaRouter.js. - Realtime:
socket.io+ custom websocket layer (modules/websocket.js,models/websocketMessages/). - Frontend: React 18 (transpiled with Babel via Gulp), Sass, served from
public/. JSX is rewritten to.jsat build time (see.babelrc.jsmodule-resolver). - Validation:
ajvJSON schemas undervalidationSchemes/, plugged in viamiddlewares/isValidRequest.js. - Telemetry: OpenTelemetry SDK (logs/metrics/traces). Bootstrap in
modules/openTelemetry.js. - Lint/test: ESLint 7 (
.eslintrc.json), Mocha 9 (.mocharc.json).
Common commands
| Task | Command |
|---|---|
Install deps (requires ../interop-db checked out) |
npm install |
| Build (gulp default) | npm run build |
| Start server (after build) | npm start |
| Dev mode (build + watchers) | npx gulp dev |
| Watchers only | npx gulp watch |
| Lint | npm run lint (or npx gulp eslint) |
| Backend tests (full suite) | npm test |
| Single backend test file | npx mocha --exit test/testVolumes.js |
| Single test by name | npx mocha --exit --grep "<pattern>" |
| Frontend tests | npm run test-ui |
| Compile Sass | npx gulp compileSass |
| Rebuild React components | npx gulp buildComponents |
| Regenerate API docs | npx gulp apidoc |
Mocha is asyncOnly: true (.mocharc.json) — every test must return a promise or use async.
Layout
Backend
app.js— Express bootstrap, route mounting, session, passport, sockets.bootstrapper.js— startup sequencing (DB, Kafka, services, OT).consts.js— central enums (component names, statuses, upgrade types, kafka topics, etc.). Add new enums here.routes/— Express routers, one file per resource. Thin: validate → call module.modules/— business logic; one file per domain (volume.js,upgrade.js,client.js,kafkaRouter.js, …). This is where real work lives.models/— DB / message schemas (Mongo collections, kafka/websocket message shapes).validationSchemes/— AJV schemas, mirrorsroutes/layout.definitions/holds shared sub-schemas.middlewares/— auth (isAuthenticated,isAdminRole), validation (isValidRequest), feature gates (isServiceAvailable,isDeprecated).services/— long-running services (nvmeshmgr,sendEmailOnServiceStop.js) and shared helpers inservices_common/.initServices/,system.d/,RPM/,nginx/,prestart.sh,build_docker.sh— packaging / deployment.upgradeScripts/,dump/,db_dump/,recoverdb.sh,dbBackup.js,restoreDB.sh— DB lifecycle / migrations.test/— Mocha specs (test*.js), shared helpers intestCommons/,testUtils/.simulation/,slash-tests/— out-of-process test rigs.ci/,.gitlab-ci.yml— CI config.
Frontend
public/javascripts/components/— React tree (App.jsx,Router.jsx,pages/,services/,shared/,core/).public/javascripts/components_js/— generated, do not edit.public/stylesheets/— Sass sources.views/— EJS templates served by Express.
Conventions
- Indentation: tabs (
.eslintrc.json:"indent": ["error", "tab"]). Don't auto-convert to spaces. - Quotes: single. Semicolons: required. Max line length: 160.
- Module style: CommonJS in backend (
require/module.exports). Frontend uses ES modules + JSX, transpiled. - Async: prefer
async/await; tests must be async (asyncOnly). - camelCase for identifiers;
properties: neverallowed (DB / API field names may keep their existing casing). - Logging: use the project logger (
logger.js), neverconsole.login committed code. - Errors: throw / pass
error.js-style errors; routes translate to HTTP via the standard error middleware. - Adding an endpoint:
- Add route in
routes/<resource>.js. - Add AJV schema in
validationSchemes/<resource>/and wire viaisValidRequest. - Put logic in
modules/<resource>.js(not in the route handler). - If a new enum value is needed, add it to
consts.js. - Add a Mocha test in
test/test<Resource>.jscovering happy path + a validation rejection.
- Add route in
- Adding a Kafka message: define the shape in
models/kafkaMessages/, register routing inmodules/kafkaRouter.js. - Adding a websocket message: define in
models/websocketMessages/, emit throughmodules/websocket.js/objectNotifier.js. - Frontend imports: import
.jsxfiles without the extension; the babelmodule-resolverrewrites.jsx → .js.
Tests
- Backend tests live in
test/, file patterntest*.js. Mocha config in.mocharc.json(30s timeout,asyncOnly,exit: true). - Use helpers in
test/testCommons/andtest/testUtils/rather than rolling your own setup. - New backend behavior should add at least one happy-path test and one failure/validation test.
- Frontend component tests live under
public/javascripts/components/test/and run vianpm run test-ui. - Don't commit
test/test.log.
Commits / PRs
- Reference the relevant NVMESH Jira ticket in the commit message (e.g.
NVMESH-8543). The user's~/.cursor/rules/jira-default-project.mdcalready defaults bare numbers to the NVMESH project. - Run
npm run lintand the relevant tests before declaring a task done. - Don't commit generated frontend output (
public/javascripts/components_js/),.patchfiles, ad-hoc dumps, ornode_modules/. - The repo also has a per-feature Cursor rule at
.cursor/rules/ndu-feature.mdc— read it before touching NDU/upgrade code.
Gotchas
interop-dbsibling repo is required.npm installwill refuse to run if../interop-dbdoesn't exist. Clone it from https://gitlab-master.nvidia.com/excelero/interop-db/ into a sibling directory (../interop-db).- Generated React output (
public/javascripts/components_js/) is gitignored and rebuilt by Gulp — never hand-edit, always change the.jsxsource and rebuild. .jsx → .jsrewrite at build time means runtime imports look like.jseven though sources are.jsx. When searching for a module, look for the.jsx.- Tabs, not spaces. ESLint will fail the build if you mix.
- Mongo driver is
mongodb-legacy. Don't introduce calls that assume the modern driver's promise-only API without checking the wrapper inmodules/mongoDBWrapper.js/modules/mongoDB.js. consts.jsis huge and load-bearing — many modules destructure from it. Add new constants here rather than re-declaring locally.- Upgrade / NDU code is intricate. See
.cursor/rules/ndu-feature.mdcfor the orchestration model (step ordering, locks,verifyVolumesAvailability) before changing anything inmodules/upgrade*.jsorroutes/upgrade*.js. - SEC stripe-size rounding: for
STRIPED_ERASURE_CODING,createVolumeByRAIDLevelsilently roundsstripeSizeup to a multiple ofDEFAULT_STRIPE_SIZE_BLOCKS * dataBlocks(=32 * dataBlocks). The user-supplied value is advisory; downstream code must read it back from the persisted volume. See.cursor/rules/volume-allocation-feature.mdc. - Ops scripts (
recoverdb.sh,restoreDB.sh,dbBackup.js,clearDB.js,dropDB.js, scripts underupgradeScripts/) touch real DB state — never run them as a side effect of a code task.
Definition of done
- Code change scoped to the task; no incidental refactors.
-
npm run lintpasses. - Affected Mocha tests added/updated and
npm test(or the targeted file) passes. - If a route changed: AJV schema updated and
npx gulp apidocrerun if API doc text changed. - If a constant/enum was introduced: added to
consts.js. - Commit message references the NVMESH Jira ticket.