Skip to content

Recover userservices_limit on IPMachinesService from its server group - #185

Open
janpenitent wants to merge 1 commit into
v4.0from
fix-ipmachines-userservices-limit
Open

Recover userservices_limit on IPMachinesService from its server group#185
janpenitent wants to merge 1 commit into
v4.0from
fix-ipmachines-userservices-limit

Conversation

@janpenitent

@janpenitent janpenitent commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Problem

Short-name macros {usec} / {use} / {left} render empty on metapools (and as garbage 0 / 0% / -1 on standalone pools) for any pool backed by a Static Multiple IP service.

Reported by a customer on 4.0.0 build 20260630, but it affects every installation since d84e5ac38.

Cause

d84e5ac38 ("Heavy redone of Physical Machines using server groups as backend") dropped the userservices_limit calculation from IPMachinesService and never reimplemented it over the new data source. The class now inherits the base default, consts.UNLIMITED (-1).

That value is not only cosmetic:

  • ServicePool.get_max() falls back to service.get_instance().userservices_limit whenever max_srvs == 0.
  • For these pools max_srvs is always 0: IPMachinesService.uses_cache = False, so the pool-save handler zeroes initial_srvs, cache_l1_srvs, cache_l2_srvs and max_srvs no matter what the admin types.
  • Therefore the service limit is the only cap — and it has been UNLIMITED since the regression. These pools currently have no effective cap at all, and there is no configuration workaround.
  • UsageInfoVars blanks all four macros when total <= 0, hence the empty macros. The standalone-pool path in uds/web/util/services.py substitutes raw, hence the -1 leaking to the UI.

Fix

Declare userservices_limit_field() on IPMachinesService, counting the servers of its server group. Service.unmarshal() already resolves this member (int / NumericField / callable), including the try/except fallback and the negative clamp — same mechanism OpenGnsysService uses.

    def userservices_limit_field(self) -> int:
        return fields.get_server_group_from_field(self.server_group).servers.count()

Machines in maintenance are counted: the limit is the number of registered machines, not the currently usable ones. Counting only non-maintenance ones would let putting a machine into maintenance lower the pool max below what is already assigned. That is why enumerate_servers() (which filters maintenance_mode=False) is not reused.

5 added lines, no new imports, no migrations, no GUI/API/serialization changes.

Tests

TestServiceMulti.test_userservices_limit — marshal/unmarshal roundtrip plus the maintenance-mode case.

Heads-up before merging

Restoring the cap is the correct pre-d84e5ac38 behaviour, but any installation currently holding more live UserServices than registered machines will start getting MaxServicesReachedError, and the admin cannot raise the limit because max_srvs is forced to 0. Worth a release note.

Two separate GUI nits found while tracing this, deliberately not touched here:

  • 5.0 labels max_srvs as "Max services per user" when it is the pool-wide maximum (4.0 has the correct wording).
  • The Availability tab renders fully editable for services with uses_cache = False, even though all four fields are always saved as 0.

@github-actions
github-actions Bot requested a review from dkmstr July 30, 2026 15:12
Since the migration of Physical Machines to server groups as backend, the
service stopped reporting its userservices_limit, so it was inherited as
UNLIMITED from the base Service class.

As a consequence, pools of this service with "Maximum number of services"
set to 0 got an unlimited usage info, and the {use}/{usec}/{left}/{total}
macros of pools and metapools were replaced by an empty string (metapools)
or by 0/0%/-1 (pools).

Now the limit is recovered on unmarshal from the servers of the server
group, as it was done before the migration. Machines on maintenance are
also counted, because the limit is the number of registered machines.
@janpenitent
janpenitent force-pushed the fix-ipmachines-userservices-limit branch from 3cbe55f to 4b1aaf2 Compare July 31, 2026 11:50
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.

2 participants