You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by di...@apache.org on 2026/05/20 05:06:45 UTC
(airavata-custos) 07/07: Enabling member level allocation restriction
This is an automated email from the ASF dual-hosted git repository.
DImuthuUpe pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/airavata-custos.git
commit 3d102159ee7bd58767ad639114574e37c7440fb6
Author: DImuthuUpe <di...@gmail.com>
AuthorDate: Wed May 20 00:58:31 2026 -0400
Enabling member level allocation restriction
---
.../internal/subscribers/members.go | 8 +++----
docs/API-Docs.md | 26 +++++++++++++---------
...n_membership_resource_override_amounts.down.sql | 20 +++++++++++++++++
...ion_membership_resource_override_amounts.up.sql | 20 +++++++++++++++++
...llocation_membership_resource_override_store.go | 13 ++++++-----
pkg/models/allocation.go | 3 ++-
...pute_allocation_membership_resource_override.go | 14 ++++++++----
7 files changed, 78 insertions(+), 26 deletions(-)
diff --git a/connectors/SLURM/Association-Mapper/internal/subscribers/members.go b/connectors/SLURM/Association-Mapper/internal/subscribers/members.go
index dfcc4ee70..2a087ab60 100644
--- a/connectors/SLURM/Association-Mapper/internal/subscribers/members.go
+++ b/connectors/SLURM/Association-Mapper/internal/subscribers/members.go
@@ -116,19 +116,19 @@ func (a *AssociationSubscriber) SubscribeToComputeAllocationMembershipResourceOv
grpTres := []client.TRES{}
- if allocationResource.ResourceType == "GrpTRES" {
+ if override.OverrideResourceAmount > 0 {
grpTres = append(grpTres, client.TRES{
Type: allocationResource.ResourceType,
- Count: override.OverriddenResourceAmount, // override.OverriddenResourceAmount is the SU amount, but SLURM needs the actual resource amount (e.g., number of CPU hours), so we need to convert it using the rate for the resource
+ Count: override.OverrideResourceAmount, // override.OverrideResourceAmount is the resource amount granted to the user for this resource (e.g., number of CPUs, GPUs).
})
}
grpTresMins := []client.TRES{}
- if allocationResource.ResourceType == "GrpTRESMins" {
+ if override.OverrideResourceTime > 0 {
grpTresMins = append(grpTresMins, client.TRES{
Type: allocationResource.ResourceType,
- Count: override.OverriddenResourceAmount,
+ Count: override.OverrideResourceTime, // override.OverrideResourceTime is the wall-clock time in minutes that the resource amount is granted for.
})
}
diff --git a/docs/API-Docs.md b/docs/API-Docs.md
index 325a219bc..3d9ded43c 100644
--- a/docs/API-Docs.md
+++ b/docs/API-Docs.md
@@ -1234,9 +1234,11 @@ List every per-resource override recorded against the given membership.
## Compute Allocation Membership Resource Overrides
-A `ComputeAllocationMembershipResourceOverride` records the SU amount of a
-specific resource (`ComputeAllocationResource`) that has been granted to a
-specific membership. There can be at most one override per
+A `ComputeAllocationMembershipResourceOverride` records the resource amount
+and wall-clock time of a specific resource (`ComputeAllocationResource`)
+that has been granted to a specific membership, overriding whatever the
+parent `ComputeAllocationResourceMapping` would otherwise provide. There can
+be at most one override per
`(compute_allocation_membership_id, compute_allocation_resource_id)` pair
(enforced by a unique key). Overrides are cascade-deleted when either the
parent membership or the parent resource is removed.
@@ -1251,18 +1253,19 @@ Create a new override.
{
"compute_allocation_membership_id": "membership-123",
"compute_allocation_resource_id": "resource-456",
- "overridden_resource_amount": 10000
+ "override_resource_amount": 24,
+ "override_resource_time": 1440
}
```
-- All three fields are required.
-- `overridden_resource_amount` must be non-negative.
+- `compute_allocation_membership_id` and `compute_allocation_resource_id` are required.
+- `override_resource_amount` and `override_resource_time` must be non-negative (default `0`).
- `id` is generated server-side when omitted.
**Errors**
- `400` — missing required fields, referenced membership/resource not found,
- or negative `overridden_resource_amount`.
+ or negative `override_resource_amount` / `override_resource_time`.
- `409` — an override already exists for this `(membership, resource)` pair.
### GET `/compute-allocation-membership-resource-overrides/{id}`
@@ -1367,19 +1370,20 @@ curl -s $BASE/compute-allocations/$ALLOC_ID/memberships | jq
# List every allocation this user is a member of.
curl -s $BASE/users/$CLUSTER_USER_ACCT_ID/compute-allocation-memberships | jq
-# Grant the membership a per-resource SU override on the debug resource.
+# Grant the membership a per-resource override on the debug resource.
OVERRIDE_ID=$(curl -s -X POST $BASE/compute-allocation-membership-resource-overrides \
-H 'Content-Type: application/json' \
-d "{
\"compute_allocation_membership_id\":\"$MEMBERSHIP_ID\",
\"compute_allocation_resource_id\":\"$RES_ID\",
- \"overridden_resource_amount\":10
+ \"override_resource_amount\":1,
+ \"override_resource_time\":20
}" | jq -r .id)
-# Bump the override amount.
+# Bump the override amount and time.
curl -s -X PUT $BASE/compute-allocation-membership-resource-overrides/$OVERRIDE_ID \
-H 'Content-Type: application/json' \
- -d '{"overridden_resource_amount":15000}' | jq
+ -d '{"override_resource_amount":16,"override_resource_time":960}' | jq
# List every resource override for the membership.
curl -s $BASE/compute-allocation-memberships/$MEMBERSHIP_ID/resource-overrides | jq
diff --git a/internal/db/migrations/000013_compute_allocation_membership_resource_override_amounts.down.sql b/internal/db/migrations/000013_compute_allocation_membership_resource_override_amounts.down.sql
new file mode 100644
index 000000000..c937d1aca
--- /dev/null
+++ b/internal/db/migrations/000013_compute_allocation_membership_resource_override_amounts.down.sql
@@ -0,0 +1,20 @@
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements. See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership. The ASF licenses this file
+-- to you under the Apache License, Version 2.0 (the
+-- "License"); you may not use this file except in compliance
+-- with the License. You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing,
+-- software distributed under the License is distributed on an
+-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+-- KIND, either express or implied. See the License for the
+-- specific language governing permissions and limitations
+-- under the License.
+
+ALTER TABLE compute_allocation_membership_resource_overrides
+ DROP COLUMN override_resource_time,
+ CHANGE COLUMN override_resource_amount overridden_resource_amount BIGINT NOT NULL DEFAULT 0;
diff --git a/internal/db/migrations/000013_compute_allocation_membership_resource_override_amounts.up.sql b/internal/db/migrations/000013_compute_allocation_membership_resource_override_amounts.up.sql
new file mode 100644
index 000000000..bc18ef857
--- /dev/null
+++ b/internal/db/migrations/000013_compute_allocation_membership_resource_override_amounts.up.sql
@@ -0,0 +1,20 @@
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements. See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership. The ASF licenses this file
+-- to you under the Apache License, Version 2.0 (the
+-- "License"); you may not use this file except in compliance
+-- with the License. You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing,
+-- software distributed under the License is distributed on an
+-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+-- KIND, either express or implied. See the License for the
+-- specific language governing permissions and limitations
+-- under the License.
+
+ALTER TABLE compute_allocation_membership_resource_overrides
+ CHANGE COLUMN overridden_resource_amount override_resource_amount BIGINT NOT NULL DEFAULT 0,
+ ADD COLUMN override_resource_time BIGINT NOT NULL DEFAULT 0 AFTER override_resource_amount;
diff --git a/internal/store/compute_allocation_membership_resource_override_store.go b/internal/store/compute_allocation_membership_resource_override_store.go
index 1e0f0d1b0..d89f11e9c 100644
--- a/internal/store/compute_allocation_membership_resource_override_store.go
+++ b/internal/store/compute_allocation_membership_resource_override_store.go
@@ -27,7 +27,7 @@ import (
"github.com/apache/airavata-custos/pkg/models"
)
-const computeAllocationMembershipResourceOverrideColumns = "id, compute_allocation_membership_id, compute_allocation_resource_id, overridden_resource_amount"
+const computeAllocationMembershipResourceOverrideColumns = "id, compute_allocation_membership_id, compute_allocation_resource_id, override_resource_amount, override_resource_time"
type mysqlComputeAllocationMembershipResourceOverrideStore struct {
db *sqlx.DB
@@ -99,9 +99,9 @@ func (s *mysqlComputeAllocationMembershipResourceOverrideStore) FindByResource(c
func (s *mysqlComputeAllocationMembershipResourceOverrideStore) Create(ctx context.Context, tx *sql.Tx, o *models.ComputeAllocationMembershipResourceOverride) error {
_, err := tx.ExecContext(ctx,
`INSERT INTO compute_allocation_membership_resource_overrides
- (id, compute_allocation_membership_id, compute_allocation_resource_id, overridden_resource_amount)
- VALUES (?, ?, ?, ?)`,
- o.ID, o.ComputeAllocationMembershipID, o.ComputeAllocationResourceID, o.OverriddenResourceAmount)
+ (id, compute_allocation_membership_id, compute_allocation_resource_id, override_resource_amount, override_resource_time)
+ VALUES (?, ?, ?, ?, ?)`,
+ o.ID, o.ComputeAllocationMembershipID, o.ComputeAllocationResourceID, o.OverrideResourceAmount, o.OverrideResourceTime)
return err
}
@@ -110,9 +110,10 @@ func (s *mysqlComputeAllocationMembershipResourceOverrideStore) Update(ctx conte
`UPDATE compute_allocation_membership_resource_overrides
SET compute_allocation_membership_id = ?,
compute_allocation_resource_id = ?,
- overridden_resource_amount = ?
+ override_resource_amount = ?,
+ override_resource_time = ?
WHERE id = ?`,
- o.ComputeAllocationMembershipID, o.ComputeAllocationResourceID, o.OverriddenResourceAmount, o.ID)
+ o.ComputeAllocationMembershipID, o.ComputeAllocationResourceID, o.OverrideResourceAmount, o.OverrideResourceTime, o.ID)
return err
}
diff --git a/pkg/models/allocation.go b/pkg/models/allocation.go
index 582bce606..a8fcd3976 100644
--- a/pkg/models/allocation.go
+++ b/pkg/models/allocation.go
@@ -103,7 +103,8 @@ type ComputeAllocationMembershipResourceOverride struct {
ID string `json:"id" db:"id"`
ComputeAllocationMembershipID string `json:"compute_allocation_membership_id" db:"compute_allocation_membership_id"`
ComputeAllocationResourceID string `json:"compute_allocation_resource_id" db:"compute_allocation_resource_id"`
- OverriddenResourceAmount int64 `json:"overridden_resource_amount" db:"overridden_resource_amount"` // The overridden SU amount for the user for this specific resource, e.g., 150 SUs for GPU hours, etc.
+ OverrideResourceAmount int64 `json:"override_resource_amount" db:"override_resource_amount"` // The overridden amount of the resource for the user (e.g., number of CPUs, GPUs).
+ OverrideResourceTime int64 `json:"override_resource_time" db:"override_resource_time"` // The overridden wall-clock time in minutes that the resource amount is granted for.
}
type ComputeAllocationMembership struct {
diff --git a/pkg/service/compute_allocation_membership_resource_override.go b/pkg/service/compute_allocation_membership_resource_override.go
index 81fadee40..e3148cd00 100644
--- a/pkg/service/compute_allocation_membership_resource_override.go
+++ b/pkg/service/compute_allocation_membership_resource_override.go
@@ -40,8 +40,11 @@ func (s *Service) CreateComputeAllocationMembershipResourceOverride(ctx context.
if o.ComputeAllocationResourceID == "" {
return nil, fmt.Errorf("%w: compute_allocation_resource_id is required", ErrInvalidInput)
}
- if o.OverriddenResourceAmount < 0 {
- return nil, fmt.Errorf("%w: overridden_resource_amount must be non-negative", ErrInvalidInput)
+ if o.OverrideResourceAmount < 0 {
+ return nil, fmt.Errorf("%w: override_resource_amount must be non-negative", ErrInvalidInput)
+ }
+ if o.OverrideResourceTime < 0 {
+ return nil, fmt.Errorf("%w: override_resource_time must be non-negative", ErrInvalidInput)
}
if m, err := s.memberships.FindByID(ctx, o.ComputeAllocationMembershipID); err != nil {
@@ -141,8 +144,11 @@ func (s *Service) UpdateComputeAllocationMembershipResourceOverride(ctx context.
if o == nil || o.ID == "" {
return nil, fmt.Errorf("%w: membership resource override id is required", ErrInvalidInput)
}
- if o.OverriddenResourceAmount < 0 {
- return nil, fmt.Errorf("%w: overridden_resource_amount must be non-negative", ErrInvalidInput)
+ if o.OverrideResourceAmount < 0 {
+ return nil, fmt.Errorf("%w: override_resource_amount must be non-negative", ErrInvalidInput)
+ }
+ if o.OverrideResourceTime < 0 {
+ return nil, fmt.Errorf("%w: override_resource_time must be non-negative", ErrInvalidInput)
}
existing, err := s.membershipOverrides.FindByID(ctx, o.ID)
if err != nil {