Skip to content

feat(storage): add persistent volume snapshot/resize/persistence suite (DATASVC-XX-02/03/04)#439

Open
abegnoche wants to merge 10 commits into
mainfrom
cursor/block-storage-trio-datasvc-35b8
Open

feat(storage): add persistent volume snapshot/resize/persistence suite (DATASVC-XX-02/03/04)#439
abegnoche wants to merge 10 commits into
mainfrom
cursor/block-storage-trio-datasvc-35b8

Conversation

@abegnoche

@abegnoche abegnoche commented May 28, 2026

Copy link
Copy Markdown
Member

What

Closes #321
Closes #322
Closes #323

Adds a new storage validation suite covering the persistent volume trio:

  • snapshot_lifecycle: snapshot a volume, restore it, and verify sentinel data.
  • volume_resize: grow the volume and in-guest filesystem, then verify size.
  • volume_persistence: stop/start the instance and verify volume/data persistence.

storage.yaml is intentionally broad so future object/file storage checks can land in the same suite.

Changes

  • Added suites/storage.yaml provider-agnostic contract.
  • Added AWS implementation under providers/aws/config/storage.yaml and providers/aws/scripts/storage/.
  • Added my-isv scaffold under providers/my-isv/config/storage.yaml and providers/my-isv/scripts/storage/.
  • Added storage to MY_ISV_DOMAINS (make demo-storage).
  • Added AWS script tests in isvctl/tests/test_aws_storage_scripts.py.

Validation

  • ISVTEST_INCLUDE_UNRELEASED=1 AWS_PROFILE=ncp-isv-lab uv run isvctl test run -f isvctl/configs/providers/aws/config/storage.yaml -- -v -s — AWS live run passed setup, all three storage tests, and teardown.
  • make demo-test
  • uvx pre-commit run
Open in Web Open in Cursor 

Summary by CodeRabbit

  • New Features

    • Added end-to-end storage validation support, including volume creation, snapshot/restore verification, resizing, restart persistence checks, and teardown.
    • Introduced a new storage suite with provider wiring and demo/example coverage to run the flow.
  • Tests

    • Added automated coverage for AWS storage validation scripts and shared helpers, including robust error handling for missing instances and transient resize verification issues.
  • Bug Fixes

    • Ensured storage-related checks are properly recognized by validation label requirements.
  • Documentation

    • Updated the suite documentation and test plan labeling for the new storage scenarios.

@copy-pr-bot

copy-pr-bot Bot commented May 28, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a storage validation suite and wiring for provider-agnostic block-storage checks, plus AWS reference scripts and my-isv demo stubs for create, snapshot, resize, persistence, and teardown flows.

Changes

Storage validation suite

