You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by la...@apache.org on 2026/07/23 19:18:44 UTC
(airavata-custos) 12/35: Create the tutorial allocation through the API so events fire
This is an automated email from the ASF dual-hosted git repository.
lahirujayathilake pushed a commit to branch pearc26
in repository https://gitbox.apache.org/repos/asf/airavata-custos.git
commit bffb209f6ac598e87fa415678e0179261c3531bf
Author: lahiruj <la...@gmail.com>
AuthorDate: Thu Jul 16 08:35:50 2026 -0400
Create the tutorial allocation through the API so events fire
---
.../seeds/pearc26/04_project_allocation.sql | 60 --------------
dev-ops/compose/seeds/pearc26/05_access_event.sql | 28 -------
dev-ops/compose/seeds/pearc26/README.md | 84 ++++++++++++++-----
dev-ops/compose/seeds/pearc26/setup-live.sh | 95 ++++++++++++++++++++++
4 files changed, 159 insertions(+), 108 deletions(-)
diff --git a/dev-ops/compose/seeds/pearc26/04_project_allocation.sql b/dev-ops/compose/seeds/pearc26/04_project_allocation.sql
deleted file mode 100644
index eff2713a3..000000000
--- a/dev-ops/compose/seeds/pearc26/04_project_allocation.sql
+++ /dev/null
@@ -1,60 +0,0 @@
--- 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.
-
--- PEARC26 seed 04: tutorial project, the allocation every approved
--- attendee joins, and its resource grant. The PI is the bootstrap
--- admin from seed 03, so the super admin operates on the project and
--- allocation directly.
---
--- The allocation name "pearc26-tutorial" is also the Slurm account name
--- and the usage-matching key, so it must stay shell-safe (no spaces).
--- The portal displays it verbatim. 25,000 SU matches the design's
--- decision record.
---
--- LIVE-CLUSTER NOTE: rows inserted here bypass the event bus, so the
--- SLURM Association-Mapper never sees them and no Slurm account is
--- created. Fine for local dev and the mocked test loop. For a live run
--- against nexus-dev, create the project/allocation/mapping through the
--- API instead (the spec's live gate does this) so the events fire.
-
-SET NAMES utf8mb4;
-SET time_zone = '+00:00';
-
-INSERT IGNORE INTO projects (id, originated_id, title, origination, project_pi_id, status)
-VALUES ('pearc26-project', 'PEARC26', 'PEARC26 Tutorial Workshop',
- 'WORKSHOP', 'pearc26-approver', 'ACTIVE');
-
-INSERT IGNORE INTO project_memberships (project_id, user_id, role)
-VALUES ('pearc26-project', 'pearc26-approver', 'PI');
-
-INSERT IGNORE INTO compute_allocations
- (id, project_id, name, status, compute_cluster_id,
- initial_su_amount, start_time, end_time)
-VALUES
- ('pearc26-allocation', 'pearc26-project', 'pearc26-tutorial', 'ACTIVE',
- '00000000-0000-0000-0000-000000000001',
- 25000, '2026-07-01 00:00:00', '2026-08-31 00:00:00');
-
--- Grant: all 4 debug-partition CPUs for the allocation window
--- (61 days = 87840 minutes). Native units x minutes, per the mapping
--- convention; the SU budget above is the spend cap.
-INSERT IGNORE INTO compute_allocation_resource_mappings
- (id, compute_allocation_id, compute_allocation_resource_id,
- resource_amount, resource_time)
-VALUES
- ('pearc26-map-debug-cpu', 'pearc26-allocation', 'pearc26-res-debug-cpu',
- 4, 87840);
diff --git a/dev-ops/compose/seeds/pearc26/05_access_event.sql b/dev-ops/compose/seeds/pearc26/05_access_event.sql
deleted file mode 100644
index 99b489861..000000000
--- a/dev-ops/compose/seeds/pearc26/05_access_event.sql
+++ /dev/null
@@ -1,28 +0,0 @@
--- 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.
-
--- PEARC26 seed 05: the event code attendees type on the request form.
--- Requires the access_events migration from the access-requests feature.
---
--- Approving a request with this code creates the account in
--- pearc26-org and a membership on pearc26-allocation.
-
-SET NAMES utf8mb4;
-SET time_zone = '+00:00';
-
-INSERT IGNORE INTO access_events (code, compute_allocation_id, organization_id)
-VALUES ('PEARC26', 'pearc26-allocation', 'pearc26-org');
diff --git a/dev-ops/compose/seeds/pearc26/README.md b/dev-ops/compose/seeds/pearc26/README.md
index 722b31ecc..fd13774a2 100644
--- a/dev-ops/compose/seeds/pearc26/README.md
+++ b/dev-ops/compose/seeds/pearc26/README.md
@@ -1,29 +1,71 @@
-# PEARC26 workshop seed set
+# PEARC26 workshop setup
-Self-contained, ordered seed data for the Access Requests trial-allocation
-flow. Duplicates parts of the older seeds on purpose — apply this folder
-alone on a fresh DB and the whole flow works.
+Ordered setup for the Access Requests trial-allocation flow. SQL seeds carry
+only the rows that fire no events (org, cluster, partition catalog, roles);
+everything event-bearing (project, allocation, resource grant) is created
+THROUGH THE API by `setup-live.sh` so the SLURM account and grant limits
+appear on the cluster automatically.
All cluster facts (name, partition, CPU counts) were read from the real
dev Slurm cluster (`nexus-dev`, login1 / 149.165.159.51) on 2026-07-16.
-Apply in order, after core migrations have run:
+## From scratch, in order
-```
-for f in dev-ops/compose/seeds/pearc26/0*.sql; do
- docker exec -i custos_db mariadb -uadmin -padmin custos < "$f"
-done
-```
+1. **Start the docker services** (from the repo root):
+
+ ```
+ docker compose -f dev-ops/compose/docker-compose.yml up -d
+ ```
+
+2. **Run the backend** (applies migrations on startup; needs the SLURM_*,
+ COMANAGE_*, OIDC_* values in the repo-root `.env`):
+
+ ```
+ set -a && source .env && set +a && go run ./cmd/server
+ ```
+
+3. **Seed the event-free data**:
+
+ ```
+ for f in dev-ops/compose/seeds/pearc26/0*.sql; do
+ docker exec -i custos_db mariadb -uadmin -padmin custos < "$f"
+ done
+ ```
+
+4. **Create the tutorial allocation through the API** (CILogon device
+ auth as the admin; requires the device grant enabled on the client):
+
+ ```
+ dev-ops/compose/seeds/pearc26/setup-live.sh
+ ```
+
+ Then verify on the cluster:
+
+ ```
+ sacctmgr -n show account pearc26-tutorial
+ sacctmgr -n show assoc account=pearc26-tutorial
+ ```
+
+5. **Run the portal** (`cd web && pnpm dev`) — attendees sign in, land on
+ `/no-access?event=PEARC26`, request access; approve from
+ Site administration > Access Requests. Approval provisions COmanage
+ (person + verified email + login identifier), LDAP/SSSD, and the SLURM
+ user association; the attendee can then `ssh nexus-<user>@<cluster>`
+ via CILogon device auth and submit jobs.
+
+To reset one attendee (registry person, custos rows, cluster cache):
+`scripts/reset-trial-test-user.sh <email> --yes`.
+
+## Files
| File | Creates |
|---|---|
| 01_org_cluster.sql | PEARC26 Attendees org; the `nexus-dev` cluster row |
| 02_resources_rates.sql | `debug` partition catalog entry + SU rate |
| 03_admin_role.sql | approver/bootstrap-admin user + `access-approver` role |
-| 04_project_allocation.sql | project (PI = the seed-03 admin), `pearc26-tutorial` allocation, resource mapping |
-| 05_access_event.sql | the PEARC26 event code row |
+| setup-live.sh | project (PI = seed-03 admin), `pearc26-tutorial` allocation (25000 SU), resource grant, PEARC26 access-event row |
-Notes:
+## Notes
- **The cluster row reuses id `00000000-0000-0000-0000-000000000001`
(= `CUSTOS_CLUSTER_ID`).** The COmanage subscriber only provisions
@@ -31,13 +73,15 @@ Notes:
different id means approvals silently never reach COmanage. The row
upserts the name to `nexus-dev` if `default_cluster.sql` got there
first.
-- 05 needs the `access_events` migration; apply it after the
- access-requests feature migration has run.
- The seed-03 user is approver, bootstrap admin, AND project PI: set
`CUSTOS_BOOTSTRAP_ADMIN_EMAIL=approver@pearc26.local` (or edit that
email to your own) and boot grants super_admin idempotently.
-- **Seeded allocations fire no events.** The SLURM Association-Mapper
- and COmanage provisioner are event-driven; SQL inserts bypass them.
- Live runs create the project/allocation/mapping via the API (see the
- goal spec's live gate).
-- Everything is `INSERT IGNORE` / upsert — safe to re-apply.
+- **Never create the allocation with SQL.** Seeded rows bypass the event
+ bus, so the SLURM account/grant never appear (this bit us once). If an
+ allocation must be replaced, tear it down and re-run `setup-live.sh`.
+- `setup-live.sh` refuses to run when an ACTIVE `pearc26-tutorial`
+ allocation already exists.
+- SQL seeds are `INSERT IGNORE` / upsert — safe to re-apply.
+- The SLURM API version matters: `SLURM_API_VERSION=40`. On v0.0.38 the
+ associations endpoint silently ignores creates (200, empty errors,
+ nothing written).
diff --git a/dev-ops/compose/seeds/pearc26/setup-live.sh b/dev-ops/compose/seeds/pearc26/setup-live.sh
new file mode 100755
index 000000000..6367e09e1
--- /dev/null
+++ b/dev-ops/compose/seeds/pearc26/setup-live.sh
@@ -0,0 +1,95 @@
+#!/usr/bin/env bash
+# PEARC26 live setup: creates the tutorial project, allocation, and resource
+# grant THROUGH THE API so the provisioning events fire (SLURM account +
+# grant limits appear on the cluster), then points the PEARC26 access event
+# at the new allocation. Run AFTER seeds 01-03 and with the backend running.
+#
+# Auth: CILogon device flow as the admin (client credentials from .env);
+# export ACCESS_TOKEN to skip the device flow with a ready bearer.
+#
+# Usage: dev-ops/compose/seeds/pearc26/setup-live.sh
+
+set -euo pipefail
+cd "$(dirname "$0")/../../../.."
+
+API="${CUSTOS_API:-http://localhost:8080}"
+DB_EXEC=(docker exec -i custos_db mariadb -u admin -padmin custos)
+
+set -a; source .env; set +a
+: "${CUSTOS_CLUSTER_ID:?missing in .env}"
+
+existing=$("${DB_EXEC[@]}" -N -e "SELECT COUNT(*) FROM compute_allocations WHERE name='pearc26-tutorial' AND status='ACTIVE'" 2>/dev/null || echo 0)
+if [ "$existing" != "0" ]; then
+ echo "An ACTIVE 'pearc26-tutorial' allocation already exists; tear it down first (or repoint access_events manually)."
+ exit 1
+fi
+
+if [ -z "${ACCESS_TOKEN:-}" ]; then
+ : "${OIDC_CLIENT_ID:?missing in .env}" "${OIDC_CLIENT_SECRET:?missing in .env}"
+ echo "== CILogon device authorization"
+ dev=$(curl -sf -X POST https://cilogon.org/oauth2/device_authorization \
+ -d "client_id=$OIDC_CLIENT_ID" -d "client_secret=$OIDC_CLIENT_SECRET" \
+ -d "scope=openid profile email org.cilogon.userinfo")
+ device_code=$(echo "$dev" | python3 -c "import json,sys; print(json.load(sys.stdin)['device_code'])")
+ echo "$dev" | python3 -c "import json,sys; d=json.load(sys.stdin); print('Authenticate at:', d.get('verification_uri_complete') or d.get('verification_uri')); print('Code:', d.get('user_code',''))"
+ interval=$(echo "$dev" | python3 -c "import json,sys; print(json.load(sys.stdin).get('interval',5))")
+ echo "Waiting for authentication..."
+ while true; do
+ sleep "$interval"
+ tok=$(curl -s -X POST https://cilogon.org/oauth2/token \
+ -d "client_id=$OIDC_CLIENT_ID" -d "client_secret=$OIDC_CLIENT_SECRET" \
+ -d "grant_type=urn:ietf:params:oauth:grant-type:device_code" \
+ -d "device_code=$device_code")
+ if echo "$tok" | grep -q access_token; then break; fi
+ if echo "$tok" | grep -qE "expired_token|access_denied"; then
+ echo "Device authorization failed: $tok"; exit 1
+ fi
+ done
+ # The backend verifier wants a JWT; some setups issue opaque access
+ # tokens, in which case the id_token is the JWT-shaped bearer.
+ ACCESS_TOKEN=$(echo "$tok" | python3 -c "
+import json,sys
+d=json.load(sys.stdin)
+a=d.get('access_token','')
+print(a if a.count('.')==2 else d.get('id_token',a))")
+ echo "Authenticated."
+fi
+
+capi() { # method path [json-body]
+ local method="$1" path="$2" body="${3:-}"
+ if [ -n "$body" ]; then
+ curl -sf -X "$method" -H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Type: application/json" "$API$path" -d "$body"
+ else
+ curl -sf -X "$method" -H "Authorization: Bearer $ACCESS_TOKEN" "$API$path"
+ fi
+}
+
+echo "== Creating project"
+project=$(capi POST /projects '{"originated_id":"PEARC26","title":"PEARC26 Tutorial Workshop","origination":"pearc26","project_pi_id":"pearc26-approver","status":"ACTIVE"}')
+project_id=$(echo "$project" | python3 -c "import json,sys; print(json.load(sys.stdin)['id'])")
+echo " project $project_id"
+
+echo "== Creating allocation (fires the SLURM account event)"
+start=$(date -u +%Y-%m-%dT%H:%M:%SZ)
+end=$(date -u -v+45d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "+45 days" +%Y-%m-%dT%H:%M:%SZ)
+alloc=$(capi POST /compute-allocations "{\"project_id\":\"$project_id\",\"name\":\"pearc26-tutorial\",\"status\":\"ACTIVE\",\"compute_cluster_id\":\"$CUSTOS_CLUSTER_ID\",\"initial_su_amount\":25000,\"start_time\":\"$start\",\"end_time\":\"$end\"}")
+alloc_id=$(echo "$alloc" | python3 -c "import json,sys; print(json.load(sys.stdin)['id'])")
+echo " allocation $alloc_id ($start -> $end)"
+
+echo "== Attaching the resource grant (fires the SLURM limits event)"
+capi POST "/compute-allocations/$alloc_id/resources" '{"compute_allocation_resource_id":"pearc26-res-debug-cpu","resource_amount":4,"resource_time":87840}' >/dev/null
+echo " grant: cpu x4 for 87840 minutes on partition debug"
+
+echo "== Recording PI membership and the PEARC26 access event"
+"${DB_EXEC[@]}" <<SQL
+INSERT IGNORE INTO project_memberships (project_id, user_id, role, added_time)
+VALUES ('$project_id', 'pearc26-approver', 'PI', NOW(6));
+INSERT INTO access_events (code, compute_allocation_id, organization_id)
+VALUES ('PEARC26', '$alloc_id', 'pearc26-org')
+ON DUPLICATE KEY UPDATE compute_allocation_id = '$alloc_id';
+SQL
+
+echo
+echo "Done. Verify on the cluster (allow a few seconds for the events):"
+echo " sacctmgr -n show account pearc26-tutorial"
+echo " sacctmgr -n show assoc account=pearc26-tutorial format=Account,User,Partition,GrpTRES,GrpTRESMins"