From 60944e0ddffdecdd2d609e2e511b060d528b533d Mon Sep 17 00:00:00 2001 From: KC Swanson Date: Fri, 17 Oct 2025 16:42:32 -0400 Subject: [PATCH 1/2] scripts to support running exec-able research containers --- rc-code/Dockerfile | 13 +++++++++++++ rc-code/build-n-push | 12 ++++++++++++ rc-code/longRC.r | 5 +++++ src/lib/aws-run-studies.ts | 2 +- src/lib/aws.ts | 1 + src/scripts/poll.ts | 11 ++++------- src/scripts/start-long-rc.ts | 32 ++++++++++++++++++++++++++++++++ 7 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 rc-code/Dockerfile create mode 100755 rc-code/build-n-push create mode 100644 rc-code/longRC.r create mode 100644 src/scripts/start-long-rc.ts diff --git a/rc-code/Dockerfile b/rc-code/Dockerfile new file mode 100644 index 0000000..cda2a0d --- /dev/null +++ b/rc-code/Dockerfile @@ -0,0 +1,13 @@ +# Use the SafeInsights R 4.5.1 base image +FROM harbor.safeinsights.org/safeinsights-public/base-container:r4.5.1-2025-09-19-15-47-18 + +RUN apt-get update && apt-get install -y \ + nano \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /code + +COPY longRC.r ./code/longRC.r + +CMD ["Rscript", "./code/longRC.r"] diff --git a/rc-code/build-n-push b/rc-code/build-n-push new file mode 100755 index 0000000..5716f48 --- /dev/null +++ b/rc-code/build-n-push @@ -0,0 +1,12 @@ +#!/bin/bash + +TAG="${1:-$(date +"%Y-%m-%d-%H-%M-%S")}" + +docker buildx build \ + --file Dockerfile \ + --platform=linux/amd64 \ + --progress=plain \ + -t harbor.safeinsights.org/openstax/code-builds/dev:$TAG \ + . + +docker push harbor.safeinsights.org/openstax/code-builds/dev:$TAG diff --git a/rc-code/longRC.r b/rc-code/longRC.r new file mode 100644 index 0000000..6fd9c59 --- /dev/null +++ b/rc-code/longRC.r @@ -0,0 +1,5 @@ +print("Welcome to the script.") +time <- 3600 +print(paste0("Waiting ", time / 60, " minutes ...")) +Sys.sleep(time) +print(paste0(time / 60, " minutes have passed. Script over.")) diff --git a/src/lib/aws-run-studies.ts b/src/lib/aws-run-studies.ts index 6574b94..ebbf82f 100644 --- a/src/lib/aws-run-studies.ts +++ b/src/lib/aws-run-studies.ts @@ -13,7 +13,7 @@ import { managementAppGetReadyStudiesRequest, toaGetJobsRequest, toaUpdateJobSta import 'dotenv/config' import { ManagementAppGetReadyStudiesResponse } from './types' -async function launchStudy( +export async function launchStudy( client: ECSClient, cluster: string, baseTaskDefinitionFamily: string, diff --git a/src/lib/aws.ts b/src/lib/aws.ts index e7b5f6d..857f5f4 100644 --- a/src/lib/aws.ts +++ b/src/lib/aws.ts @@ -138,6 +138,7 @@ export async function runECSFargateTask( }, }, tags: tags, + enableExecuteCommand: true, } const command = new RunTaskCommand(jobTaskInput) console.log('AWS: START: Prompting an ECS task to run ...') diff --git a/src/scripts/poll.ts b/src/scripts/poll.ts index a67cef5..66fd453 100644 --- a/src/scripts/poll.ts +++ b/src/scripts/poll.ts @@ -1,5 +1,3 @@ -import { checkForErroredJobs } from '../lib/check-jobs' -import { runStudies } from '../lib/run-studies' const pollStudiesInterval = parseInt(process.env.POLL_STUDIES_INTERVAL_SECONDS ?? '30') const pollForErroredJobsInterval = parseInt(process.env.POLL_ERRORED_JOBS_INTERVAL_SECONDS ?? '60') @@ -7,14 +5,13 @@ const pollForErroredJobsInterval = parseInt(process.env.POLL_ERRORED_JOBS_INTERV console.log('Polling interval for studies:', pollStudiesInterval) console.log('Polling interval for failed jobs:', pollForErroredJobsInterval) function pollStudies(): void { - console.log(`Polling management app at ${new Date()}`) - - runStudies({ ignoreAWSJobs: false }) + // console.log(`Polling management app at ${new Date()}`) + // runStudies({ ignoreAWSJobs: false }) } function pollForErroredJobs(): void { - console.log(`Polling for errored jobs at ${new Date()}`) - checkForErroredJobs() + // console.log(`Polling for errored jobs at ${new Date()}`) + // checkForErroredJobs() } // Poll for studies every 10 minutes by default (for dev) diff --git a/src/scripts/start-long-rc.ts b/src/scripts/start-long-rc.ts new file mode 100644 index 0000000..344942b --- /dev/null +++ b/src/scripts/start-long-rc.ts @@ -0,0 +1,32 @@ +import { launchStudy } from '../lib/aws-run-studies' +import { ensureValueWithError } from '../lib/utils' +import { ECSClient } from '@aws-sdk/client-ecs' + +const main = async (): Promise => { + const ecsClient = new ECSClient() + + // Get vals from env vars set in IaC + const cluster = ensureValueWithError(process.env.ECS_CLUSTER, 'Env var ECS_CLUSTER not found') + const baseTaskDefinition = ensureValueWithError( + process.env.BASE_TASK_DEFINITION_FAMILY, + 'Env var BASE_TASK_DEFINITION_FAMILY not found', + ) + const subnets = ensureValueWithError(process.env.VPC_SUBNETS, 'Env var VPC_SUBNETS not found') + const securityGroup = ensureValueWithError(process.env.SECURITY_GROUP, 'Env var SECURITY_GROUP not found') + + // Launch the study + await launchStudy( + ecsClient, + cluster, + baseTaskDefinition, + subnets.split(','), + securityGroup, + 'N/A', // no need to supply correct TOA endpoint + 'test-job-id', + // URL to container built from files in `../../rc-code/` directory: + 'harbor.safeinsights.org/openstax/code-builds/dev:2025-10-17-16-31-40', + 'Exec-able container', + ) +} + +main() From 5a93daacb907f2a02262c9043a024b670e0d9a1d Mon Sep 17 00:00:00 2001 From: KC Swanson Date: Fri, 17 Oct 2025 16:45:32 -0400 Subject: [PATCH 2/2] lint --- src/scripts/poll.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/scripts/poll.ts b/src/scripts/poll.ts index 66fd453..6e5ca02 100644 --- a/src/scripts/poll.ts +++ b/src/scripts/poll.ts @@ -1,4 +1,3 @@ - const pollStudiesInterval = parseInt(process.env.POLL_STUDIES_INTERVAL_SECONDS ?? '30') const pollForErroredJobsInterval = parseInt(process.env.POLL_ERRORED_JOBS_INTERVAL_SECONDS ?? '60')