Skip to content

fix(rest): refuse props edits on create doors, honour definitions_only, drop tracker numbers - #216

Merged
Andrei Kvapil (kvaps) merged 3 commits into
mainfrom
fix/create-spawn-prop-fields
Nov 2, 2026
Merged

Andrei Kvapil (kvaps) merged 3 commits into
mainfrom
fix/create-spawn-prop-fields

Conversation

@kvaps

@kvaps Andrei Kvapil (kvaps) commented Oct 24, 2026 •

Copy link
Copy Markdown
Member

rd create and rg spawn decoded override_props, delete_props and delete_namespaces and dropped them, answering success for an edit that never happened. A create has no props to edit yet, and neither golinstor nor python-linstor sends these fields on either call, so a non-empty one is now refused with 400 naming the field and where props go instead. With #190 this covers what #202 lists for spawn. partial is still decoded and not acted on; that predates this PR and stays open.

rg spawn also ignored definitions_only (linstor rg spawn --definition-only) and placed replicas anyway. It now stops after the definition and its volumes.

Operator-facing strings no longer carry internal tracker numbers: errors, events and log lines said things like "(Bug 174)" or "pending Phase 12". The src_snap_name refusal now says what is not supported, and the comment that still called that field a no-op is gone. A test walks every string literal in pkg, internal and cmd and fails on a tracker number, so new ones don't creep back.

Fixes #210
Fixes #211

Testing

  • Each new refusal and the definitions_only branch were reverted in turn, and the named test fails each time.
  • An L6 cli-matrix cell and an L7 replay (rg-spawn-definitions-only) pin the definitions-only spawn at operator-CLI level. Not run on a stand.
  • go test ./...: green apart from the known pkg/rest shutdown flake.
  • golangci-lint on the changed lines: clean.
  • Not run on a stand.

@coderabbitai

coderabbitai Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 103 files, which is 3 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

Check out review usage here.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 480056d2-545f-4e57-962d-e7c3da9840bb
Commits

Reviewing files that changed from the base of the PR and between 1652387 and 1ac8621.