Layer / File(s) Summary
Suite contract, wiring, and docs
isvctl/configs/suites/storage.yaml, isvctl/configs/suites/README.md, isvctl/configs/providers/my-isv/scripts/README.md, docs/test-plan.yaml, Makefile, scripts/validate_suite_wiring.py
Defines the storage suite contract, adds storage references in suite and domain docs, tags the block-storage test-plan entries, adds storage to the Makefile domain list, and requires the storage label for wired suite checks.
Shared AWS EBS helper module
isvctl/configs/providers/aws/scripts/common/ebs.py
Adds shared EBS helpers for instance lookup, volume and snapshot lifecycle operations, by-id device resolution, best-effort cleanup, and SSH-based mount/sentinel reads.
AWS storage scripts and config
isvctl/configs/providers/aws/config/storage.yaml, isvctl/configs/providers/aws/scripts/storage/*, isvctl/configs/providers/aws/scripts/common/ebs.py
Wires the AWS storage command phases and adds executable scripts for volume creation, snapshot verification, resize verification, persistence verification, and teardown, all emitting structured JSON results.
AWS storage script tests
isvctl/tests/test_aws_storage_scripts.py
Exercises the AWS helper functions and each storage script entrypoint across success, failure, cleanup, and teardown-skip cases.
my-isv provider stub scripts and config
isvctl/configs/providers/my-isv/config/storage.yaml, isvctl/configs/providers/my-isv/scripts/storage/*.py
Wires the my-isv storage command phases and adds demo-mode stub scripts for create, snapshot, resize, persistence, and teardown flows.

Estimated code review effort: 4 (Complex) | ~60 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR implements the three linked block-storage checks: snapshot lifecycle, volume resize, and persistence across restarts.
Out of Scope Changes check ✅ Passed The extra docs, wiring, tests, and demo target updates all support the storage suite and stay within scope.
Docstring Coverage ✅ Passed Docstring coverage is 87.80% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the new storage suite and its snapshot, resize, and persistence focus.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/block-storage-trio-datasvc-35b8

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

@abegnoche abegnoche changed the title feat(block-storage): add EBS snapshot/resize/persistence suite (DATASVC-XX-02/03/04) feat(storage): add EBS snapshot/resize/persistence suite (DATASVC-XX-02/03/04) Jun 12, 2026
@cursor cursor Bot changed the title feat(storage): add EBS snapshot/resize/persistence suite (DATASVC-XX-02/03/04) feat(storage): add persistent volume snapshot/resize/persistence suite (DATASVC-XX-02/03/04) Jun 12, 2026
@abegnoche

Copy link
Copy Markdown
Member Author

Note: currently in draft because it adds a new storage.yaml file

cursoragent and others added 8 commits July 9, 2026 18:28
Adds a provider-agnostic block-storage validation suite plus the AWS
reference implementation covering the block-storage trio that share one
fixture (launch instance + create/attach EBS volume):

- DATASVC-XX-02 (#321) snapshot_lifecycle: CreateSnapshot -> restore to a
  new volume -> attach/mount -> byte-compare the sentinel data.
- DATASVC-XX-03 (#322) volume_resize: ModifyVolume + in-guest
  growpart/resize2fs, verifying the guest sees the larger filesystem.
- DATASVC-XX-04 (#323) volume_persistence: stop/start the instance and
  verify the volume stays attached with its data intact.

Reuses existing StepSuccessCheck + FieldExistsCheck + CrudOperationsCheck
(no new validation classes, no released_tests.json change). common/ebs.py
centralizes the boto3 volume/snapshot lifecycle and the Nitro NVMe by-id
device mapping; create_volume/teardown_volume own the shared fixture.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Alexandre Begnoche <abegnoche@users.noreply.github.com>
Adds the my-isv living-example scaffold (TODO blocks + ISVCTL_DEMO_MODE
dummy success) for the five block-storage scripts and the provider config
that imports the suite. Adds block-storage to MY_ISV_DOMAINS so
'make demo-test' exercises the whole pipeline end-to-end with no cloud.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Alexandre Begnoche <abegnoche@users.noreply.github.com>
Adds the block-storage suite to the contracts list and per-step field
table in suites/README.md, and a block-storage/ row to the my-isv
scaffold domains table.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Alexandre Begnoche <abegnoche@users.noreply.github.com>
Covers the common/ebs Nitro device mapping and modification waiter, plus
happy-path and failure cases (guest setup failure, snapshot content
mismatch, cleanup leak, growpart failure, volume detached after restart)
for the five AWS block-storage scripts using boto3/ssh fakes.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Alexandre Begnoche <abegnoche@users.noreply.github.com>
boto3 waiters raise WaiterError (a BotoCoreError, not a ClientError), so
a waiter timeout would have propagated uncaught and skipped the JSON
contract the validations depend on - the same failure mode #438 fixed for
S3. Broaden the AWS script except clauses to (ClientError, BotoCoreError)
and make the ebs cleanup helpers swallow BotoCoreError so best-effort
teardown never raises out of a finally block. Also pass the snapshot ID
to cleanup when CreateSnapshot succeeded but the completion wait failed.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Alexandre Begnoche <abegnoche@users.noreply.github.com>
…new suite

Move the DATASVC-XX-02/03/04 block-storage validations out of the
standalone suites/block-storage.yaml and into suites/vm.yaml, so block
storage is validated under the existing VM contract rather than adding
another suite file.

- vm.yaml: add fixture_volume / snapshot_lifecycle / volume_resize /
  volume_persistence / volume_teardown_checks. These activate only when a
  provider config supplies the matching volume steps; a standard VM run
  skips them automatically. Renamed the volume teardown check to
  volume_teardown_checks to avoid colliding with the VM teardown_checks,
  and dropped the redundant instance_launched (covered by setup_checks).
- providers/aws|my-isv/config/block-storage.yaml: import suites/vm.yaml,
  rename the command group to vm (must match the inherited platform), and
  exclude the ssh-labelled VM host checks (cloud-init/GPU/OS/NIM are not
  block-storage concerns).
- delete suites/block-storage.yaml.
- docs: drop block-storage from the suites list and point the domain's
  contract at vm.yaml.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Alexandre Begnoche <abegnoche@users.noreply.github.com>
Replace the earlier approach of folding block-storage validations into
suites/vm.yaml. Instead, add a dedicated suites/storage.yaml umbrella
contract (platform: storage) that today covers persistent block storage
(DATASVC-XX-02/03/04) and is the future home for object/file storage
checks - avoiding both suite proliferation and the skip-noise of sharing
the VM contract.

- suites/storage.yaml: new umbrella contract (was the block-storage suite).
- suites/vm.yaml: reverted to its original VM-only validations.
- providers/aws|my-isv/config/block-storage.yaml: import suites/storage.yaml
  and use the 'storage' command group (matches the suite platform).
- docs: list the 'storage' suite and point the block-storage domain's
  contract at storage.yaml.

The block-storage provider domain (config/block-storage.yaml +
scripts/block-storage/) stays as the concrete block-volume implementation
of the storage contract.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Alexandre Begnoche <abegnoche@users.noreply.github.com>
Complete the storage-suite rename by aligning the runnable provider domain
with the suite name.

- providers/aws|my-isv/config/storage.yaml replace config/block-storage.yaml.
- providers/aws|my-isv/scripts/storage/ replace scripts/block-storage/.
- Makefile demo domain is now storage, so the focused smoke test is
  make demo-storage.
- Tests and docs now refer to storage paths and the AWS unit test file is
  renamed to test_aws_storage_scripts.py.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Alexandre Begnoche <abegnoche@users.noreply.github.com>
@cursor cursor Bot force-pushed the cursor/block-storage-trio-datasvc-35b8 branch from fc35116 to 25bca23 Compare July 9, 2026 18:29
Add test_id and labels to storage.yaml checks (DATASVC02-01 through
DATASVC04-01), register the storage suite in validate_suite_wiring.py,
and sync the storage label into docs/test-plan.yaml. These guardrails
landed on main after PR #439 was opened.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Alexandre Begnoche <abegnoche@users.noreply.github.com>
@abegnoche abegnoche marked this pull request as ready for review July 9, 2026 18:32
@abegnoche abegnoche requested a review from a team as a code owner July 9, 2026 18:32
@abegnoche

Copy link
Copy Markdown
Member Author

/ok to test cfe0ce8

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

🔐 TruffleHog Secret Scan

No secrets or credentials found!

Your code has been scanned for 700+ types of secrets and credentials. All clear! 🎉

🔗 View scan details

🕐 Last updated: 2026-07-09 18:33:45 UTC | Commit: cfe0ce8

@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: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@isvctl/configs/providers/aws/scripts/storage/create_volume.py`:
- Around line 136-154: The instance lookup in the create_volume flow can crash
before the existing error handling because describe_instances() may return an
empty Reservations list and the code indexes into
instances["Reservations"][0]["Instances"][0]. Add an explicit empty-result check
in the create_volume script before reading instance details, and surface a JSON
error path when no instance is found. Apply the same safeguard in the
corresponding DescribeInstances handling in snapshot_lifecycle, volume_resize,
and volume_persistence so they all fail gracefully instead of raising
IndexError.

In `@isvctl/configs/providers/aws/scripts/storage/volume_resize.py`:
- Line 167: The final size-verification call in the volume resize flow is
unguarded, so a transient AWS failure can crash the script after the resize work
has already completed. Update the `main` flow in `volume_resize.py` around the
`describe_volumes` verification for `ebs_grew` to wrap it in the same
`try`/`except (ClientError, BotoCoreError)` pattern used elsewhere, and return
the existing JSON error response instead of letting a traceback escape.

In `@isvctl/configs/providers/my-isv/scripts/storage/volume_resize.py`:
- Line 60: Reject non-positive resize deltas in demo mode by validating the
parsed `--grow-gib` value before `success=True` is set in `volume_resize.py`.
Update the demo-mode path in `main` (and any helper logic around
`new_size_gib`/`old_size_gib`) so it fails or exits early when `grow_gib <= 0`
or would not increase the volume size, instead of reporting success. Keep the
check close to the existing resize calculation so the script’s demo-mode
contract is enforced consistently.

In `@isvctl/configs/suites/storage.yaml`:
- Around line 78-91: The storage suite checks for fixture_volume (and the
similar cases in the other storage blocks) only validate IDs and operation
names, so they miss the real contract outcomes. Update the relevant check
definitions to require the documented result fields from the storage workflow,
using the existing FieldExistsCheck/related checks tied to the storage fixture
steps, so the suite verifies the seeded sentinel, restore content match, and
filesystem size expectations rather than just
create/attach/format/mount/write_sentinel being present.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 0bc78e71-1cb7-4da3-9765-b4c067d72597

📥 Commits

Reviewing files that changed from the base of the PR and between 7a001b5 and cfe0ce8.

📒 Files selected for processing (20)
  • Makefile
  • docs/test-plan.yaml
  • isvctl/configs/providers/aws/config/storage.yaml
  • isvctl/configs/providers/aws/scripts/common/ebs.py
  • isvctl/configs/providers/aws/scripts/storage/create_volume.py
  • isvctl/configs/providers/aws/scripts/storage/snapshot_lifecycle.py
  • isvctl/configs/providers/aws/scripts/storage/teardown_volume.py
  • isvctl/configs/providers/aws/scripts/storage/volume_persistence.py
  • isvctl/configs/providers/aws/scripts/storage/volume_resize.py
  • isvctl/configs/providers/my-isv/config/storage.yaml
  • isvctl/configs/providers/my-isv/scripts/README.md
  • isvctl/configs/providers/my-isv/scripts/storage/create_volume.py
  • isvctl/configs/providers/my-isv/scripts/storage/snapshot_lifecycle.py
  • isvctl/configs/providers/my-isv/scripts/storage/teardown_volume.py
  • isvctl/configs/providers/my-isv/scripts/storage/volume_persistence.py
  • isvctl/configs/providers/my-isv/scripts/storage/volume_resize.py
  • isvctl/configs/suites/README.md
  • isvctl/configs/suites/storage.yaml
  • isvctl/tests/test_aws_storage_scripts.py
  • scripts/validate_suite_wiring.py

Comment thread isvctl/configs/providers/aws/scripts/storage/create_volume.py
Comment thread isvctl/configs/providers/aws/scripts/storage/volume_resize.py Outdated
Comment thread isvctl/configs/providers/my-isv/scripts/storage/volume_resize.py
Comment thread isvctl/configs/suites/storage.yaml
Add ebs.describe_instance() and use it in all four AWS storage scripts so
an empty DescribeInstances response returns JSON instead of IndexError.
Wrap the final describe_volumes size check in volume_resize.py, preserve
API error messages when verify_size already failed, and reject
non-positive --grow-gib in the my-isv demo stub.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Alexandre Begnoche <abegnoche@users.noreply.github.com>
@abegnoche

Copy link
Copy Markdown
Member Author

/ok to test 798f788

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants