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 {