Files selected for processing: 103
  • CLAUDE.md
  • api/v1alpha1/resourcedefinition_types.go
  • cmd/apiserver/bind.go
  • cmd/apiserver/bind_flag_test.go
  • cmd/apiserver/bind_test.go
  • cmd/apiserver/main.go
  • cmd/controller/bind.go
  • cmd/controller/bind_flag_test.go
  • cmd/controller/bind_test.go
  • cmd/controller/main.go
  • cmd/satellite/flags.go
  • cmd/satellite/flags_test.go
  • cmd/satellite/main.go
  • config/crd/bases/blockstor.cozystack.io_resourcedefinitions.yaml
  • config/rbac/role.yaml
  • config/rbac/satellite_role.yaml
  • docs/cli-parity-known-deltas.md
  • docs/layer-stack.md
  • docs/linstor-migration.md
  • docs/usage.md
  • internal/cli/snapshot.go
  • internal/cli/snapshot_restore_prepared_test.go
  • internal/controller/export_test.go
  • internal/controller/group_layer_stack_watch_test.go
  • internal/controller/layer_stack_test.go
  • internal/controller/resource_controller.go
  • internal/controller/resourcedefinition_controller.go
  • internal/controller/resourcedefinition_layer_stack.go
  • internal/controller/resourcedefinition_layer_stack_test.go
  • internal/controller/tiebreaker_no_drbd_bug_334_test.go
  • pkg/api/v1/annotations.go
  • pkg/api/v1/layer_stack.go
  • pkg/api/v1/resource_definition.go
  • pkg/api/v1/resource_group.go
  • pkg/effectiveprops/effective.go
  • pkg/effectiveprops/effective_test.go
  • pkg/linstormigrate/convert.go
  • pkg/linstormigrate/layer_stack_test.go
  • pkg/luks/luks.go
  • pkg/luks/luks_bug_175_test.go
  • pkg/luks/luks_holds_data_test.go
  • pkg/luks/luks_test.go
  • pkg/rest/autoplace.go
  • pkg/rest/create_doors_props_modify_test.go
  • pkg/rest/flags_validation.go
  • pkg/rest/kv_store.go
  • pkg/rest/nodes.go
  • pkg/rest/operator_messages_test.go
  • pkg/rest/props_modify.go
  • pkg/rest/rd_clone.go
  • pkg/rest/rd_clone_validation_test.go
  • pkg/rest/resource_definitions.go
  • pkg/rest/restore_effective_layers_test.go
  • pkg/rest/rg_deleted_race_test.go
  • pkg/rest/server.go
  • pkg/rest/snapshot_restore.go
  • pkg/rest/snapshots.go
  • pkg/rest/spawn.go
  • pkg/rest/vd_passphrase_bug_233.go
  • pkg/satellite/agent.go
  • pkg/satellite/controllers/config.go
  • pkg/satellite/controllers/device_holds_data_event_internal_test.go
  • pkg/satellite/controllers/layer_stack_pin.go
  • pkg/satellite/controllers/layer_stack_pin_internal_test.go
  • pkg/satellite/controllers/manager.go
  • pkg/satellite/controllers/physicaldevice.go
  • pkg/satellite/controllers/resource.go
  • pkg/satellite/controllers/snapshot_fetcher.go
  • pkg/satellite/controllers/snapshot_fetcher_test.go
  • pkg/satellite/reconciler.go
  • pkg/satellite/reconciler_drbd_test.go
  • pkg/satellite/reconciler_luks_holds_data_test.go
  • pkg/satellite/stream/client.go
  • pkg/satellite/stream/redial_spec_test.go
  • pkg/satellite/stream/server.go
  • pkg/satellite/stream/stream.go
  • pkg/satellite/stream/tls.go
  • pkg/satellite/stream/tls_test.go
  • pkg/storage/exec.go
  • pkg/storage/lvm/lvm_common.go
  • pkg/storage/lvm/lvm_thick.go
  • pkg/storage/lvm/lvm_thick_test.go
  • pkg/storage/lvm/thick_wipe_test.go
  • pkg/store/effective_layer_stack_test.go
  • pkg/store/inmemory_resource_definition.go
  • pkg/store/k8s/layer_stack_group_case_test.go
  • pkg/store/k8s/layer_stack_test.go
  • pkg/store/k8s/objectmeta_write_extended_bug_235_test.go
  • pkg/store/k8s/resource_definitions.go
  • pkg/store/restore_target.go
  • pkg/store/storetest/storetest.go
  • stand/blockstor-apiserver-deploy.yaml
  • stand/blockstor-apiserver-tls.yaml
  • stand/blockstor-deploy.yaml
  • stand/blockstor-satellite-daemonset.yaml
  • tests/e2e/cli-matrix/rg-layer-stack-pin.sh
  • tests/e2e/cli-matrix/rg-spawn-definitions-only.sh
  • tests/e2e/tiebreaker-r-d-cleanup.sh
  • tests/operator-harness/lib.sh
  • tests/operator-harness/replay-runner.sh
  • tests/operator-harness/replay/rg-layer-stack-pin.yaml
  • tests/operator-harness/replay/rg-spawn-definitions-only.yaml
  • tests/scenarios/03-networking.md

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Andrei Kvapil (@kvaps) NOT LGTM. The refusals and the definitions_only branch are correct. Two smaller things block.

  1. Five satellite log lines still carry tracker numbers, and the new test doesn't catch them. The pattern in operator_messages_test.go:20 matches Bug but not BUG, so pkg/satellite/reconciler.go still logs BUG-028 at lines 2536 and 3334, and BUG-048 at 2891, 2899 and 2984. They are the same kind of log.FromContext(ctx).Info line this PR rewrites for Bug 360 and Bug 366. With (?i) added, the test reports exactly these five. It leaves the persisted annotation key bug136.blockstor.cozystack.io/... alone, since nothing separates bug from 136. I also tried a wider pattern (lower case, bug#, phase10, scenario N) and found nothing else.

  2. The two new test files have no // SPDX-License-Identifier: Apache-2.0 header. AGENTS.md asks for it on every blockstor-authored Go file, and these are the only .go files under pkg, internal and cmd without one.

Things I checked and found fine:

  • No real client sends the props-modify fields on these two calls. golinstor v0.60.0's ResourceDefinitionCreate and ResourceGroupSpawn don't have them. python-linstor doesn't send them. linstor-csi never calls spawn at all: it uses ResourceDefinitions.Create with an empty envelope. Upstream's JsonGenTypes for both calls don't declare these fields either, so upstream already refuses them as unknown properties. The refusal uses writeError like the other 400s, so golinstor decodes it.
  • definitions_only now matches upstream's spawnResourceDefinition: 201, definition and volumes created, no autoplace.
  • Each mutation turns its test red: reverting either refusal, dropping any switch case, removing the definitions_only branch, and putting (Bug 180) back into a literal.
  • No Go test, e2e script or replay YAML matches the old wording of the rewritten strings, so the renames don't change behaviour.

CI never ran on af675d1. The force-push came two seconds before the base switched to main, and GitHub still shows the PR as conflicting. The compare API says 2 ahead and 0 behind main, and a local merge is clean, so pushing again should get both a fresh mergeability check and a CI run. The previous run on 8a65508 (same two patches, older base) failed TestGroupKWFSpawnAndDependentReAutoplace and recovery-deleting-convert. Both have failed on unrelated branches too (runs 40125502076, 40125493977, 40334484413). The spawn test runs spawn-resources without --definition-only and never reaches the new branch. DCO complains about 1652387, which is the squashed #190 commit on main, not one of the commits here.

