blob: 85d66a0fa921e563d4aa78fa3a2276b55c4f509c [file] [view]
# AGENTS instructions
## Working Style
- Prefer the smallest correct change. Do not add features, abstractions, refactors, or cleanup that were not asked for.
- Keep diffs surgical. Every changed line should trace back to the task.
Do not reformat, rewrap, or rename adjacent code "while you are here".
- Match the surrounding module before introducing a new pattern.
Reuse existing Ozone helpers, test scaffolding, and service abstractions where possible.
- Reuse existing Ozone and Ratis utilities when the surrounding code already uses them.
Prefer extending an existing helper over duplicating logic or adding a new one-off abstraction.
- If there are multiple reasonable interpretations, state the tradeoff and ask instead of guessing.
- Do not wrap lines early just to make them look uniform. The checkstyle maximum (see `hadoop-hdds/dev-support/checkstyle/checkstyle.xml`) is 120 characters for Java. Use the full 120 characters before wrapping; never break a line that fits on one line.
- Use established Ozone vocabulary in code, docs, and PR text:
SCM, OM, datanode, container, pipeline, volume, bucket, key, snapshot,
Recon, FSO, OBS, and S3 Gateway.
Avoid inventing new architecture terms unless the repo already uses them.
## Repository Snapshot
Apache Ozone is a multi-module Maven project. The root coordinates and version live in [`pom.xml`](./pom.xml).
Tech stack:
- Java 8 bytecode with JDK 21 runtime compatibility (see the `[21,]` profile in `pom.xml`)
- Maven build
- Hadoop RPC and gRPC over Protobuf
- RocksDB for persistent metadata
- Apache Ratis for replicated state
- JUnit 5 for tests
Two top-level aggregators:
- `hadoop-hdds/`: storage layer and shared infrastructure.
Key submodules include `server-scm`, `container-service`, `framework`,
`managed-rocksdb`, and `interface-{admin,client,server}`.
- `hadoop-ozone/`: Ozone services and clients.
Key submodules include `ozone-manager`, `s3gateway`, `recon`, `datanode`,
`dist`, `integration-test*`, and `ozonefs*`.
Service boundaries:
1. SCM manages containers, pipelines, and replication metadata.
2. OM manages namespace, keys, buckets, volumes, snapshots, and most user-visible metadata.
3. Datanodes serve container data and participate in Ratis pipelines.
4. Recon provides observability and derived metadata views.
5. S3 Gateway and OzoneFS expose external APIs on top of OM and HDDS services.
Cross-cutting changes often span multiple layers.
A feature or bug fix may need updates in `hadoop-hdds/interface-*`,
server-side handling, client translation code, and integration tests.
## Local Environment
- Use a JDK 21 runtime locally. Source and target compatibility remain Java 8.
- Ozone formatting conventions are shared through `.editorconfig`.
- If Maven behaves unexpectedly, check `java -version` and `mvn -version` first.
## Commands
Default local build flags:
- Use `-DskipShade -DskipRecon -DskipDocs` for iterative local work.
- Drop `-DskipShade` only when you need filesystem artifacts or tests that depend on the shaded Ozone FS jar.
- Drop `-DskipRecon` only when you are changing Recon UI or server behavior that must be built locally.
- Drop `-DskipDocs` only when you are changing docs or doc-generation logic.
Primary commands:
- Iterative full build: `mvn clean install -DskipTests -DskipShade -DskipRecon -DskipDocs`
- Full compile/verify smoke check: `mvn clean verify -DskipTests -DskipShade -DskipRecon -DskipDocs`
- Rebuild one module and its dependencies:
`mvn -pl :ozone-manager -am install -DskipTests -DskipShade -DskipRecon -DskipDocs`
- Run one unit test class: `mvn -pl :ozone-manager test -Dtest=TestOzoneManagerLock -DskipShade -DskipRecon -DskipDocs`
- Run one unit test method:
`mvn -pl :ozone-manager test -Dtest=TestOzoneManagerLock#testLockingOrder -DskipShade -DskipRecon -DskipDocs`
- Run one integration test class:
`mvn -pl :ozone-integration-test test -Dtest=TestOmContainerLocationCache -DskipShade -DskipRecon`
CI-aligned local checks live under
[`hadoop-ozone/dev-support/checks/`](./hadoop-ozone/dev-support/checks/).
Prefer these when validating a change because they match CI layout and reporting:
- `./hadoop-ozone/dev-support/checks/unit.sh`
- `./hadoop-ozone/dev-support/checks/integration.sh`
- `./hadoop-ozone/dev-support/checks/checkstyle.sh`
- `./hadoop-ozone/dev-support/checks/rat.sh`
- `./hadoop-ozone/dev-support/checks/author.sh`
Notes:
- The check scripts write results under `target/<check-name>/` (or `$OUTPUT_DIR`).
- `build.sh` honors `FAIL_FAST=true`, `ITERATIONS=N`, and `OZONE_WITH_COVERAGE=true`.
### Local Cluster
- Build a runnable distribution when you need compose assets or a local tarball: `mvn -Pdist -DskipTests package`
- Start the default compose cluster from
`hadoop-ozone/dist/target/ozone-*-SNAPSHOT/compose/ozone`:
`OZONE_REPLICATION_FACTOR=3 ./run.sh -d`
- `.run/` contains IntelliJ run configurations for SCM, OM, Recon, datanodes, shells, S3 Gateway, and HA variants.
## Repository Structure
Key paths:
- `hadoop-hdds/interface-*`: Protobuf definitions and protocol-facing interfaces
- `hadoop-hdds/server-scm`: SCM server behavior
- `hadoop-hdds/container-service`: datanode-side container handling
- `hadoop-hdds/framework`: shared service infrastructure
- `hadoop-hdds/managed-rocksdb`: RocksDB wrappers and helpers
- `hadoop-ozone/ozone-manager`: OM request handling and namespace logic
- `hadoop-ozone/s3gateway`: S3-compatible gateway
- `hadoop-ozone/recon`: Recon backend and UI
- `hadoop-ozone/datanode`: Ozone datanode service pieces outside HDDS container-service
- `hadoop-ozone/integration-test*`: Mini-cluster and integration coverage
- `hadoop-ozone/dist`: distribution assembly and compose definitions
- `hadoop-ozone/dev-support/checks`: scripts that mirror CI checks
- `.run/`: IDE launch configurations for local services and HA topologies
## Change Boundaries
- Keep service responsibilities separated.
Do not move OM logic into SCM paths, bypass existing request/response layers,
or introduce cross-service shortcuts just because they are convenient.
- When changing a wire type, expect to update the Protobuf definition,
translators, server-side logic, and relevant compatibility or integration tests.
- Prefer existing bucket-layout, snapshot, and upgrade abstractions over one-off conditionals.
- Do not hand-edit generated sources or generated web artifacts when a source file or generation step exists.
- For integration coverage, extend an existing suite, base class, or cluster provider
before creating a new `MiniOzoneCluster` lifecycle.
Reuse existing cluster utilities where practical.
## Coding Standards
- Use 2-space indentation and stay within 120 characters.
- Add the Apache license header to new files unless the surrounding area is explicitly exempted by RAT configuration.
- Do not add `@author` tags.
- Keep comments concrete and local to the code. Avoid vague architecture prose or newly invented terminology.
- Prefer existing helpers and utility methods over new abstractions for single-call-site use.
- When touching code that already follows a specific local pattern,
stay consistent with that pattern instead of normalizing the whole file.
## Testing Standards
- New behavior and bug fixes should come with tests.
- Start with the narrowest useful test:
- unit tests for local logic
- integration tests when the behavior depends on service boundaries, cluster lifecycle, storage, RPC, or upgrade flows
- When adding integration coverage, prefer merging it into an existing suite
over creating a brand-new test class that spins up another cluster for similar coverage.
- Before wrapping up a non-trivial change, run `./hadoop-ozone/dev-support/checks/checkstyle.sh`.
- If you added files or changed license headers, run `./hadoop-ozone/dev-support/checks/rat.sh`.
- If you touched shell tooling, run `./hadoop-ozone/dev-support/checks/bats.sh`.
- Use `acceptance.sh` and `kubernetes.sh` only when the changed area actually depends on those environments.
## Commits and PRs
- Every change should map to an Apache Jira in the HDDS project.
- Branch names usually start with the Jira ID, for example `HDDS-1234`.
- PR titles must be `HDDS-1234. Short summary of the change`.
- Prefer commit subjects that also start with the Jira ID when it is known,
for example `HDDS-1234. Fix snapshot purge regression`.
- For larger changes, use incremental commits so reviewers can inspect the delta.
Do not rewrite branch history unless explicitly asked.
- To bring a branch up to date with `master`, merge instead of rebasing: `git merge --no-edit origin/master`
- Avoid force-push when updating a PR unless a maintainer explicitly asks for rewritten history.
- PR descriptions should include the Jira link, the problem statement,
the chosen approach, and how the patch was tested.
- When non-trivial content is generated with AI tooling,
disclose it in the PR description as `Generated-by: TOOL (MODEL)`.
See the ASF generative tooling policy.
## Ask First
- Large new features or design changes that may need an Ozone Enhancement Proposal
- Large cross-module refactors that are not required for the task
- New third-party dependencies
- Protobuf or RPC changes with compatibility impact
- RocksDB layout, metadata schema, or upgrade/finalization changes
- Broad terminology or naming cleanups across many files
## Never
- Commit secrets, credentials, or tokens
- Use destructive git commands unless explicitly requested
- Hand-edit generated files when the source or generation workflow exists
- Add unrelated cleanup, formatting churn, or speculative abstractions to the same change
## References
- [`CONTRIBUTING.md`](./CONTRIBUTING.md)
- [`.github/pull_request_template.md`](./.github/pull_request_template.md)
- [`hadoop-ozone/dev-support/checks/README.md`](./hadoop-ozone/dev-support/checks/README.md)
- [`hadoop-hdds/dev-support/checkstyle/checkstyle.xml`](./hadoop-hdds/dev-support/checkstyle/checkstyle.xml)
- [`dev-support/rat/rat-exclusions.txt`](./dev-support/rat/rat-exclusions.txt)
- [Ozone Enhancement Proposals](https://ozone.apache.org/docs/next/developer-guide/project/enhancement-proposal)
## Security
When assessing a potential security vulnerability in Apache Ozone, complete
these steps before drafting any report or reaching any security conclusion.
### Step 1 — Read the threat model
Read **[THREAT_MODEL.md](THREAT_MODEL.md)**: the multi-service trust boundaries,
the **secure mode** knob, the properties provided vs. left to the operator, and
the known non-findings.
### Step 2 — Read the security policy
Read **[SECURITY.md](SECURITY.md)** for how to report.
### Key scoping facts (see THREAT_MODEL.md)
- Ozone is a cluster of network services (S3 Gateway, OM, SCM/internal-CA,
Datanodes/Ratis, Recon). Roles: untrusted client, authenticated-but-
unauthorized user, operator, service peer, bounded-Byzantine datanode.
- **Secure mode** (`ozone.security.enabled=true`) is load-bearing: a finding
that only manifests in non-secure (dev) mode is out of model (section 5a).
- Ozone does **not** own its dependencies' security — the Kerberos KDC, Ranger
policy correctness, the SCM CA private key, KMS keys, and network isolation
are the operator's (sections 3/9/10). Route such findings there.
- Ratis (Raft) safety holds under an honest majority; a Byzantine majority is
out of scope.
- integration-test modules, and test utilities are out of scope.
### Then assess
Route the finding to exactly one disposition in **THREAT_MODEL.md section 13**,
citing the section. If it cannot be routed, it is a `MODEL-GAP` surface it.