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 <[email protected]>
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 {

Reply via email to