Non-blocking:

  1. The CLI flag is --definition-only (see rsc_grp_cmds.py in linstor-client). The comment at create_doors_props_modify_test.go:80 and the PR body say --definitions-only.
  2. pkg/api/v1/resource_group.go:101 still says spawn is "the call linstor-csi uses to actually create a Resource from a group". That isn't true, and this PR already removed the same claim from spawn.go.
  3. There are text conflicts with #215 in cmd/controller/main.go (the --enable-rest-api help) and with #192 and #222 in vd_passphrase_bug_233.go. The other open PRs merge cleanly.

Comment thread pkg/rest/operator_messages_test.go Outdated
// "Bug 174", "Bug-020" and "Phase 12". They mean nothing to an operator
// reading an error, an event or a log line, so no string literal in the
// shipped code carries one; comments may.
var internalTrackerRef = regexp.MustCompile(`\bBug[- ][0-9]|\bPhase [0-9]`)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This misses BUG-028/BUG-048, which still ship in five reconciler.go log lines. (?i) catches them and still leaves the bug136. annotation key alone.

@@ -0,0 +1,72 @@
package rest

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing // SPDX-License-Identifier: Apache-2.0 header.

@@ -0,0 +1,159 @@
package rest

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing // SPDX-License-Identifier: Apache-2.0 header.

@kvaps

Copy link
Copy Markdown
Member Author

Thanks, head c386940.

The pattern is case-insensitive now, the five BUG-028/BUG-048 log lines are rewritten, and both test files carry the license header. The flag is --definition-only in the test comment and the PR body, and the ResourceGroupSpawn comment no longer says linstor-csi calls it. This push should also give CI and the mergeability check a fresh run.

I'll resolve the text conflicts with #215 and #222 on whichever lands second.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Andrei Kvapil (@kvaps) Both blockers from my last review are fixed at c386940. If I put a BUG-048 literal back into a reconciler.go log line, the tracker test fails, and it passes again without the (?i). The SPDX headers are in, and the new shell and replay files match their neighbours, which carry no header either.

I re-read the whole diff and ran the tests on a trial merge with main at 7bb6606. The new tests pass, and each of the three fixes fails its own test when I disable it. The other pkg/rest failures are the known 2s server-shutdown flake.

The red E2E lane 3 is recovery-deleting-convert (exit 2). It fails the same way on f64cf3b from #217 and on d9d2c29, and neither contains these commits. The scenario only sends override_props to the modify PUT, which this PR doesn't touch, so I don't think the diff causes it.

Two things that don't block. #215 touches the neighbouring flag help string in cmd/controller/main.go, so whichever PR lands second gets a small conflict there. CRD field descriptions still say "Phase 10.x", and operators see those in kubectl explain; that is outside the errors, events and logs this PR covers, so a follow-up is fine.

rd create and rg spawn decoded override_props, delete_props and
delete_namespaces and dropped them, answering success for an edit that
never happened. A create has no props to edit yet, and neither
golinstor nor python-linstor sends these fields there, so a non-empty
one is now refused with 400 naming the field and where props go
instead.

rg spawn also ignored definitions_only and placed replicas anyway; it
now stops after the definition and its volumes.

Error messages, events and log lines no longer carry internal tracker
numbers ("Bug 174", "pending Phase 12"). A test walks the shipped
string literals and fails on one. The src_snap_name refusal says what
is unsupported instead of naming a phase, and the stale comment that
called the field a no-op is gone.

Fixes #210
Fixes #211

Assisted-by: LLM
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
`linstor rg spawn-resources --definition-only` placed replicas before
the fix. An L6 cli-matrix cell and an L7 replay check that the
definition and its volume exist and that no replica appears over a
hold window.

Assisted-by: LLM
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
…ines

Five satellite log lines still carried BUG-028 and BUG-048, which the
test missed because it matched the mixed-case spelling only. The test
now matches in any case, and the two new test files carry the license
header. The spawn payload comment no longer says linstor-csi calls it.

Assisted-by: LLM
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
@kvaps

Copy link
Copy Markdown
Member Author

Your approval on c386940 was dismissed by my rebase onto main after #215 landed, sorry. The only change is the conflict in cmd/controller/main.go: --enable-rest-api keeps this PR's help text, --rest-bind-address keeps #215's loopback default and help. Head 1ac8621, the rest of the tree is the same.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Andrei Kvapil (@kvaps) Still LGTM, only the rebase changed since c386940. The conflict with #215 in the --enable-rest-api help keeps the loopback default. TestPlainListenerFlagUsesTheLoopbackDefault passes, and fails if I put ":3370" back. CI is green on 1ac8621.

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.

operator-facing errors and comments carry internal tracker numbers rd create and rg spawn accept delete_namespaces and drop it

2 participants