Skip to content

feat(balancing): remap target storage on node-local storage clusters#114

Open
arturod67 wants to merge 3 commits into
credativ:mainfrom
YorkHost-fr:feat/target-storage-remap
Open

feat(balancing): remap target storage on node-local storage clusters#114
arturod67 wants to merge 3 commits into
credativ:mainfrom
YorkHost-fr:feat/target-storage-remap

Conversation

@arturod67

Copy link
Copy Markdown

ProxLB always migrates keeping the source storage id. On clusters built on node-local (non-shared) storage, the source storage id often does not exist on the target node, so the migration is rejected by Proxmox at validation time ("storage 'X' is not available on node 'Y'") before any task is created.

Add optional target storage resolution:

  • balancing.target_storage_auto (default False): pick the active/enabled storage on the target node accepting the guest content type ('images' for VMs, 'rootdir' for CTs) with the most free space.
  • balancing.target_storage_map (optional): pin a storage per target node, taking precedence over auto selection.

VMs receive 'targetstorage', CTs receive 'target-storage'. Default behaviour is unchanged (both options off => no remap), preserving correctness on shared-storage clusters.

Adds unit tests for _resolve_target_storage and documents the options in the README and example config.

ProxLB always migrates keeping the source storage id. On clusters built on
node-local (non-shared) storage, the source storage id often does not exist on
the target node, so the migration is rejected by Proxmox at validation time
("storage 'X' is not available on node 'Y'") before any task is created.

Add optional target storage resolution:
- balancing.target_storage_auto (default False): pick the active/enabled
  storage on the target node accepting the guest content type ('images' for
  VMs, 'rootdir' for CTs) with the most free space.
- balancing.target_storage_map (optional): pin a storage per target node,
  taking precedence over auto selection.

VMs receive 'targetstorage', CTs receive 'target-storage'. Default behaviour is
unchanged (both options off => no remap), preserving correctness on
shared-storage clusters.

Adds unit tests for _resolve_target_storage and documents the options in the
README and example config.
Comment thread proxlb/models/tests/test_balancing_resolve_target_storage.py Outdated
Comment thread proxlb/models/tests/test_balancing_resolve_target_storage.py Outdated
Comment thread proxlb/models/tests/test_balancing_resolve_target_storage.py Outdated
Comment thread proxlb/models/balancing.py Outdated
Comment thread proxlb/models/balancing.py Outdated
Comment thread proxlb/models/balancing.py Outdated
@dlucredativ

Copy link
Copy Markdown
Contributor

While testing I realized that the targetstorage Feature only works when the resource is not HA-managed. If it is HA-managed, the API will run the hamigrate task, but the qmigrate task that it is supposed to trigger, fails in the same way as you mentioned above: "storage 'X' is not available on node 'Y'".

In ProxLB this creates an infinite loop:

Balancing: HA migration request UPID:... (guest: foobar) was accepted but the underlying qmigrate task is not visible yet. Waiting...

@dlucredativ dlucredativ left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would like to postpone the commit regarding the capacity guard and fix #115 first. The storage api calls you make for this guard would be part of the fix.

  • gather node storage information from nodes(*).storage.get()
  • gather guest storage information from nodes(*).storage(*).content.get()

Also in the long run, I would like to make the guard obsolete and instead let proxlb-solver handle it.

claude added 2 commits July 3, 2026 17:37
- Replace the copy-pasted author header in the resolve-target-storage tests.
- Add the missing type annotations in the test helpers and type the storage
  fixtures with the proxmoxer stubs' Storage TypedDict (via a 'Storages'
  alias in the TYPE_CHECKING block, as suggested in review).
- Annotate the storage listing call in _resolve_target_storage with the
  same 'Storages' alias.
- Drop the unnecessary int() coercions on the 'active'/'enabled' storage
  flags and on 'avail'.
- Match the requested content type against the comma-separated content
  tokens instead of a substring check, with a regression test.
Migrations of HA-managed guests are routed through the Proxmox HA stack
(hamigrate), which does not forward the 'targetstorage' / 'target-storage'
parameter to the migration task it spawns. On node-local storage clusters
that task then fails with "storage 'X' is not available on node 'Y'",
leaving ProxLB waiting for a qmigrate task that never appears.

Detect HA-managed guests via /cluster/ha/resources (fetched lazily, once
per balancing pass) and skip their migration with an explanatory warning
whenever a target storage remap would be applied. Guests without a remap
keep the existing behaviour, and an API error while listing HA resources
safely degrades to 'not HA-managed'.

Documents the limitation in the README and the example config.
@arturod67 arturod67 force-pushed the feat/target-storage-remap branch from 04992c7 to fbaa15a Compare July 3, 2026 17:39
@arturod67

Copy link
Copy Markdown
Author

Done I've dropped the capacity guard from this PR so it can be revisited on top of the #115 fix, where the nodes().storage.get() / storage().content.get() calls will live. The branch now only contains the original feature, the review fixes, and the HA-managed guest skip (the infinite-loop issue you hit while testing: since the HA stack doesn't forward targetstorage, ProxLB now checks /cluster/ha/resources once per pass and skips those guests with an explanatory warning instead).

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.

3 participants