From 2284ac237080a4b0b69d7a833b150fd7b839229f Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Fri, 28 Jun 2024 11:27:24 -0400 Subject: [PATCH 01/29] [IA-4996] Deploy Jupyter on AKS: TEST! --- .../dsde/workbench/leonardo/diskModels.scala | 4 ++ .../workbench/leonardo/kubernetesModels.scala | 6 ++ http/src/main/resources/reference.conf | 16 +++++ http/src/main/resources/swagger/api-docs.yaml | 1 + .../workbench/leonardo/app/AppInstall.scala | 6 ++ .../leonardo/app/JupyterAppInstall.scala | 58 +++++++++++++++++++ .../leonardo/config/KubernetesAppConfig.scala | 17 ++++++ .../leonardo/dao/HttpJupyterDAO.scala | 17 +++--- .../workbench/leonardo/dao/JupyterDAO.scala | 11 ++++ .../leonardo/db/PersistentDiskComponent.scala | 5 +- .../http/AppDependenciesBuilder.scala | 4 ++ .../leonardo/http/ConfigReader.scala | 1 + .../http/service/LeoAppServiceInterp.scala | 1 + .../leonardo/monitor/LeoMetricsMonitor.scala | 1 + 14 files changed, 137 insertions(+), 11 deletions(-) create mode 100644 http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala create mode 100644 http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/JupyterDAO.scala diff --git a/core/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/diskModels.scala b/core/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/diskModels.scala index 0469790efa0..b977f2c8038 100644 --- a/core/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/diskModels.scala +++ b/core/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/diskModels.scala @@ -129,6 +129,10 @@ object FormattedBy extends Enum[FormattedBy] { override def asString: String = "CROMWELL" } + final case object Jupyter extends FormattedBy { + override def asString: String = "JUPYTER" + } + final case object Allowed extends FormattedBy { override def asString: String = "ALLOWED" } diff --git a/core/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/kubernetesModels.scala b/core/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/kubernetesModels.scala index 0d7213473b8..22c3e7e30b0 100644 --- a/core/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/kubernetesModels.scala +++ b/core/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/kubernetesModels.scala @@ -364,6 +364,10 @@ object AppType { override def toString: String = "HAIL_BATCH" } + case object Jupyter extends AppType { + override def toString: String = "JUPYTER" + } + // See more context in https://docs.google.com/document/d/1RaQRMqAx7ymoygP6f7QVdBbZC-iD9oY_XLNMe_oz_cs/edit case object Allowed extends AppType { override def toString: String = "ALLOWED" @@ -384,9 +388,11 @@ object AppType { def appTypeToFormattedByType(appType: AppType): FormattedBy = appType match { case Galaxy => FormattedBy.Galaxy + case Jupyter => FormattedBy.Jupyter case Custom => FormattedBy.Custom case Allowed => FormattedBy.Allowed case Cromwell | Wds | HailBatch | WorkflowsApp | CromwellRunnerApp => FormattedBy.Cromwell + } } diff --git a/http/src/main/resources/reference.conf b/http/src/main/resources/reference.conf index 6a5243aa774..2dd42f8877c 100644 --- a/http/src/main/resources/reference.conf +++ b/http/src/main/resources/reference.conf @@ -449,6 +449,22 @@ azure { chart-versions-to-exclude-from-updates = [] } + jupyter-app-config { + chart-name = "terra-helm/jupyter" + chart-version = "0.1.0" + release-name-suffix = "jupyter-rls" + namespace-name-suffix = "jupyter-ns" + ksa-name = "jupyter-ksa" + services = [ + { + # TODO + } + ] + enabled = true + # App developers - Please keep the list of non-backward compatible versions in the list below + chart-versions-to-exclude-from-updates = [] + } + # App types which are allowed to launch with WORKSPACE_SHARED access scope. allowed-shared-apps = [ "WDS", diff --git a/http/src/main/resources/swagger/api-docs.yaml b/http/src/main/resources/swagger/api-docs.yaml index aaa6ea003fe..57b731dbc03 100644 --- a/http/src/main/resources/swagger/api-docs.yaml +++ b/http/src/main/resources/swagger/api-docs.yaml @@ -2988,6 +2988,7 @@ components: - ALLOWED - WORKFLOWS_APP - CROMWELL_RUNNER_APP + - JUPYTER AllowedChartName: type: string enum: diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/AppInstall.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/AppInstall.scala index 36faa19632b..c500068a7d0 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/AppInstall.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/AppInstall.scala @@ -12,8 +12,10 @@ import org.broadinstitute.dsde.workbench.leonardo.{ AppContext, AppType, BillingProfileId, + CloudContext, LandingZoneResources, ManagedIdentityName, + RuntimeName, WorkspaceId, WsmControlledDatabaseResource } @@ -34,6 +36,10 @@ trait AppInstall[F[_]] { /** Checks status of the app. */ def checkStatus(baseUri: Uri, authHeader: Authorization)(implicit ev: Ask[F, AppContext]): F[Boolean] + +// /** Checks status of the app. */ +// def checkStatus(cloudContext: CloudContext, runtimeName: RuntimeName)(implicit ev: Ask[F, AppContext]): F[Boolean] + } object AppInstall { diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala new file mode 100644 index 00000000000..bf7788051c4 --- /dev/null +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala @@ -0,0 +1,58 @@ +package org.broadinstitute.dsde.workbench.leonardo.app + +import cats.effect.Async +import cats.mtl.Ask +import org.broadinstitute.dsde.workbench.leonardo.{AppContext, CloudContext, RuntimeName} +import org.broadinstitute.dsde.workbench.leonardo.config.JupyterAppConfig +import org.broadinstitute.dsde.workbench.leonardo.dao.JupyterDAO +import org.broadinstitute.dsde.workbench.leonardo.util.AppCreationException +import org.broadinstitute.dsp.Values +import org.http4s.Uri +import org.http4s.headers.Authorization + +/** + * Jupyter app. + */ +class JupyterAppInstall[F[_]](config: JupyterAppConfig, JupyterDao: JupyterDAO[F])(implicit F: Async[F]) + extends AppInstall[F] { + override def databases: List[Database] = List.empty + + override def buildHelmOverrideValues( + params: BuildHelmOverrideValuesParams + )(implicit ev: Ask[F, AppContext]): F[Values] = + for { + ctx <- ev.ask + // Storage container is required for Cromwell app + storageContainer <- F.fromOption( + params.storageContainer, + AppCreationException("Storage container required for Hail Batch app", Some(ctx.traceId)) + ) + values = + List( + raw"persistence.storageAccount=${params.landingZoneResources.storageAccountName.value}", + raw"persistence.blobContainer=${storageContainer.name.value}", + raw"persistence.workspaceManager.url=${params.config.wsmConfig.uri.renderString}", + raw"persistence.workspaceManager.workspaceId=${params.workspaceId.value}", + raw"persistence.workspaceManager.containerResourceId=${storageContainer.resourceId.value.toString}", + raw"persistence.workspaceManager.storageContainerUrl=https://${params.landingZoneResources.storageAccountName.value}.blob.core.windows.net/${storageContainer.name.value}", + raw"persistence.leoAppName=${params.app.appName.value}", + + // identity configs + raw"workloadIdentity.serviceAccountName=${params.ksaName.value}", + + // relay configs + raw"relay.domain=${params.relayPath.authority.getOrElse("none")}", + raw"relay.subpath=/${params.relayPath.path.segments.last.toString}" + ) + } yield Values(values.mkString(",")) + + override def checkStatus(baseUri: Uri, authHeader: Authorization)(implicit + ev: Ask[F, AppContext] + ): F[Boolean] = + F.pure(true) // TODO (LM) + + def isProxyAvailable(cloudContext: CloudContext, runtimeName: RuntimeName)(implicit + ev: Ask[F, AppContext] + ): F[Boolean] = + JupyterDao.isProxyAvailable(cloudContext, runtimeName) +} diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/config/KubernetesAppConfig.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/config/KubernetesAppConfig.scala index 0c6c05540bc..2e8c7b96b91 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/config/KubernetesAppConfig.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/config/KubernetesAppConfig.scala @@ -47,6 +47,7 @@ object KubernetesAppConfig { case (CromwellRunnerApp, CloudProvider.Azure) => Some(ConfigReader.appConfig.azure.cromwellRunnerAppConfig) case (Wds, CloudProvider.Azure) => Some(ConfigReader.appConfig.azure.wdsAppConfig) case (HailBatch, CloudProvider.Azure) => Some(ConfigReader.appConfig.azure.hailBatchAppConfig) + case (Jupyter, CloudProvider.Azure) => Some(ConfigReader.appConfig.azure.jupyterAppConfig) case _ => None } } @@ -202,6 +203,22 @@ final case class HailBatchAppConfig(chartName: ChartName, val appType: AppType = AppType.HailBatch } +final case class JupyterAppConfig(chartName: ChartName, + chartVersion: ChartVersion, + releaseNameSuffix: ReleaseNameSuffix, + namespaceNameSuffix: NamespaceNameSuffix, + ksaName: KsaName, + services: List[ServiceConfig], + enabled: Boolean, + chartVersionsToExcludeFromUpdates: List[ChartVersion] +) extends KubernetesAppConfig { + override val kubernetesServices: List[KubernetesService] = services.map(s => KubernetesService(ServiceId(-1), s)) + override val serviceAccountName = ServiceAccountName(ksaName.value) + + val cloudProvider: CloudProvider = CloudProvider.Azure + val appType: AppType = AppType.Jupyter +} + final case class ContainerRegistryUsername(asString: String) extends AnyVal final case class ContainerRegistryPassword(asString: String) extends AnyVal final case class ContainerRegistryCredentials(username: ContainerRegistryUsername, password: ContainerRegistryPassword) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/HttpJupyterDAO.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/HttpJupyterDAO.scala index 4f558efcc46..d27e94ea73d 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/HttpJupyterDAO.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/HttpJupyterDAO.scala @@ -1,24 +1,28 @@ package org.broadinstitute.dsde.workbench.leonardo.dao import cats.effect.Async +import cats.mtl.Ask import cats.syntax.all._ import io.circe.Decoder import org.broadinstitute.dsde.workbench.leonardo.dao.ExecutionState.{Idle, OtherState} import org.broadinstitute.dsde.workbench.leonardo.dao.HostStatus.HostReady import org.broadinstitute.dsde.workbench.leonardo.dao.HttpJupyterDAO._ import org.broadinstitute.dsde.workbench.leonardo.dns.RuntimeDnsCache -import org.broadinstitute.dsde.workbench.leonardo.{CloudContext, RuntimeName} +import org.broadinstitute.dsde.workbench.leonardo.{AppContext, CloudContext, RuntimeName} import org.broadinstitute.dsde.workbench.model.google.GoogleProject +import org.broadinstitute.dsde.workbench.openTelemetry.OpenTelemetryMetrics import org.http4s.circe.CirceEntityDecoder._ import org.http4s.client.Client -import org.http4s.{Header, Headers, Method, Request} +import org.http4s.headers.Authorization +import org.http4s.{Header, Headers, Method, Request, Uri} import org.typelevel.ci.CIString import org.typelevel.log4cats.Logger //Jupyter server API doc https://github.com/jupyter/jupyter/wiki/Jupyter-Notebook-Server-API class HttpJupyterDAO[F[_]](val runtimeDnsCache: RuntimeDnsCache[F], client: Client[F], samDAO: SamDAO[F])(implicit F: Async[F], - logger: Logger[F] + logger: Logger[F], + metrics: OpenTelemetryMetrics[F] ) extends JupyterDAO[F] { private val SETDATEACCESSEDINSPECTOR_HEADER_IGNORE: Header.Raw = Header.Raw(CIString("X-SetDateAccessedInspector-Action"), "ignore") @@ -110,13 +114,6 @@ object HttpJupyterDAO { implicit val sessionDecoder: Decoder[Session] = Decoder.forProduct1("kernel")(Session) } -trait JupyterDAO[F[_]] { - def isAllKernelsIdle(cloudContext: CloudContext, runtimeName: RuntimeName): F[Boolean] - def isProxyAvailable(cloudContext: CloudContext, runtimeName: RuntimeName): F[Boolean] - def createTerminal(googleProject: GoogleProject, runtimeName: RuntimeName): F[Unit] - def terminalExists(googleProject: GoogleProject, runtimeName: RuntimeName, terminalName: TerminalName): F[Boolean] -} - sealed abstract class ExecutionState object ExecutionState { case object Idle extends ExecutionState { diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/JupyterDAO.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/JupyterDAO.scala new file mode 100644 index 00000000000..5b30aabfc02 --- /dev/null +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/JupyterDAO.scala @@ -0,0 +1,11 @@ +package org.broadinstitute.dsde.workbench.leonardo.dao + +import org.broadinstitute.dsde.workbench.leonardo.{CloudContext, RuntimeName} +import org.broadinstitute.dsde.workbench.model.google.GoogleProject + +trait JupyterDAO[F[_]] { + def isAllKernelsIdle(cloudContext: CloudContext, runtimeName: RuntimeName): F[Boolean] + def isProxyAvailable(cloudContext: CloudContext, runtimeName: RuntimeName): F[Boolean] + def createTerminal(googleProject: GoogleProject, runtimeName: RuntimeName): F[Unit] + def terminalExists(googleProject: GoogleProject, runtimeName: RuntimeName, terminalName: TerminalName): F[Boolean] +} \ No newline at end of file diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/db/PersistentDiskComponent.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/db/PersistentDiskComponent.scala index 15f7d97c151..91a2714a64c 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/db/PersistentDiskComponent.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/db/PersistentDiskComponent.scala @@ -129,6 +129,7 @@ class PersistentDiskTable(tag: Tag) extends Table[PersistentDiskRecord](tag, "PE case FormattedBy.Galaxy => (galaxyPvcId, lastUsedBy).mapN((gp, lb) => GalaxyRestore(gp, lb)) case FormattedBy.Cromwell => lastUsedBy.map(Other) + case FormattedBy.Jupyter => lastUsedBy.map(Other) // TODO (LM) case FormattedBy.Allowed => lastUsedBy.map(Other) case FormattedBy.GCE | FormattedBy.Custom => None }, @@ -274,7 +275,9 @@ object persistentDiskQuery { isAttachedToRuntime <- RuntimeConfigQueries.isDiskAttached(diskId) isAttached <- if (isAttachedToRuntime) DBIO.successful(true) else appQuery.isDiskAttached(diskId) } yield isAttached - case Some(FormattedBy.Galaxy | FormattedBy.Custom | FormattedBy.Cromwell | FormattedBy.Allowed) => + case Some( + FormattedBy.Galaxy | FormattedBy.Custom | FormattedBy.Cromwell | FormattedBy.Allowed | FormattedBy.Jupyter + ) => appQuery.isDiskAttached(diskId) case Some(FormattedBy.GCE) => RuntimeConfigQueries.isDiskAttached(diskId) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/AppDependenciesBuilder.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/AppDependenciesBuilder.scala index 4f37b5541c8..525a77a04c3 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/AppDependenciesBuilder.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/AppDependenciesBuilder.scala @@ -184,6 +184,7 @@ class AppDependenciesBuilder(baselineDependenciesBuilder: BaselineDependenciesBu baselineDependencies.cbasDAO, baselineDependencies.cromwellDAO, baselineDependencies.hailBatchDAO, + baselineDependencies.jupyterDAO, baselineDependencies.listenerDAO, baselineDependencies.samDAO, kubeAlg, @@ -219,6 +220,9 @@ class AppDependenciesBuilder(baselineDependenciesBuilder: BaselineDependenciesBu baselineDependencies.wdsDAO, baselineDependencies.azureApplicationInsightsService ) + val jupyterAppInstall = + new JupyterAppInstall[IO](ConfigReader.appConfig.azure.jupyterAppConfig, baselineDependencies.jupyterDAO) + val workflowsAppInstall = new WorkflowsAppInstall[IO]( ConfigReader.appConfig.azure.workflowsAppConfig, diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/ConfigReader.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/ConfigReader.scala index 460f5dbf4c0..54281394cb3 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/ConfigReader.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/ConfigReader.scala @@ -27,6 +27,7 @@ final case class AzureConfig( workflowsAppConfig: WorkflowsAppConfig, wdsAppConfig: WdsAppConfig, hailBatchAppConfig: HailBatchAppConfig, + jupyterAppConfig: JupyterAppConfig, allowedSharedApps: List[AppType], tdr: TdrConfig, listenerChartConfig: ListenerChartConfig, diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/LeoAppServiceInterp.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/LeoAppServiceInterp.scala index b0c560eef5b..2388eee0a91 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/LeoAppServiceInterp.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/LeoAppServiceInterp.scala @@ -1209,6 +1209,7 @@ final class LeoAppServiceInterp[F[_]: Parallel](config: AppServiceConfig, (diskResult.disk.formattedBy, diskResult.disk.appRestore) match { case (Some(FormattedBy.Galaxy), Some(GalaxyRestore(_, _))) | (Some(FormattedBy.Cromwell), Some(AppRestore.Other(_))) | + (Some(FormattedBy.Jupyter), Some(AppRestore.Other(_))) | // TODO (LM) (Some(FormattedBy.Allowed), Some(AppRestore.Other(_))) => val lastUsedBy = diskResult.disk.appRestore.get.lastUsedBy for { diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/monitor/LeoMetricsMonitor.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/monitor/LeoMetricsMonitor.scala index 62530014dd4..d15c6ef97a8 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/monitor/LeoMetricsMonitor.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/monitor/LeoMetricsMonitor.scala @@ -33,6 +33,7 @@ class LeoMetricsMonitor[F[_]](config: LeoMetricsMonitorConfig, cbasDAO: CbasDAO[F], cromwellDAO: CromwellDAO[F], hailBatchDAO: HailBatchDAO[F], + jupyterDAO: JupyterDAO[F], listenerDAO: ListenerDAO[F], samDAO: SamDAO[F], kubeAlg: KubernetesAlgebra[F], From 2e393d989afc7db70f039e2f18147cf195424fa5 Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Mon, 1 Jul 2024 04:30:15 -0400 Subject: [PATCH 02/29] more boilerplate --- Dockerfile | 2 ++ .../workbench/leonardo/kubernetesModels.scala | 2 +- http/src/main/resources/leo.conf | 4 +++ http/src/main/resources/reference.conf | 28 +++++++++---------- .../leonardo/app/JupyterAppInstall.scala | 7 +---- .../leonardo/dao/HttpJupyterDAO.scala | 17 ++++++++++- .../workbench/leonardo/dao/JupyterDAO.scala | 8 ++++-- .../http/service/LeoAppServiceInterp.scala | 2 +- .../leonardo/monitor/LeoMetricsMonitor.scala | 5 ++-- .../leonardo/util/BuildHelmChartValues.scala | 4 ++- 10 files changed, 51 insertions(+), 28 deletions(-) diff --git a/Dockerfile b/Dockerfile index 3c881659c86..a177939c518 100644 --- a/Dockerfile +++ b/Dockerfile @@ -34,6 +34,7 @@ ENV CROMWELL_CHART_VERSION 0.2.506 ENV HAIL_BATCH_CHART_VERSION 0.2.0 ENV RSTUDIO_CHART_VERSION 0.12.0 ENV SAS_CHART_VERSION 0.17.0 +ENV JUPYTER_CHART_VERSION 0.1.0 RUN mkdir /leonardo COPY ./leonardo*.jar /leonardo @@ -68,6 +69,7 @@ RUN cd /leonardo && \ helm pull terra-helm/rstudio --version $RSTUDIO_CHART_VERSION --untar && \ helm pull terra-helm/sas --version $SAS_CHART_VERSION --untar && \ helm pull oci://terradevacrpublic.azurecr.io/hail/hail-batch-terra-azure --version $HAIL_BATCH_CHART_VERSION --untar && \ + helm pull oci://terradevacrpublic.azurecr.io/jupyter-server:test --version $JUPYTER_CHART_VERSION --untar && \ cd / # Install https://github.com/apangin/jattach to get access to JDK tools diff --git a/core/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/kubernetesModels.scala b/core/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/kubernetesModels.scala index 22c3e7e30b0..4cc34523479 100644 --- a/core/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/kubernetesModels.scala +++ b/core/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/kubernetesModels.scala @@ -381,7 +381,7 @@ object AppType { def stringToObject: Map[String, AppType] = values.map(v => v.toString -> v).toMap /** - * Disk formatting for an App. Currently, only Galaxy, RStudio and Custom app types + * Disk formatting for an App. Currently, only Galaxy, RStudio, Jupyter and Custom app types * support disk management. So we default all other app types to Cromwell, * but the field is unused. */ diff --git a/http/src/main/resources/leo.conf b/http/src/main/resources/leo.conf index 9a39d4aa587..e9447ed1776 100644 --- a/http/src/main/resources/leo.conf +++ b/http/src/main/resources/leo.conf @@ -183,6 +183,10 @@ azure { enabled = ${?HAIL_BATCH_APP_ENABLED} } + jupyter-app-config { + enabled = ${?JUPYTER_APP_ENABLED} + } + coa-app-config { instrumentation-enabled = ${?COA_INSTRUMENTATION_ENABLED} database-enabled = ${?COA_DATABASE_ENABLED} diff --git a/http/src/main/resources/reference.conf b/http/src/main/resources/reference.conf index 2dd42f8877c..96ab93c32ec 100644 --- a/http/src/main/resources/reference.conf +++ b/http/src/main/resources/reference.conf @@ -449,21 +449,21 @@ azure { chart-versions-to-exclude-from-updates = [] } - jupyter-app-config { - chart-name = "terra-helm/jupyter" - chart-version = "0.1.0" - release-name-suffix = "jupyter-rls" - namespace-name-suffix = "jupyter-ns" - ksa-name = "jupyter-ksa" - services = [ - { - # TODO - } - ] - enabled = true - # App developers - Please keep the list of non-backward compatible versions in the list below - chart-versions-to-exclude-from-updates = [] + jupyter-app-config { + chart-name = "terra-helm/jupyter" + chart-version = "0.1.0" + release-name-suffix = "jupyter-rls" + namespace-name-suffix = "jupyter-ns" + ksa-name = "jupyter-ksa" + services = [ + { + # TODO } + ] + enabled = true + # App developers - Please keep the list of non-backward compatible versions in the list below + chart-versions-to-exclude-from-updates = [] + } # App types which are allowed to launch with WORKSPACE_SHARED access scope. allowed-shared-apps = [ diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala index bf7788051c4..98b4581c378 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala @@ -49,10 +49,5 @@ class JupyterAppInstall[F[_]](config: JupyterAppConfig, JupyterDao: JupyterDAO[F override def checkStatus(baseUri: Uri, authHeader: Authorization)(implicit ev: Ask[F, AppContext] ): F[Boolean] = - F.pure(true) // TODO (LM) - - def isProxyAvailable(cloudContext: CloudContext, runtimeName: RuntimeName)(implicit - ev: Ask[F, AppContext] - ): F[Boolean] = - JupyterDao.isProxyAvailable(cloudContext, runtimeName) + JupyterDao.getStatus(baseUri, authHeader) } diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/HttpJupyterDAO.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/HttpJupyterDAO.scala index d27e94ea73d..d71acbdeec0 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/HttpJupyterDAO.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/HttpJupyterDAO.scala @@ -13,6 +13,7 @@ import org.broadinstitute.dsde.workbench.model.google.GoogleProject import org.broadinstitute.dsde.workbench.openTelemetry.OpenTelemetryMetrics import org.http4s.circe.CirceEntityDecoder._ import org.http4s.client.Client +import org.http4s.client.dsl.Http4sClientDsl import org.http4s.headers.Authorization import org.http4s.{Header, Headers, Method, Request, Uri} import org.typelevel.ci.CIString @@ -23,10 +24,24 @@ class HttpJupyterDAO[F[_]](val runtimeDnsCache: RuntimeDnsCache[F], client: Clie F: Async[F], logger: Logger[F], metrics: OpenTelemetryMetrics[F] -) extends JupyterDAO[F] { +) extends JupyterDAO[F] + with Http4sClientDsl[F] { private val SETDATEACCESSEDINSPECTOR_HEADER_IGNORE: Header.Raw = Header.Raw(CIString("X-SetDateAccessedInspector-Action"), "ignore") + def getStatus(baseUri: Uri, authHeader: Authorization)(implicit + ev: Ask[F, AppContext] + ): F[Boolean] = for { + _ <- metrics.incrementCounter("jupyter/status") + res <- client.status( + Request[F]( + method = Method.GET, + uri = baseUri / "api" / "status", // TODO (LM) this may need to change + headers = Headers(authHeader) + ) + ) + } yield res.isSuccess + def isProxyAvailable(cloudContext: CloudContext, runtimeName: RuntimeName): F[Boolean] = for { hostStatus <- Proxy.getRuntimeTargetHost[F](runtimeDnsCache, cloudContext, runtimeName) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/JupyterDAO.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/JupyterDAO.scala index 5b30aabfc02..9a7ae591e79 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/JupyterDAO.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/JupyterDAO.scala @@ -1,11 +1,15 @@ package org.broadinstitute.dsde.workbench.leonardo.dao -import org.broadinstitute.dsde.workbench.leonardo.{CloudContext, RuntimeName} +import cats.mtl.Ask +import org.broadinstitute.dsde.workbench.leonardo.{AppContext, CloudContext, RuntimeName} import org.broadinstitute.dsde.workbench.model.google.GoogleProject +import org.http4s.Uri +import org.http4s.headers.Authorization trait JupyterDAO[F[_]] { def isAllKernelsIdle(cloudContext: CloudContext, runtimeName: RuntimeName): F[Boolean] def isProxyAvailable(cloudContext: CloudContext, runtimeName: RuntimeName): F[Boolean] def createTerminal(googleProject: GoogleProject, runtimeName: RuntimeName): F[Unit] def terminalExists(googleProject: GoogleProject, runtimeName: RuntimeName, terminalName: TerminalName): F[Boolean] -} \ No newline at end of file + def getStatus(baseUri: Uri, authHeader: Authorization)(implicit ev: Ask[F, AppContext]): F[Boolean] +} diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/LeoAppServiceInterp.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/LeoAppServiceInterp.scala index 2388eee0a91..f232edbf688 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/LeoAppServiceInterp.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/LeoAppServiceInterp.scala @@ -91,7 +91,7 @@ final class LeoAppServiceInterp[F[_]: Parallel](config: AppServiceConfig, enableIntraNodeVisibility = req.labels.get(AOU_UI_LABEL).exists(x => x == "true") _ <- req.appType match { case AppType.Galaxy | AppType.HailBatch | AppType.Wds | AppType.Cromwell | AppType.WorkflowsApp | - AppType.CromwellRunnerApp => + AppType.CromwellRunnerApp | AppType.Jupyter => F.unit case AppType.Allowed => req.allowedChartName match { diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/monitor/LeoMetricsMonitor.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/monitor/LeoMetricsMonitor.scala index d15c6ef97a8..3b1c7a3a615 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/monitor/LeoMetricsMonitor.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/monitor/LeoMetricsMonitor.scala @@ -180,8 +180,9 @@ class LeoMetricsMonitor[F[_]](config: LeoMetricsMonitorConfig, case ServiceName("cbas") => cbasDAO.getStatus(relayPath, authHeader).handleError(_ => false) case ServiceName("cromwell") | ServiceName("cromwell-reader") | ServiceName("cromwell-runner") => cromwellDAO.getStatus(relayPath, authHeader).handleError(_ => false) - case ServiceName("wds") => wdsDAO.getStatus(relayPath, authHeader).handleError(_ => false) - case ServiceName("batch") => hailBatchDAO.getStatus(relayPath, authHeader).handleError(_ => false) + case ServiceName("wds") => wdsDAO.getStatus(relayPath, authHeader).handleError(_ => false) + case ServiceName("batch") => hailBatchDAO.getStatus(relayPath, authHeader).handleError(_ => false) + case ServiceName("jupyter") => jupyterDAO.getStatus(relayPath, authHeader).handleError(_ => false) case s if s == ConfigReader.appConfig.azure.listenerChartConfig.service.config.name => listenerDAO.getStatus(relayPath).handleError(_ => false) case s => diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/BuildHelmChartValues.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/BuildHelmChartValues.scala index 0d31fdf1580..d85f5d908ce 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/BuildHelmChartValues.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/BuildHelmChartValues.scala @@ -259,7 +259,9 @@ private[leonardo] object BuildHelmChartValues { case AppType.Wds => s"http://wds-${release.asString}-wds-svc:8080" case AppType.HailBatch => "http://batch:8080" case AppType.WorkflowsApp => s"http://wfa-${release.asString}-reverse-proxy-service:8000/" - case _ => "unknown" + case AppType.Jupyter => + s"http://jupyter-${release.asString}:8000/" // TODO (LM) may need to switch order http://jupyter:8000%{REQUEST_URI} + case _ => "unknown" } // Hail batch serves requests on /{appName}/batch and uses relative redirects, From 8ee56bbcdec97e056ec7176d3cd511e38775f1ad Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Tue, 2 Jul 2024 18:55:18 -0400 Subject: [PATCH 03/29] compiling --- .../workbench/leonardo/app/AppInstall.scala | 3 +- .../leonardo/app/JupyterAppInstall.scala | 40 ++++--- .../http/service/RuntimeServiceInterp.scala | 6 +- .../leonardo/util/AKSInterpreter.scala | 105 +++++++++++++++++- .../leonardo/util/GKEInterpreter.scala | 2 +- .../leonardo/util/GceInterpreter.scala | 2 +- .../leonardo/app/BaseAppInstallSpec.scala | 2 + .../leonardo/app/CromwellAppInstallSpec.scala | 1 + .../leonardo/dao/MockJupyterDAO.scala | 8 +- .../leonardo/http/ConfigReaderSpec.scala | 12 +- .../monitor/LeoMetricsMonitorSpec.scala | 2 + 11 files changed, 153 insertions(+), 30 deletions(-) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/AppInstall.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/AppInstall.scala index c500068a7d0..a6a80182ecf 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/AppInstall.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/AppInstall.scala @@ -12,10 +12,8 @@ import org.broadinstitute.dsde.workbench.leonardo.{ AppContext, AppType, BillingProfileId, - CloudContext, LandingZoneResources, ManagedIdentityName, - RuntimeName, WorkspaceId, WsmControlledDatabaseResource } @@ -81,6 +79,7 @@ object Database { final case class BuildHelmOverrideValuesParams(app: App, workspaceId: WorkspaceId, + workspaceName: String, cloudContext: AzureCloudContext, billingProfileId: BillingProfileId, landingZoneResources: LandingZoneResources, diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala index 98b4581c378..caff8f8fbc9 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala @@ -1,8 +1,8 @@ package org.broadinstitute.dsde.workbench.leonardo.app - import cats.effect.Async import cats.mtl.Ask -import org.broadinstitute.dsde.workbench.leonardo.{AppContext, CloudContext, RuntimeName} +import cats.syntax.all._ +import org.broadinstitute.dsde.workbench.leonardo.AppContext import org.broadinstitute.dsde.workbench.leonardo.config.JupyterAppConfig import org.broadinstitute.dsde.workbench.leonardo.dao.JupyterDAO import org.broadinstitute.dsde.workbench.leonardo.util.AppCreationException @@ -13,7 +13,7 @@ import org.http4s.headers.Authorization /** * Jupyter app. */ -class JupyterAppInstall[F[_]](config: JupyterAppConfig, JupyterDao: JupyterDAO[F])(implicit F: Async[F]) +class JupyterAppInstall[F[_]](config: JupyterAppConfig, jupyterDao: JupyterDAO[F])(implicit F: Async[F]) extends AppInstall[F] { override def databases: List[Database] = List.empty @@ -25,29 +25,35 @@ class JupyterAppInstall[F[_]](config: JupyterAppConfig, JupyterDao: JupyterDAO[F // Storage container is required for Cromwell app storageContainer <- F.fromOption( params.storageContainer, - AppCreationException("Storage container required for Hail Batch app", Some(ctx.traceId)) + AppCreationException("Storage container required for Jupyter app", Some(ctx.traceId)) + ) + + disk <- F.fromOption( + params.app.appResources.disk, + AppCreationException("Disk required for Jupyter app", Some(ctx.traceId)) ) + values = List( - raw"persistence.storageAccount=${params.landingZoneResources.storageAccountName.value}", - raw"persistence.blobContainer=${storageContainer.name.value}", - raw"persistence.workspaceManager.url=${params.config.wsmConfig.uri.renderString}", - raw"persistence.workspaceManager.workspaceId=${params.workspaceId.value}", - raw"persistence.workspaceManager.containerResourceId=${storageContainer.resourceId.value.toString}", - raw"persistence.workspaceManager.storageContainerUrl=https://${params.landingZoneResources.storageAccountName.value}.blob.core.windows.net/${storageContainer.name.value}", - raw"persistence.leoAppName=${params.app.appName.value}", + // workspace configs + raw"workspace.id=${params.workspaceId.value.toString}", + raw"workspace.name=${params.workspaceName}", + raw"workspace.storageContainer.url=https://${params.landingZoneResources.storageAccountName.value}.blob.core.windows.net/${storageContainer.name.value}", + raw"workspace.storageContainer.resourceId=${storageContainer.resourceId.value.toString}", + raw"workspace.cloudProvider=Azure", - // identity configs - raw"workloadIdentity.serviceAccountName=${params.ksaName.value}", + // persistent disk configs + raw"persistence.diskName=${disk.name}", + raw"persistence.diskSize=${disk.size}", - // relay configs - raw"relay.domain=${params.relayPath.authority.getOrElse("none")}", - raw"relay.subpath=/${params.relayPath.path.segments.last.toString}" + // misc + raw"serviceAccount.name=${params.ksaName.value}", + raw"relay.connectionName=${params.app.appName.value}" ) } yield Values(values.mkString(",")) override def checkStatus(baseUri: Uri, authHeader: Authorization)(implicit ev: Ask[F, AppContext] ): F[Boolean] = - JupyterDao.getStatus(baseUri, authHeader) + jupyterDao.getStatus(baseUri, authHeader) } diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeServiceInterp.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeServiceInterp.scala index 998011f5fce..f3a800d6529 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeServiceInterp.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeServiceInterp.scala @@ -1196,7 +1196,8 @@ object RuntimeServiceInterp { case Some(formattedBy) => if (willBeUsedBy == formattedBy) { formattedBy match { - case FormattedBy.Galaxy | FormattedBy.Cromwell | FormattedBy.Custom | FormattedBy.Allowed => + case FormattedBy.Galaxy | FormattedBy.Cromwell | FormattedBy.Custom | FormattedBy.Allowed | + FormattedBy.Jupyter => appQuery.isDiskAttached(pd.id).transaction case FormattedBy.GCE => RuntimeConfigQueries.isDiskAttached(pd.id).transaction } @@ -1299,7 +1300,8 @@ object RuntimeServiceInterp { case Some(formattedBy) => if (willBeUsedBy == formattedBy) { formattedBy match { - case FormattedBy.Galaxy | FormattedBy.Cromwell | FormattedBy.Custom | FormattedBy.Allowed => + case FormattedBy.Galaxy | FormattedBy.Cromwell | FormattedBy.Custom | FormattedBy.Allowed | + FormattedBy.Jupyter => appQuery.isDiskAttached(pd.id).transaction case FormattedBy.GCE => RuntimeConfigQueries.isDiskAttached(pd.id).transaction } diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/AKSInterpreter.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/AKSInterpreter.scala index da81725c578..e0cd647718c 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/AKSInterpreter.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/AKSInterpreter.scala @@ -57,14 +57,9 @@ class AKSInterpreter[F[_]](config: AKSInterpreterConfig, ) extends AKSAlgebra[F] { implicit private def booleanDoneCheckable: DoneCheckable[Boolean] = identity[Boolean] - implicit private def listDoneCheckable[A: DoneCheckable]: DoneCheckable[List[A]] = as => as.forall(_.isDone) - private[util] def isPodDone(podStatus: PodStatus): Boolean = podStatus == PodStatus.Failed || podStatus == PodStatus.Succeeded - implicit private def podDoneCheckable: DoneCheckable[List[PodStatus]] = - (ps: List[PodStatus]) => ps.forall(isPodDone) - implicit private def createDatabaseDoneCheckable: DoneCheckable[CreatedControlledAzureDatabaseResult] = _.getJobReport.getStatus != JobReport.StatusEnum.RUNNING @@ -75,6 +70,11 @@ class AKSInterpreter[F[_]](config: AKSInterpreterConfig, implicit private def deleteWsmResourceDoneCheckable: DoneCheckable[DeleteControlledAzureResourceResult] = _.getJobReport.getStatus != JobReport.StatusEnum.RUNNING + implicit private def wsmCreateAzureResourceResultDoneCheckable: DoneCheckable[CreateControlledAzureResourceResult] = + (v: CreateControlledAzureResourceResult) => + v.getJobReport.getStatus.equals(JobReport.StatusEnum.SUCCEEDED) || v.getJobReport.getStatus + .equals(JobReport.StatusEnum.FAILED) + private def getListenerReleaseName(appReleaseName: Release): Release = Release(s"${appReleaseName.asString}-listener-rls") @@ -118,6 +118,11 @@ class AKSInterpreter[F[_]](config: AKSInterpreterConfig, } } + wsmWorkspaceApi <- buildWsmWorkspaceApiClient + + // Resolve the workspace in WSM + workspace <- F.blocking(wsmWorkspaceApi.getWorkspace(params.workspaceId.value, IamRole.READER)) + wsmResourceApi <- buildWsmResourceApiClient // Create or fetch WSM managed identity (if shared app) @@ -148,6 +153,14 @@ class AKSInterpreter[F[_]](config: AKSInterpreterConfig, ) } + // Create or fetch WSM disk (only for Jupyter apps) + _ <- childSpan("createWsmDisk").use { implicit ev => + createOrFetchWsmDiskResource( + app, + params.workspaceId + ) + } + // Create or fetch WSM databases wsmDatabases <- childSpan("createWsmDatabaseResources").use { implicit ev => createOrFetchWsmDatabaseResources( @@ -232,6 +245,7 @@ class AKSInterpreter[F[_]](config: AKSInterpreterConfig, helmOverrideValueParams = BuildHelmOverrideValuesParams( app, params.workspaceId, + workspace.getDisplayName, params.cloudContext, params.billingProfileId, landingZoneResources, @@ -468,6 +482,7 @@ class AKSInterpreter[F[_]](config: AKSInterpreterConfig, helmOverrideValueParams = BuildHelmOverrideValuesParams( app, workspaceId, + workspaceDesc.displayName, params.cloudContext, billingProfileId, landingZoneResources, @@ -885,6 +900,86 @@ class AKSInterpreter[F[_]](config: AKSInterpreterConfig, } } yield wsmControlledDBResources + private[util] def createOrFetchWsmDiskResource(app: App, workspaceId: WorkspaceId)(implicit + ev: Ask[F, AppContext] + ): F[Unit] = + for { + ctx <- ev.ask + + _ <- + app.appResources.disk match { + case Some(disk) => + for { + + _ <- logger.info(ctx.loggingCtx)( + s"Creating WSM disk for app ${app.appName.value} in cloud workspace ${workspaceId.value}" + ) + + wsmResourceApi <- buildWsmControlledResourceApiClient + + common = getWsmCommonFields(disk.name.value, + s"Disk for Leo app ${app.appName.value}", + app, + CloningInstructionsEnum.NOTHING + ) + + createDiskJobId = UUID.randomUUID().toString + jobControl = new JobControl() + .id(createDiskJobId) + + azureDisk = new AzureDiskCreationParameters() + .name(disk.name.value) + .size(disk.size.gb) + + request = new CreateControlledAzureDiskRequestV2Body() + .common(common) + .azureDisk(azureDisk) + .jobControl(jobControl) + + _ <- logger.info(ctx.loggingCtx)(s"WSM create disk request: ${request}") + + // Execute WSM call + createDiskResponse <- F.blocking( + wsmResourceApi.createAzureDiskV2(request, workspaceId.value) + ) + + op = F.blocking(wsmResourceApi.getCreateAzureDiskResult(workspaceId.value, createDiskJobId)) + result <- streamFUntilDone( + op, + config.appMonitorConfig.createApp.maxAttempts, + config.appMonitorConfig.createApp.interval + ).interruptAfter(config.appMonitorConfig.createApp.interruptAfter).compile.lastOrError + + _ <- logger.info(ctx.loggingCtx)(s"WSM create database job result: ${result}") + + _ <- F.raiseWhen(result.getJobReport.getStatus != JobReport.StatusEnum.SUCCEEDED)( + AppCreationException( + s"WSM database creation failed for app ${app.appName.value}. WSM response: ${result}", + Some(ctx.traceId) + ) + ) + + _ <- logger.info(ctx.loggingCtx)(s"WSM create disk response: ${createDiskResponse}") + + // Save record in APP_CONTROLLED_RESOURCE table + _ <- appControlledResourceQuery + .insert( + app.id.id, + WsmControlledResourceId(common.getResourceId), + WsmResourceType.AzureDisk, + AppControlledResourceStatus.Created + ) + .transaction + + // Update disk status + _ <- persistentDiskQuery.updateStatus(disk.id, DiskStatus.Ready, ctx.now).transaction + + } yield result + + case None => F.pure(None) + } + } yield () + private[util] def createMissingAppControlledResources(app: App, appInstall: AppInstall[F], workspaceId: WorkspaceId, diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/GKEInterpreter.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/GKEInterpreter.scala index 8b192c426bb..51143aa71d2 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/GKEInterpreter.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/GKEInterpreter.scala @@ -1213,7 +1213,7 @@ class GKEInterpreter[F[_]]( config.monitorConfig.startApp.interval ).interruptAfter(config.monitorConfig.startApp.interruptAfter).compile.lastOrError } yield last.isDone - case AppType.Wds | AppType.HailBatch | AppType.WorkflowsApp | AppType.CromwellRunnerApp => + case AppType.Wds | AppType.HailBatch | AppType.WorkflowsApp | AppType.CromwellRunnerApp | AppType.Jupyter => F.raiseError(AppCreationException(s"App type ${dbApp.app.appType} not supported on GCP")) } diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/GceInterpreter.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/GceInterpreter.scala index 7ec68a89a34..b32142fbf37 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/GceInterpreter.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/GceInterpreter.scala @@ -156,7 +156,7 @@ class GceInterpreter[F[_]]( isFormatted <- persistentDisk.formattedBy match { case Some(FormattedBy.Galaxy) | Some(FormattedBy.Custom) | Some(FormattedBy.Cromwell) | Some( FormattedBy.Allowed - ) => + ) | Some(FormattedBy.Jupyter) => F.raiseError[Boolean]( new RuntimeException( s"Trying to use an app formatted disk for creating GCE runtime. This should never happen. Disk Id: ${x.persistentDiskId}." diff --git a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/app/BaseAppInstallSpec.scala b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/app/BaseAppInstallSpec.scala index 3eb445db0d4..e19e27b835a 100644 --- a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/app/BaseAppInstallSpec.scala +++ b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/app/BaseAppInstallSpec.scala @@ -73,6 +73,7 @@ class BaseAppInstallSpec extends AnyFlatSpecLike with LeonardoTestSuite with Moc ) val workspaceId = WorkspaceId(UUID.randomUUID) + val workspaceName = "workspaceName" val workspaceCreatedDate = java.time.OffsetDateTime.parse("1970-01-01T12:15:30-07:00") val aksInterpConfig = AKSInterpreterConfig( @@ -88,6 +89,7 @@ class BaseAppInstallSpec extends AnyFlatSpecLike with LeonardoTestSuite with Moc BuildHelmOverrideValuesParams( app, workspaceId, + workspaceName, cloudContext, billingProfileId, lzResources, diff --git a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/app/CromwellAppInstallSpec.scala b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/app/CromwellAppInstallSpec.scala index 867d708cd9c..678753ab125 100644 --- a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/app/CromwellAppInstallSpec.scala +++ b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/app/CromwellAppInstallSpec.scala @@ -82,6 +82,7 @@ class CromwellAppInstallSpec extends BaseAppInstallSpec { val params = BuildHelmOverrideValuesParams( app, workspaceId, + workspaceName, cloudContext, billingProfileId, lzResources.copy(postgresServer = Some(PostgresServer("postgres", false))), diff --git a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/dao/MockJupyterDAO.scala b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/dao/MockJupyterDAO.scala index b6487febe52..3d34a8126cb 100644 --- a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/dao/MockJupyterDAO.scala +++ b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/dao/MockJupyterDAO.scala @@ -1,8 +1,11 @@ package org.broadinstitute.dsde.workbench.leonardo.dao import cats.effect.IO -import org.broadinstitute.dsde.workbench.leonardo.{CloudContext, RuntimeName} +import cats.mtl.Ask +import org.broadinstitute.dsde.workbench.leonardo.{AppContext, CloudContext, RuntimeName} import org.broadinstitute.dsde.workbench.model.google.GoogleProject +import org.http4s.Uri +import org.http4s.headers.Authorization class MockJupyterDAO(isUp: Boolean = true) extends JupyterDAO[IO] { override def isProxyAvailable(cloudContext: CloudContext, clusterName: RuntimeName): IO[Boolean] = @@ -17,6 +20,9 @@ class MockJupyterDAO(isUp: Boolean = true) extends JupyterDAO[IO] { runtimeName: RuntimeName, terminalName: TerminalName ): IO[Boolean] = IO.pure(true) + + override def getStatus(baseUri: Uri, authHeader: Authorization)(implicit ev: Ask[IO, AppContext]): IO[Boolean] = + IO.pure(isUp) } object MockJupyterDAO extends MockJupyterDAO(isUp = true) diff --git a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/http/ConfigReaderSpec.scala b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/http/ConfigReaderSpec.scala index 295335c7b3f..274c624f9bb 100644 --- a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/http/ConfigReaderSpec.scala +++ b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/http/ConfigReaderSpec.scala @@ -231,7 +231,17 @@ class ConfigReaderSpec extends AnyFlatSpec with Matchers { List( ServiceConfig(ServiceName("batch"), KubernetesServiceKindName("ClusterIP")) ), - false, + enabled = false, + chartVersionsToExcludeFromUpdates = List() + ), + JupyterAppConfig( + ChartName("jupyter"), + ChartVersion("0.1.0"), + ReleaseNameSuffix("jupyter-rls"), + NamespaceNameSuffix("jupyter-ns"), + KsaName("jupyter-ksa"), + List(), // TOD0 (LM) + enabled = false, chartVersionsToExcludeFromUpdates = List() ), List(AppType.Wds, AppType.WorkflowsApp), diff --git a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/monitor/LeoMetricsMonitorSpec.scala b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/monitor/LeoMetricsMonitorSpec.scala index 21ca1feb84a..2b77e81ee60 100644 --- a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/monitor/LeoMetricsMonitorSpec.scala +++ b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/monitor/LeoMetricsMonitorSpec.scala @@ -97,6 +97,7 @@ class LeoMetricsMonitorSpec extends AnyFlatSpec with LeonardoTestSuite with Test cbasDAO, cromwellDAO, hailBatchDAO, + jupyterDAO, relayListenerDAO, samDAO, kube, @@ -371,6 +372,7 @@ class LeoMetricsMonitorSpec extends AnyFlatSpec with LeonardoTestSuite with Test cbasDAO, cromwellDAO, hailBatchDAO, + jupyterDAO, relayListenerDAO, samDAO, kube, From fc28b25bb376d7d198079aa2c2468732adb7b9b0 Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Wed, 3 Jul 2024 02:36:33 -0400 Subject: [PATCH 04/29] config issue --- http/src/main/resources/reference.conf | 5 +++-- .../dsde/workbench/leonardo/http/ConfigReaderSpec.scala | 8 +++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/http/src/main/resources/reference.conf b/http/src/main/resources/reference.conf index 96ab93c32ec..1be3a8228c1 100644 --- a/http/src/main/resources/reference.conf +++ b/http/src/main/resources/reference.conf @@ -457,8 +457,9 @@ azure { ksa-name = "jupyter-ksa" services = [ { - # TODO - } + name = "jupyter" + kind = "ClusterIP" + } ] enabled = true # App developers - Please keep the list of non-backward compatible versions in the list below diff --git a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/http/ConfigReaderSpec.scala b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/http/ConfigReaderSpec.scala index 274c624f9bb..ba776345525 100644 --- a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/http/ConfigReaderSpec.scala +++ b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/http/ConfigReaderSpec.scala @@ -235,13 +235,15 @@ class ConfigReaderSpec extends AnyFlatSpec with Matchers { chartVersionsToExcludeFromUpdates = List() ), JupyterAppConfig( - ChartName("jupyter"), + ChartName("terra-helm/jupyter"), ChartVersion("0.1.0"), ReleaseNameSuffix("jupyter-rls"), NamespaceNameSuffix("jupyter-ns"), KsaName("jupyter-ksa"), - List(), // TOD0 (LM) - enabled = false, + List( + ServiceConfig(ServiceName("jupyter"), KubernetesServiceKindName("ClusterIP")) + ), + enabled = true, chartVersionsToExcludeFromUpdates = List() ), List(AppType.Wds, AppType.WorkflowsApp), From f210f7a45c5fc7625990afc3e997c5fe4b05280d Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Wed, 3 Jul 2024 09:25:00 -0400 Subject: [PATCH 05/29] chart ver --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index a177939c518..3edb44f4454 100644 --- a/Dockerfile +++ b/Dockerfile @@ -69,7 +69,7 @@ RUN cd /leonardo && \ helm pull terra-helm/rstudio --version $RSTUDIO_CHART_VERSION --untar && \ helm pull terra-helm/sas --version $SAS_CHART_VERSION --untar && \ helm pull oci://terradevacrpublic.azurecr.io/hail/hail-batch-terra-azure --version $HAIL_BATCH_CHART_VERSION --untar && \ - helm pull oci://terradevacrpublic.azurecr.io/jupyter-server:test --version $JUPYTER_CHART_VERSION --untar && \ + helm pull terra-helm/jupyter --version $JUPYTER_CHART_VERSION --untar && \ cd / # Install https://github.com/apangin/jattach to get access to JDK tools From 2a7eeaf1e1afe527c88dfcf5a8ebf750ac00016c Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Wed, 3 Jul 2024 10:02:10 -0400 Subject: [PATCH 06/29] todos --- .../dsde/workbench/leonardo/db/PersistentDiskComponent.scala | 2 +- .../workbench/leonardo/http/service/LeoAppServiceInterp.scala | 2 +- .../dsde/workbench/leonardo/util/BuildHelmChartValues.scala | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/db/PersistentDiskComponent.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/db/PersistentDiskComponent.scala index 91a2714a64c..6d8ec0eada0 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/db/PersistentDiskComponent.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/db/PersistentDiskComponent.scala @@ -129,7 +129,7 @@ class PersistentDiskTable(tag: Tag) extends Table[PersistentDiskRecord](tag, "PE case FormattedBy.Galaxy => (galaxyPvcId, lastUsedBy).mapN((gp, lb) => GalaxyRestore(gp, lb)) case FormattedBy.Cromwell => lastUsedBy.map(Other) - case FormattedBy.Jupyter => lastUsedBy.map(Other) // TODO (LM) + case FormattedBy.Jupyter => lastUsedBy.map(Other) case FormattedBy.Allowed => lastUsedBy.map(Other) case FormattedBy.GCE | FormattedBy.Custom => None }, diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/LeoAppServiceInterp.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/LeoAppServiceInterp.scala index f232edbf688..35ff982cb34 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/LeoAppServiceInterp.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/LeoAppServiceInterp.scala @@ -1209,7 +1209,7 @@ final class LeoAppServiceInterp[F[_]: Parallel](config: AppServiceConfig, (diskResult.disk.formattedBy, diskResult.disk.appRestore) match { case (Some(FormattedBy.Galaxy), Some(GalaxyRestore(_, _))) | (Some(FormattedBy.Cromwell), Some(AppRestore.Other(_))) | - (Some(FormattedBy.Jupyter), Some(AppRestore.Other(_))) | // TODO (LM) + (Some(FormattedBy.Jupyter), Some(AppRestore.Other(_))) | (Some(FormattedBy.Allowed), Some(AppRestore.Other(_))) => val lastUsedBy = diskResult.disk.appRestore.get.lastUsedBy for { diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/BuildHelmChartValues.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/BuildHelmChartValues.scala index d85f5d908ce..87132fa0eb5 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/BuildHelmChartValues.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/BuildHelmChartValues.scala @@ -260,7 +260,7 @@ private[leonardo] object BuildHelmChartValues { case AppType.HailBatch => "http://batch:8080" case AppType.WorkflowsApp => s"http://wfa-${release.asString}-reverse-proxy-service:8000/" case AppType.Jupyter => - s"http://jupyter-${release.asString}:8000/" // TODO (LM) may need to switch order http://jupyter:8000%{REQUEST_URI} + s"http://jupyter-${release.asString}-reverse-proxy-service:8000/" // TODO (LM) may need to alter order http://jupyter:8000%{REQUEST_URI} case _ => "unknown" } From 7c0617200c619599509f4ebaa64439a62133820a Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Wed, 3 Jul 2024 11:09:34 -0400 Subject: [PATCH 07/29] use local ver of helm chart --- Dockerfile | 7 +++++-- jupyter-0.1.0.tgz | Bin 0 -> 1891 bytes 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 jupyter-0.1.0.tgz diff --git a/Dockerfile b/Dockerfile index 3edb44f4454..32ec0e715f6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -57,8 +57,11 @@ RUN helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx && \ # .Files helm helper can't access files outside a chart. Hence in order to populate cert file properly, we're # pulling `terra-app-setup` locally and add cert files to the chart. As a result we need to pull all GKE -# charts locally as well so they can acess the local cert files during the helm install step, see https://helm.sh/docs/chart_template_guide/accessing_files/ +# charts locally as well so they can access the local cert files during the helm install step, see https://helm.sh/docs/chart_template_guide/accessing_files/ # Helm does not seem to support the direct installation of a chart located in OCI so let's pull it to a local directory for now. +COPY ./jupyter-0.1.0.tgz /leonardo +RUN tar -xzf /leonardo/jupyter-0.1.0.tgz -C /leonardo + RUN cd /leonardo && \ helm repo update && \ helm pull terra-app-setup-charts/terra-app-setup --version $TERRA_APP_SETUP_VERSION --untar && \ @@ -69,7 +72,7 @@ RUN cd /leonardo && \ helm pull terra-helm/rstudio --version $RSTUDIO_CHART_VERSION --untar && \ helm pull terra-helm/sas --version $SAS_CHART_VERSION --untar && \ helm pull oci://terradevacrpublic.azurecr.io/hail/hail-batch-terra-azure --version $HAIL_BATCH_CHART_VERSION --untar && \ - helm pull terra-helm/jupyter --version $JUPYTER_CHART_VERSION --untar && \ +# helm pull terra-helm/jupyter --version $JUPYTER_CHART_VERSION --untar && \ cd / # Install https://github.com/apangin/jattach to get access to JDK tools diff --git a/jupyter-0.1.0.tgz b/jupyter-0.1.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..5b7214c4f3a79341ec69d7555432e618dfd0addc GIT binary patch literal 1891 zcmV-p2b}mHiwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0PGrFZ{xTz&-xVu-5$_hYgu+2ClJtwAPElXZL&s^+kH3`0WFPV zHWaBPDc^dt`R@fqN|t10WB0PzYvFmZEDq<3oKO4TdA8Ij`zLcEb+9BU+k0^c!!R6= zM#X0shV9RAa5&l)co+`$AbfdI)*)A#$i46n^J**iKLRA9?@=l$ zcm#`~m!OIz&2;hom;=c&Mq^^WLxPIlaZEr9kU58c+N;CJ6ak)QjEY|DNipm zjOrA;Mad})20`e3Z{2sWw^#cAg0LLbw+R5x`2S!y3|s!cKiCg<{{I^A15Bh?&;%2h zE=lBxsJXfnkSKwWudp=9Agu6FQ3Bw0glZf z!Q>RO8ru)o7hYw4YeaJdr&MCBgt553h2$(e@0wh_kpA$V^~3WND>fl|^0;R|S)^BBha#Uo9x^Vy7k z0>9^jqlG*%k6t0!iA16iNX226Gq!|}Ibn20F)6Z@;ShKq(9$mOwc%joS1`qx8!G2xmelKp**?1iLIHc=)5W9j{dRv zVXkDXEMSQQSJpgsZz*Tv<(9%_l5#x*|3}sPQTZ)emg(kKtNXEW;c6#oJi|3E<`j$5 zbXUV-F)~H=#EBLdtK)2|QMa&tcFh=k0f`wSF@pa$AN*T?d)E9)R+gqodqNx(A&hX)( zW6Kx#mDmeZRYSEk>~*rYby?dw)}e!Li78i_ zm^!N=Z{2O2u-_{Fujl^+GbWZP@)sKiJ(K@O;r_Ul|Ht9raF_pI1M2f1l4YvD7YAmPZ*(TR6{TwIicz0Cgih4>~_Xw1KlCxY8p{O zIh8O0)tS~I1;tX$s1^DoXRNf+`Rr2Yi9}^?{tEBO11KaU8JSW>HLcsx0!fngs~%jQ z-P|6ZUYuXnR*1Y)5&Y)&b0y36dVze=mpSj1DyTX1-;{b4{eIAF_WSUrt#*CZ;{U70 zF&1e`jIaOZ_otNir$o*Dzk}b48)(QEO$|!pH^wV19gBgYO>0h^YBCcv_La`kCSIYR zCtHxF$+Pr~mA0Vh9P#Tkuh(ZnTd?SuC_TmT>6y|W;I|^uWSa@8Rrk@)wa!``D>t3g zXLWVRq|hQ3EP|VpNo~zWpbHcC*4U-y?S$xgLzmi!Drn57+IHJ4VRghZMil`Y*E$nWwK#JDOdKo36lv(rgDm@UfO`> zaK9Srujyx(k4YS(QWqjAi>@AAAxS<+s_}yGrRU1cE1cPNBcT0l$S`=*=(mgaW%k%m zM^m7-rgUv-FRSWdRUDsEb#DdAlByJbo`9+9Z;Id4@sl1o)^0q|>-D^ijH#@{tPV#Ju`k13yRSMf&n(ysye>zx?|E>>x!M_4L_y3>KxIO Date: Mon, 8 Jul 2024 14:50:28 -0400 Subject: [PATCH 08/29] log permissions --- .../workbench/leonardo/http/service/RuntimeServiceInterp.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeServiceInterp.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeServiceInterp.scala index f3a800d6529..d86b26f27f4 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeServiceInterp.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeServiceInterp.scala @@ -1331,6 +1331,8 @@ object RuntimeServiceInterp { WorkspaceAction.CreateControlledApplicationResource, userInfo ) // TODO: Correct check? + _ <- log.info(s"has permission: ${hasPermission.toString}") + _ <- log.info(s"workspace: ${workspaceId.toString}") _ <- if (hasPermission) F.unit else F.raiseError[Unit](ForbiddenError(userInfo.userEmail)) samResource <- F.delay(PersistentDiskSamResourceId(UUID.randomUUID().toString)) // Look up the original email in case this API was called by a pet SA From ee35023a5587a73b27857e60326e237f02a2000a Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Mon, 8 Jul 2024 15:22:22 -0400 Subject: [PATCH 09/29] more logging --- .../dsde/workbench/leonardo/auth/SamAuthProvider.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/auth/SamAuthProvider.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/auth/SamAuthProvider.scala index e30e9df0c5e..ee5ba7fb57a 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/auth/SamAuthProvider.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/auth/SamAuthProvider.scala @@ -74,6 +74,7 @@ class SamAuthProvider[F[_]: OpenTelemetryMetrics]( .info(Map("traceId" -> traceId.asString), e)(s"$action is not allowed for resource $samResource") .as(false) } + _ <- logger.info(s"result of hasPermission($samResource, $action): $res") } yield res override def hasPermissionWithProjectFallback[R, A]( From 604c98777fa08214ec27c08a69472868357dc5a5 Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:19:37 -0400 Subject: [PATCH 10/29] allow disks for jup apps --- .../leonardo/http/service/LeoAppServiceInterp.scala | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/LeoAppServiceInterp.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/LeoAppServiceInterp.scala index 35ff982cb34..d296c68d32e 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/LeoAppServiceInterp.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/LeoAppServiceInterp.scala @@ -1414,11 +1414,13 @@ final class LeoAppServiceInterp[F[_]: Parallel](config: AppServiceConfig, // Validate disk. // Apps on GCP require a disk. - // Apps on Azure require _no_ disk. - _ <- (cloudContext.cloudProvider, diskOpt) match { - case (CloudProvider.Gcp, None) => + // Apps on Azure require _no_ disk. !!except Jupyter apps!! + _ <- (cloudContext.cloudProvider, diskOpt, req.appType == AppType.Jupyter) match { + case (CloudProvider.Gcp, None, _) => Left(AppRequiresDiskException(cloudContext, appName, req.appType, ctx.traceId)) - case (CloudProvider.Azure, Some(_)) => + case (CloudProvider.Azure, None, true) => + Left(AppRequiresDiskException(cloudContext, appName, req.appType, ctx.traceId)) + case (CloudProvider.Azure, Some(_), false) => Left(AppDiskNotSupportedException(cloudContext, appName, req.appType, ctx.traceId)) case _ => Right(()) } From d4f8b8297ef161370e7318347aca25e5d1cb8341 Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:46:47 -0400 Subject: [PATCH 11/29] app install --- .../dsde/workbench/leonardo/app/AppInstall.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/AppInstall.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/AppInstall.scala index a6a80182ecf..0185c4e4fee 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/AppInstall.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/AppInstall.scala @@ -47,13 +47,15 @@ object AppInstall { cromwellAppInstall: CromwellAppInstall[F], workflowsAppInstall: WorkflowsAppInstall[F], hailBatchAppInstall: HailBatchAppInstall[F], - cromwellRunnerAppInstall: CromwellRunnerAppInstall[F] + cromwellRunnerAppInstall: CromwellRunnerAppInstall[F], + jupyterAppInstall: JupyterAppInstall[F] ): AppType => AppInstall[F] = _ match { case AppType.Wds => wdsAppInstall case AppType.Cromwell => cromwellAppInstall case AppType.WorkflowsApp => workflowsAppInstall case AppType.HailBatch => hailBatchAppInstall case AppType.CromwellRunnerApp => cromwellRunnerAppInstall + case AppType.Jupyter => jupyterAppInstall case e => throw new IllegalArgumentException(s"Unexpected app type: ${e}") } From b43b9f5a811e5edecde32737c1f63b2ae0b8b648 Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:53:52 -0400 Subject: [PATCH 12/29] oops --- .../dsde/workbench/leonardo/http/AppDependenciesBuilder.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/AppDependenciesBuilder.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/AppDependenciesBuilder.scala index 525a77a04c3..2b5a635aa89 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/AppDependenciesBuilder.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/AppDependenciesBuilder.scala @@ -238,7 +238,8 @@ class AppDependenciesBuilder(baselineDependenciesBuilder: BaselineDependenciesBu cromwellAppInstall, workflowsAppInstall, hailBatchAppInstall, - cromwellRunnerAppInstall + cromwellRunnerAppInstall, + jupyterAppInstall ) val aksAlg = new AKSInterpreter[IO]( From e0c271923255492564f8e3f11984c046aed78ace Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Mon, 8 Jul 2024 17:29:46 -0400 Subject: [PATCH 13/29] change chart loc --- http/src/main/resources/reference.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http/src/main/resources/reference.conf b/http/src/main/resources/reference.conf index 1be3a8228c1..070150b3256 100644 --- a/http/src/main/resources/reference.conf +++ b/http/src/main/resources/reference.conf @@ -450,7 +450,7 @@ azure { } jupyter-app-config { - chart-name = "terra-helm/jupyter" + chart-name = "leonardo/jupyter" // TODO (LM) this should be terra-helm/jupyter chart-version = "0.1.0" release-name-suffix = "jupyter-rls" namespace-name-suffix = "jupyter-ns" From 37c9f246c73c5f0e735c0d1d1ffefdac8d8e1a15 Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Tue, 9 Jul 2024 09:38:24 -0400 Subject: [PATCH 14/29] missing /? --- http/src/main/resources/reference.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http/src/main/resources/reference.conf b/http/src/main/resources/reference.conf index 070150b3256..4842212e1a8 100644 --- a/http/src/main/resources/reference.conf +++ b/http/src/main/resources/reference.conf @@ -450,7 +450,7 @@ azure { } jupyter-app-config { - chart-name = "leonardo/jupyter" // TODO (LM) this should be terra-helm/jupyter + chart-name = "/leonardo/jupyter" // TODO (LM) this should be terra-helm/jupyter chart-version = "0.1.0" release-name-suffix = "jupyter-rls" namespace-name-suffix = "jupyter-ns" From 190c9a8e8284ba3a5ba1f5c92596dfe50fd86455 Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Tue, 9 Jul 2024 10:54:16 -0400 Subject: [PATCH 15/29] log vals --- .../dsde/workbench/leonardo/util/AKSInterpreter.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/AKSInterpreter.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/AKSInterpreter.scala index e0cd647718c..595c59d34dd 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/AKSInterpreter.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/AKSInterpreter.scala @@ -258,6 +258,10 @@ class AKSInterpreter[F[_]](config: AKSInterpreterConfig, ) values <- app.appType.buildHelmOverrideValues(helmOverrideValueParams) + _ <- logger.info(ctx.loggingCtx)( + s"Values for app ${params.appName.value} are ${values.asString}" + ) + // Install app chart _ <- childSpan("helmInstallApp").use { _ => helmClient From 713ed4403219d9f5b02cb16e38f4408dd211ce7c Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Tue, 9 Jul 2024 11:19:34 -0400 Subject: [PATCH 16/29] get value --- .../dsde/workbench/leonardo/app/JupyterAppInstall.scala | 4 ++-- .../dsde/workbench/leonardo/model/LeoException.scala | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala index caff8f8fbc9..6c5287793cc 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala @@ -43,8 +43,8 @@ class JupyterAppInstall[F[_]](config: JupyterAppConfig, jupyterDao: JupyterDAO[F raw"workspace.cloudProvider=Azure", // persistent disk configs - raw"persistence.diskName=${disk.name}", - raw"persistence.diskSize=${disk.size}", + raw"persistence.diskName=${disk.name.value}", + raw"persistence.diskSize=${disk.size.gb}", // misc raw"serviceAccount.name=${params.ksaName.value}", diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/model/LeoException.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/model/LeoException.scala index 4a7d2118972..8add04f24d0 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/model/LeoException.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/model/LeoException.scala @@ -246,7 +246,7 @@ case class AppResourceCannotBeDeletedException(wsmResourceId: WsmControlledResou wsmResourceType: WsmResourceType, traceId: TraceId ) extends LeoException( - s"Azure ${wsmResourceType.toString} with id ${wsmResourceId.value} associated with ${appId.id} cannot be deleted in $status status, please wait and try again", + s"Azure ${wsmResourceType.toString} with id ${wsmResourceId.value} associated with ${appId.id} cannot be deleted in $status status in WSM, please wait and try again", StatusCodes.Conflict, traceId = Some(traceId) ) From d4c0ac210b2d4074d773b5390ab08bb0a28050f0 Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Tue, 9 Jul 2024 13:47:43 -0400 Subject: [PATCH 17/29] helm update --- jupyter-0.1.0.tgz | Bin 1891 -> 1889 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/jupyter-0.1.0.tgz b/jupyter-0.1.0.tgz index 5b7214c4f3a79341ec69d7555432e618dfd0addc..8ff1cb20745280e9c6e3cd89a0fac0367d0698a1 100644 GIT binary patch delta 1837 zcmV+|2h#ZC4&e@vNq;L@jvXfu(1#!i4(V-jMx5JyI1~XbjbkpD1Q|dJcPxe6QhbGO?CeL zlmkgqMk8XrLyU^vbBsX?kQs-6+N;CJ6aL4UaS|5t$@U@XOg#u&qN33`skVWA8ILOR6- z2_1l@djrsf+<#*Tu0|JP0jY_+Qme4pA;z6BL z8G_rJiv&yDUTWfm(#Z8)Ox1(IPlePWoSdATH~>?k@HffKzH*D}IDZKFpi&Z{ku_o> ziwo6c2sgi7-(Fr_+>K9fPOmO*FK&$Zarb+xX4i_+LVuEbJQG|K%2DPrY=d}%N@Oy^ z%TAU~^AO&m;6%p4F(#uCo<@<#xDLM{nj?{sWv;j293vBLub;yG0Zz^F!1x@}8r%1i zE2lENHKH;8Ih7b`A(z{nlKFg!uU(zcPu)`Ov%xok@-Q_fDI*$H?{1FF9Ida@7fJ=s z#Q($5QGd{i|3`yhw2%L<0jpK-C+Fg0N_d<{e-mLq%<|_b?+KirdXJCJYUM$UGs+QM zlBT}FbHQ7$kc?^YZ5v@i0Qm20NntR5U7(aSM)(X`W;}w?Ab+IEB%96XM{qqC3R=ix z^XTM~ok=7bfm9r38DmTMkP${_6yrQw84kYl9)B(E9A6s_Mt%iTj7X*slt>VM$)+ed zYE)L!8ATQ=AQFMmglb#e>N!>Lmm(jYUr!7!<@cacjQ;97mot#akf_33kqz_88qB_< z8vdY+!4x4=MotAJ7rv0T)2L>>X;?a|>{u>Vwk%MdT;ImlOjUH=y8YGaer#O0+DRJEC>j@Yiuq|4SHog4 zGDY^piRKvV<7}%@x3GOKnlbnc5>rMZ1ov+)xOeXEt|O8}a4Vhamd>tO@#e@9U(I{D z#38I!KzYQnxT%P5SvA)bvb;oiTafc>H-Dp0>oiSE%^n{ev+1GoL{lYJo#ATLvE?&- z$b`n0nwwM-!pS|x-gIdRmA7PK3#m>sO$y<^XsEV^UMG87owcoF9op}fm~y3wskR#O z*4?HM_G`ue&HNu@%EU53{$k^xXY&6r7>ru^e-sRYeg1z9sLy{$nyTKS?>tZ*hktNh z-2*2)p@^$9QFFF+7WHtcgp`ebIOQ>N4MVffBv`Y@#6B7k6++*1 zQ-$|gY6;QN{B4bV2ZPOsv}QE20+tuPAX?MV0Bg|Sk;94Q08pxvKR22=+a$U5{M|&z z!v;J)y4Ch5lT7K}!wfBTi+2%)d2%57MZ zUI>;YSX0*9>X5yn$*r~ltUJPYIn6UhXcE>COkYlDa=i`tbP*Lhqq2?eka0bYD50E6 zn1EWCwm|aprJ7MI^l`>mX{F2Awa{aU%G~@l-jfHAOGr{OrHpD?x1$9T$A9ft9$a7C z-kqLbU0&B#h`d)J{O}N@r;kuh1{! z9Z1voS$f7wJ5Vef@yj$Pn}3s`9awbCm7e1G^knHz@LLmUvQ355s{82YTBj|Jm79+1 zv${H@QfLtg7Q*e>xVB~^(3OdM8|)JEc1-lVp-XL0RSK>qbEP3z1>)rqOTb@5}75 zrH-aRZB6Og(q329!+*LsKBwxz3Y5lGDf~PEQ`O(*zp3L#JuFxk;{ng}oUM*BFUkL# z^NhAUP@BuQtnjxx#C1+`Y>N7jp;}i8yIh)Y?QY*4Y{vhh4}HPE0zCKspW&!I|2Z1; z2mAQ{8qgUuih1el&wcD)hR#@~G|J1d(`Z4w=AQrzXd>@Xk0#rNY*(MrXj_^SrJaU5 b!+jXp!yfkV{{jCA00960Yxpy_04x9icWs~( delta 1839 zcmV+~2hjN84&x4xNq=iub{r=V(1#!i4(V;OMv~ioI1~XbjbkxC)F}HWb0T%HBq`f_aR|dO9FIoDXBdX<&v0-!+8d0< zqrq@IIv9p~;b3?e4)!2?c~RCOSDMJZ@DKB9EB8MFB%|+9Dt{_?1dE}Upo%5Ubn*R| z1IaQ*V`9ETf{Na8Oh5~eIfsARtHa0?1c&2au02jtjKEzfPcJi!>J+?1$tes5LFj#N z-FL9JSNi{gupHI52>{Rd|6n)_TmHX4*bjI9{~GWEOr%)Q1QVDpLC?`RERFztg>UdSlQB{Jh{G!t(mImyeZ_4{;~OCu4Jq%V2K1* z)_**9Zz*Tv<(9%_l5#x*|3}sPQTZ)emg(kKtNXEW;c6#oJi|3E<`j$5bXUV-F)~H= z#EBLdtK)2|QMa&tcFh=k0f`wSF@pa$AN*T?d)E z9)R+gCL z@zJlg$GN0>X_`s=q*s#7)X!4nS$_n>FbvyoPv(T*;Y2VRo6hYWzY;=UP*vElB)t$U zPqC(KZ=*x*x%Rf&2C(V{-xoAb7@=uYLogjVq3Pu&{957L}hON3h&7SC?q5qnNmhIt=rK8Ns{)f9)Db(-P|6Z zUYuXnR*1Y)5&Y)&b0y36dVze=mpSj1DyTX1-;{b4{eIAF_WSUrt#*CZ;{U70F&1e` zjIaOZ_otNir$o*Dzk}b48)(QEO$|!pH^wV19gBgYO>0h^YBCcv_La`kCSIYRCtHxF z$+Pr~mA0Vh9P#Tkuh(ZnTYs?Vm?%BP@#&e;AK&N1!Jh@z>wo{cYrRYZ@Z9e| z`v-^Z`hPGU@9O{8fX45?W$8a@)p1)l0KIHc)$(PsVMHlc_PPm^2}q`Lim6`OfaY+& z8tSjxkJ{cXrFc+=>&i}z*r*ic7P zpth!TZD}v7>S0wJpMO$yZw1PdsuX^nfT`+lir>`nlO8$NZamQI^}LOavM9;_oAZn} zJW!j~hCJH%B^@@$Iwn4?-%3fo+o@9l1XI#`eYt`B{|zXCk>|DVygJ^wk_4~M(> z{~FL4G~B%O_2)kJFGD9RR~qH{#A~!5Jy)^bygPm8TwfD;hbVf|E@Zp Date: Tue, 9 Jul 2024 14:29:22 -0400 Subject: [PATCH 18/29] add resourceid --- .../dsde/workbench/leonardo/app/JupyterAppInstall.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala index 6c5287793cc..0863d689f15 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala @@ -45,6 +45,7 @@ class JupyterAppInstall[F[_]](config: JupyterAppConfig, jupyterDao: JupyterDAO[F // persistent disk configs raw"persistence.diskName=${disk.name.value}", raw"persistence.diskSize=${disk.size.gb}", + raw"persistence.diskResourceId=${disk.wsmResourceId.toString}", // misc raw"serviceAccount.name=${params.ksaName.value}", From eb417921e2754f8e4a83549f9de7135febe912ba Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Tue, 9 Jul 2024 14:31:31 -0400 Subject: [PATCH 19/29] add package --- jupyter-0.1.0.tgz | Bin 1889 -> 1899 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/jupyter-0.1.0.tgz b/jupyter-0.1.0.tgz index 8ff1cb20745280e9c6e3cd89a0fac0367d0698a1..da3db48680751a2bb4f6edadf57ec37f90cbdbe8 100644 GIT binary patch delta 1845 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 delta 1835 zcmV+`2h{lM4&e@vOMi|XClJtwAPElXZE{AO+kH3`0WFPVHWaBPDc^d%`R@fqNtR?~ zWB0PzZQ*&bEDq<3oKO4TS-R9HduMYZwZ9|@J9u#jf*=?Thxum^1ntkDe>^hkx3u!^ji_htpps4krnQP+TcTFH;Qb6r4rLDe(J#;CyS{ z_i%7f`u~Ek4As{O0MGb;|FD19^8Z19xcC28fgfNj#e&8d!*mIHj>ci33GB=5}}bbVj_zR z)no`azg^#6UR~UcPj61IE^aSwjQDZ)d#h&Giqb-odw)C=TocMs<}z%9c!Nr0GQ!JF zmQM2!-lE_{#=83|eM9g3%y3W zR?`_p7AqhUfzgC&Tixn8Rq&T0AD&-N3@+vOpi+$f>N}S+kjRjz!d#IJ^U4~`zM~rc zpp3y3AyY<91tb@~khasPX1!@xI;-qhE>^ZIP@Y`h#@0+#bl&80hyU3AFxN6x7O+J8 z8-HsaySJ3H@p4DuQc1a(zEjeG}#&4{#SG_nGg7rr1`)6f8G(BF~6iRA!Ls*^uAnmOAfx%K?rM99Mi zJU+VB_9&B7FHK8{AN5+Ynfh6ZEPoB*FbIP7+p{_0_c#`eMy7xJmEQ=Vuc*pxSdv}{ zmL*tI*4yfky`ssjwgId=!go2%Ge&3<)(}izPH1wy4f%8t6+5G{jqZ?fJ&h=#oJyF0 zT9~##^7EydQ7iOu##m{k%h|QiV~NV#{59T_2arohQZl8CYFf9W1ro>YSAQN{U)Cb;OUHbmXwzCDPBowL8~aLUX%nx|FXJ6Z z)A(6>#!5R-EFAI6G$)&rp?@7%bj+2W;`sDr=}+)m6KS$dh19D1=;vCeEsm9&j_b3! zI;2u)5eXK;?b*1tW+Tv*iF+ID67zOU^t_=G`kVeqEWZ|CpJ?6IYe zra)~?>Dtm>SJlJ1IDbB;>cI+>##Jf&JONYH-{!xm<3~L#SQp~~&-0wEjxsOF|C{rS zwmeXq%eSoXw>!jjPI7FD`jDYoR|>mans4oH-yLkm|Dq3l!M_4L_y3>as6GEV8uSPI z`2QNv88nJ{>FdvZ>|ch?Sf(_}%dyjFLA>Ul01Rj%?@^E2g(PfOpV4SrniHj+hC9Q3 Z7}>)f_VE7!{|Nv9|Nm?FGq(UN000SdpO*jt From 1a56f1261a3fbb19db77cde74ea89b7de6d838d9 Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Tue, 9 Jul 2024 18:49:23 -0400 Subject: [PATCH 20/29] changing azure volume structure --- .../workbench/leonardo/app/AppInstall.scala | 6 +++-- .../leonardo/app/JupyterAppInstall.scala | 9 +++++++- .../http/service/RuntimeServiceInterp.scala | 2 -- .../leonardo/util/AKSInterpreter.scala | 21 +++++++++--------- .../leonardo/app/BaseAppInstallSpec.scala | 5 +++-- .../leonardo/app/CromwellAppInstallSpec.scala | 3 ++- jupyter-0.1.0.tgz | Bin 1899 -> 2025 bytes 7 files changed, 28 insertions(+), 18 deletions(-) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/AppInstall.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/AppInstall.scala index 0185c4e4fee..e6ad0d17b71 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/AppInstall.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/AppInstall.scala @@ -15,7 +15,8 @@ import org.broadinstitute.dsde.workbench.leonardo.{ LandingZoneResources, ManagedIdentityName, WorkspaceId, - WsmControlledDatabaseResource + WsmControlledDatabaseResource, + WsmControlledResourceId } import org.broadinstitute.dsp.Values import org.http4s.Uri @@ -90,5 +91,6 @@ final case class BuildHelmOverrideValuesParams(app: App, ksaName: ServiceAccountName, managedIdentityName: ManagedIdentityName, databaseNames: List[WsmControlledDatabaseResource], - config: AKSInterpreterConfig + config: AKSInterpreterConfig, + diskWsmResourceId: Option[WsmControlledResourceId] ) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala index 0863d689f15..1a9fefebbc7 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala @@ -33,6 +33,11 @@ class JupyterAppInstall[F[_]](config: JupyterAppConfig, jupyterDao: JupyterDAO[F AppCreationException("Disk required for Jupyter app", Some(ctx.traceId)) ) +// diskResourceId <- F.fromOption( +// params.diskWsmResourceId, +// AppCreationException("Disk required for Jupyter app", Some(ctx.traceId)) +// ) + values = List( // workspace configs @@ -45,7 +50,9 @@ class JupyterAppInstall[F[_]](config: JupyterAppConfig, jupyterDao: JupyterDAO[F // persistent disk configs raw"persistence.diskName=${disk.name.value}", raw"persistence.diskSize=${disk.size.gb}", - raw"persistence.diskResourceId=${disk.wsmResourceId.toString}", + // raw"persistence.diskResourceId=${diskResourceId.value.toString}", + raw"persistence.subscriptionId=${params.cloudContext.subscriptionId.value}", + raw"persistence.resourceGroupName=${params.cloudContext.managedResourceGroupName.value}", // misc raw"serviceAccount.name=${params.ksaName.value}", diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeServiceInterp.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeServiceInterp.scala index d86b26f27f4..f3a800d6529 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeServiceInterp.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/http/service/RuntimeServiceInterp.scala @@ -1331,8 +1331,6 @@ object RuntimeServiceInterp { WorkspaceAction.CreateControlledApplicationResource, userInfo ) // TODO: Correct check? - _ <- log.info(s"has permission: ${hasPermission.toString}") - _ <- log.info(s"workspace: ${workspaceId.toString}") _ <- if (hasPermission) F.unit else F.raiseError[Unit](ForbiddenError(userInfo.userEmail)) samResource <- F.delay(PersistentDiskSamResourceId(UUID.randomUUID().toString)) // Look up the original email in case this API was called by a pet SA diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/AKSInterpreter.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/AKSInterpreter.scala index 595c59d34dd..831b904002a 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/AKSInterpreter.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/AKSInterpreter.scala @@ -154,7 +154,7 @@ class AKSInterpreter[F[_]](config: AKSInterpreterConfig, } // Create or fetch WSM disk (only for Jupyter apps) - _ <- childSpan("createWsmDisk").use { implicit ev => + diskResourceId <- childSpan("createWsmDisk").use { implicit ev => createOrFetchWsmDiskResource( app, params.workspaceId @@ -254,7 +254,8 @@ class AKSInterpreter[F[_]](config: AKSInterpreterConfig, namespace.serviceAccountName, managedIdentityName, wsmDatabases ++ referenceDatabases, - config + config, + diskResourceId ) values <- app.appType.buildHelmOverrideValues(helmOverrideValueParams) @@ -495,7 +496,8 @@ class AKSInterpreter[F[_]](config: AKSInterpreterConfig, ksaName, managedIdentityName, wsmDatabases ++ referenceDatabases, - config + config, + app.appResources.disk.flatMap(_.wsmResourceId) ) values <- app.appType.buildHelmOverrideValues(helmOverrideValueParams) @@ -906,11 +908,11 @@ class AKSInterpreter[F[_]](config: AKSInterpreterConfig, private[util] def createOrFetchWsmDiskResource(app: App, workspaceId: WorkspaceId)(implicit ev: Ask[F, AppContext] - ): F[Unit] = + ): F[Option[WsmControlledResourceId]] = for { ctx <- ev.ask - _ <- + diskResourceId <- app.appResources.disk match { case Some(disk) => for { @@ -946,6 +948,7 @@ class AKSInterpreter[F[_]](config: AKSInterpreterConfig, createDiskResponse <- F.blocking( wsmResourceApi.createAzureDiskV2(request, workspaceId.value) ) + _ <- logger.info(ctx.loggingCtx)(s"WSM create disk response: ${createDiskResponse}") op = F.blocking(wsmResourceApi.getCreateAzureDiskResult(workspaceId.value, createDiskJobId)) result <- streamFUntilDone( @@ -958,13 +961,11 @@ class AKSInterpreter[F[_]](config: AKSInterpreterConfig, _ <- F.raiseWhen(result.getJobReport.getStatus != JobReport.StatusEnum.SUCCEEDED)( AppCreationException( - s"WSM database creation failed for app ${app.appName.value}. WSM response: ${result}", + s"WSM disk creation failed for app ${app.appName.value}. WSM response: ${result}", Some(ctx.traceId) ) ) - _ <- logger.info(ctx.loggingCtx)(s"WSM create disk response: ${createDiskResponse}") - // Save record in APP_CONTROLLED_RESOURCE table _ <- appControlledResourceQuery .insert( @@ -978,11 +979,11 @@ class AKSInterpreter[F[_]](config: AKSInterpreterConfig, // Update disk status _ <- persistentDiskQuery.updateStatus(disk.id, DiskStatus.Ready, ctx.now).transaction - } yield result + } yield Some(WsmControlledResourceId(common.getResourceId)) case None => F.pure(None) } - } yield () + } yield diskResourceId private[util] def createMissingAppControlledResources(app: App, appInstall: AppInstall[F], diff --git a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/app/BaseAppInstallSpec.scala b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/app/BaseAppInstallSpec.scala index e19e27b835a..5f8c5773ddc 100644 --- a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/app/BaseAppInstallSpec.scala +++ b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/app/BaseAppInstallSpec.scala @@ -6,7 +6,7 @@ import com.azure.resourcemanager.batch.models.{BatchAccount, BatchAccountKeys} import org.broadinstitute.dsde.workbench.azure._ import org.broadinstitute.dsde.workbench.google2.KubernetesSerializableName.ServiceAccountName import org.broadinstitute.dsde.workbench.google2.{NetworkName, SubnetworkName} -import org.broadinstitute.dsde.workbench.leonardo.CommonTestData.{azureRegion, billingProfileId} +import org.broadinstitute.dsde.workbench.leonardo.CommonTestData.{azureRegion, billingProfileId, wsmResourceId} import org.broadinstitute.dsde.workbench.leonardo.KubernetesTestData.makeApp import org.broadinstitute.dsde.workbench.leonardo.config.Config.appMonitorConfig import org.broadinstitute.dsde.workbench.leonardo.config.SamConfig @@ -98,7 +98,8 @@ class BaseAppInstallSpec extends AnyFlatSpecLike with LeonardoTestSuite with Moc ServiceAccountName("ksa-1"), ManagedIdentityName("mi-1"), databases, - aksInterpConfig + aksInterpConfig, + None ) private def setUpMockSamDAO: SamDAO[IO] = { diff --git a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/app/CromwellAppInstallSpec.scala b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/app/CromwellAppInstallSpec.scala index 678753ab125..300458c595f 100644 --- a/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/app/CromwellAppInstallSpec.scala +++ b/http/src/test/scala/org/broadinstitute/dsde/workbench/leonardo/app/CromwellAppInstallSpec.scala @@ -91,7 +91,8 @@ class CromwellAppInstallSpec extends BaseAppInstallSpec { ServiceAccountName("ksa-1"), ManagedIdentityName("mi-1"), cromwellOnAzureDatabases, - aksInterpConfig + aksInterpConfig, + None ) val overrides = cromwellAppInstall.buildHelmOverrideValues(params) diff --git a/jupyter-0.1.0.tgz b/jupyter-0.1.0.tgz index da3db48680751a2bb4f6edadf57ec37f90cbdbe8..c539834e085a721b165a99ca4a630c44a17748cb 100644 GIT binary patch delta 1985 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 w1DeQN)Z=y`+tp_@+Lq=-X|LhV;D0_O9N+*4_& Date: Thu, 11 Jul 2024 11:14:18 -0400 Subject: [PATCH 21/29] status endpoint --- .../dsde/workbench/leonardo/app/JupyterAppInstall.scala | 2 +- .../dsde/workbench/leonardo/dao/HttpJupyterDAO.scala | 6 +++++- .../dsde/workbench/leonardo/util/AKSInterpreter.scala | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala index 1a9fefebbc7..53299ea4048 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala @@ -63,5 +63,5 @@ class JupyterAppInstall[F[_]](config: JupyterAppConfig, jupyterDao: JupyterDAO[F override def checkStatus(baseUri: Uri, authHeader: Authorization)(implicit ev: Ask[F, AppContext] ): F[Boolean] = - jupyterDao.getStatus(baseUri, authHeader) + jupyterDao.getStatus(baseUri, authHeader).handleError(_ => false) } diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/HttpJupyterDAO.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/HttpJupyterDAO.scala index d71acbdeec0..6606b8300bd 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/HttpJupyterDAO.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/HttpJupyterDAO.scala @@ -40,6 +40,9 @@ class HttpJupyterDAO[F[_]](val runtimeDnsCache: RuntimeDnsCache[F], client: Clie headers = Headers(authHeader) ) ) + _ <- logger.info(s"(LM) Jupyter endpoint: ${baseUri / "api" / "status"}") + _ <- logger.info(s"(LM) Jupyter status result: $res") + } yield res.isSuccess def isProxyAvailable(cloudContext: CloudContext, runtimeName: RuntimeName): F[Boolean] = @@ -56,7 +59,8 @@ class HttpJupyterDAO[F[_]](val runtimeDnsCache: RuntimeDnsCache[F], client: Clie client .successful( Request[F]( - method = Method.GET, + method = + Method.GET, // private def azureUri: Uri = Uri.unsafeFromString(s"https://${hostname.address()}/${path}") uri = x.toNotebooksUri / "api" / "status", headers = headers ) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/AKSInterpreter.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/AKSInterpreter.scala index 831b904002a..648ffcb5bb7 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/AKSInterpreter.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/AKSInterpreter.scala @@ -440,6 +440,7 @@ class AKSInterpreter[F[_]](config: AKSInterpreterConfig, relayDomain = s"${landingZoneResources.relayNamespace.value}.servicebus.windows.net" relayEndpoint = s"https://${relayDomain}/" relayPath = Uri.unsafeFromString(relayEndpoint) / hcName.value + relayPrimaryKey <- azureRelayService.getRelayHybridConnectionKey(landingZoneResources.relayNamespace, hcName, params.cloudContext From e7de53ee2c366647ee17b7ef6f2e7aaed0383cac Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Fri, 12 Jul 2024 11:03:46 -0400 Subject: [PATCH 22/29] new helm --- jupyter-0.1.0.tgz | Bin 2025 -> 1989 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/jupyter-0.1.0.tgz b/jupyter-0.1.0.tgz index c539834e085a721b165a99ca4a630c44a17748cb..b2d00d2d620b8478d49523aa3b753237ffee44d2 100644 GIT binary patch delta 1942 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 M|K2Zx?f@ Date: Fri, 12 Jul 2024 11:14:47 -0400 Subject: [PATCH 23/29] new helm again --- jupyter-0.1.0.tgz | Bin 1989 -> 1992 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/jupyter-0.1.0.tgz b/jupyter-0.1.0.tgz index b2d00d2d620b8478d49523aa3b753237ffee44d2..46a0b5e81ba0b0a77fd1b93feb14584f3ac6bb25 100644 GIT binary patch delta 1954 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 From a1c3da6eed8a1970e304bf9b65a55d153f8bf0ea Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Fri, 12 Jul 2024 14:58:19 -0400 Subject: [PATCH 24/29] new helm again again --- jupyter-0.1.0.tgz | Bin 1992 -> 1998 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/jupyter-0.1.0.tgz b/jupyter-0.1.0.tgz index 46a0b5e81ba0b0a77fd1b93feb14584f3ac6bb25..1fe33686f7b78083e1c9c41690421032c1cc5b2f 100644 GIT binary patch delta 1960 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 From 70654881cf373ac920c56ed4a99c347daf8ee098 Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Tue, 16 Jul 2024 22:40:37 -0400 Subject: [PATCH 25/29] launch w/o PD --- jupyter-0.1.0.tgz | Bin 1998 -> 2006 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/jupyter-0.1.0.tgz b/jupyter-0.1.0.tgz index 1fe33686f7b78083e1c9c41690421032c1cc5b2f..c1f16dcf17ab77f05f27b1fb35b349fbbb71b68a 100644 GIT binary patch delta 1965 zcmV;e2U7UX57rNmKYzM4&-xVyYA>+eO&>`dClIiQED5^oHmQ;1whtFWKugCl7m8F# z%B`E`zYioOTaxX@Uegp8FkdW-hv$ntpVWWLVyaO_Cu1UYI3+pTdG-;~9>$ z-QRfku(z|@>-P@&d%gYrcqiW7JB)if5I;XFi=$MU$esARX@7Nv`;!b((Dx`66+D5- zo|mCYB`vi5f6Rdt1*0i3{~<#~?>J_l1;~=azunPcWC()8@o(22Cpjii9Vt&w3rw0A zyh%+d4tK-Y``NN@$Ieb|{}aMWR6oW6JYoO4`|&}?{`YtH54ZOJ65|yNq?phQGZ;=m zkI@(`)NVjXuYWoqi3iX&ZvdK;J50dWC?&~oLQ+|jLq^k(d?_WSGNdA^zypPHf-=#l zv~O?;jYA>s)hU$;_|aJ8Si_q6LP(v!(b3V72QVZGf0xX_)#ugsyiY>jtAeCxcuScm zvq}`1z}4@UH|G~;w}a!WYaTq z2+yqdHy#JX$UdjGCh&fZ9v{7jhX67hQI6n~q6iI~55atfluSeD$_Qhr5WaUQg@JrG zK`Cj5@D;Qyc?$h~`$+Taax|i!!4G_>a3Rmkqkm^PJCR5<0+~@5m5fc{V@VhtQOs<# zG897Z13KImUKoO5TR6tPX)v>Uvaxssb;>dSUQ^N zv45VN>9PV@IlqpsnVR8wZTU|AvHoVxd7Np$AqlUXdfeKY&(_NgnJXmadIbJ2D)>eD z9bAs+`bTT|W9z^*cG6fzRk)a4w7Xdy4F|=@5ZQ_ywGi{|?26IUuzRkGG587+3r11| z|8G9{xBlj)Bl28u$DLZvotty)jgjS{8h=NY;{+Zafbx`;SzD0Mk!sH=WHx1ZTcHaZ zC!-SUxF~AL9v?lk=zeC2CQF=Eh7S)*mVAYerO?OU zt}Euhsi>}m!BX-rTkC4a8FaXuW6G5#Ci`mf+ccYs*&pTq7vq111ryU8`Lnfyo_~n{ zy|{PSiU0k0Z`=QQkQQ$lj8m=DTLFc3s-f5!_&0%- z1|*jBnpRO<-EH~~dUGUgvW1XZE#LaF)w;?pRm*siK}szkgDyr;euz`kS%hntm}s{f$}eg3pD>FoAzEk=`3Y(-f65?m-%5@8OD`shRK_pdlK~pJ|80qjtTr z^pU!;9|quO-SdJV@YXtlwvO1i5VZxwx+lnSyk=dp-uYN|tmc8$b8+@#iE5r=ZFX|M z+x{2*e^rM*megD(z_ZRPf4z~XPCB{FB&c1LNW=1%WNc4N0=JGNsxUT*v^00960w|?jE04x9iAye9q delta 1957 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 From e2cb6b53cbf443b8d06e13aeb47501d7a857dd55 Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Tue, 23 Jul 2024 11:04:17 -0400 Subject: [PATCH 26/29] dynamic PD --- .../leonardo/app/JupyterAppInstall.scala | 5 ++++- jupyter-0.1.0.tgz | Bin 2006 -> 2080 bytes 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala index 53299ea4048..593ca7c2b37 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala @@ -50,10 +50,13 @@ class JupyterAppInstall[F[_]](config: JupyterAppConfig, jupyterDao: JupyterDAO[F // persistent disk configs raw"persistence.diskName=${disk.name.value}", raw"persistence.diskSize=${disk.size.gb}", - // raw"persistence.diskResourceId=${diskResourceId.value.toString}", raw"persistence.subscriptionId=${params.cloudContext.subscriptionId.value}", raw"persistence.resourceGroupName=${params.cloudContext.managedResourceGroupName.value}", + // app resource requests + raw"resources.cpu=100", //${params.app.appResources}", + raw"resources.memory=128", //${disk.size.gb}", + // misc raw"serviceAccount.name=${params.ksaName.value}", raw"relay.connectionName=${params.app.appName.value}" diff --git a/jupyter-0.1.0.tgz b/jupyter-0.1.0.tgz index c1f16dcf17ab77f05f27b1fb35b349fbbb71b68a..d2f7ca9d81a50ab582c56412a16ed0c5717f963d 100644 GIT binary patch delta 2039 zcmV8U>LRi|6njY*!llUKo7=J%xQ`#OctPL zXdD)*Fd(E?Zhw&218BN80L{oP#^7s|lB75%iOh=$qe(!%6cQ5|P!X2seT8z4GS;ZH zZ)gdP6Cv)@DU~t!;Y?&$;hOPWNFBrL*RNlD0289{cgYN1wO@VD`%}m}m6HUGYzY%Z zTB;&rxcvR%`t1D8&G`88`25ZFn@b~Z+Wp?C)it8DkbmSBPXyP5a+Fqv#~@y!5`|3g ztdphJH2OOfoXAvo#zZv1<0KIU*YP(*^CU8|uzCy5F)`8gVjFG`j?Hqw_!ROQ+mBc0 zUTy-i(#V|=Q>yMxsl-GJxoEFSxI)%92GK7kY~$-jujrR;#w{kRv!>fl0J5~>TPccs ztAbvIrhlwO@}iqqhM84sW9(=9;Ln6=aW!T+BN|nBGec&UI?(wu9R&}>|NYTn)QbOy z2hngB|6c;`@55icH=lFDQycwF!~rq2&xx%GykEoR(!0O!LyA+%5qy&8fx+{kzaAk4 z(-62a!gwkKA6!adFyGHnN}3{k1uYAn!05m}(tqr#m`>?u@cTZLw2-If(X*1BNF*A8 ztT;>y#uo6YAdF5aruMWl90KnnI@%Ur8xBT(1rtn2p%9eF5PmBrC^>3WPSYtxmMS0; zfzga=m)+_aRq&VcJUqR)GPsoAg32-ZYv7$tK_WwPH>?>z5_l|1#lQISqghClP z6@L&bd?{_GQO$VMuynezV>P(4Wr?zN{4us>YDMRjl{@~&;}>%+mcPyua_5@)bT6LSswKO)44T zX)df@yY9vqEY=l>`=INY88F9G%b56N>C&IjHd_&&uo6H0N8w%>!Y!xWJ0;fDhu3>2AnFBVqdB1HMsTc;PQYgL8QOk%< zX76g`I~Z(6q&1_F6R_IwCDEFO27g$C{u4R8b{qgIb?kGaxO26PUq8Q_2sUiMa_O(8 zCxxVXVM z#}h0tS(%Iy3#-qr=M5|W%uD5ILz?dX7{Y5P?lF5X<<9G{+_UDQU1 zyj3y$;fIBiRna|1J`ZKV`;`i62H~qpFWUtOnk|43UbWS(_geh_)Ho(0%ZTyyKm2e) zc{m|z=Kmf1e$qfgK5uGJ8GpagbZO~m8;b5&E5%v$Yl6nS%30dPSLkQy6G+qaL3+kY zPoP*j;|5m zhU=4YZOlcWa})PA*k$JJnCMwUms;a0XmqXGc6;1`)e*}KNF?cd&VLp$ObJupFLfPCJnZ0%KpAzRktCQ1j1 zqV8@eNJM5PJ}NlpbFb%8>E8OPg%PD(9$8iWiJ}I<|C^`B75!q4__ua` zbr_`>!#|lw?ySN|f=Zc}mBM|vM3R1#RO5S|pn2I&e=pHyyMI+;d5PwDv?3~6Qb{G9 zqugelN|=8Uo-&LftlycaaEnIGixpTd!^Snr)_EJ3EoN$YVTAQ+aPul9@$+fAiE2_fm z!Oi4keq_DkwQ%-H*EZQWL)&NP)As9k`~PPAFYC}}{1o7!?|+7)cK_$_U@+Ll|CfMH zPb>SSFW>iZpA4O_LTQv|W3N$y^qU_A7|=xCq8_(X)vh|DQMNQYN>6I;41Z)db_YAy V!46&y{uclM|Nkoa9R>g_001Y!5T^hD delta 1965 zcmV;e2U7T;5Y`WnKYzM4&-xVyYA>+eO&>`dClIiQED5^oHmQ;1whtFWKugCl7m8F# z%B`E`zYioOTaxX@Uegp8FkdW-hv$ntpVWWLVyaO_Cu1UYI3+pTdG-;~9>$ z-QRfku(z|@>-P@&d%gYrcqiW7JB)if5I;XFi=$MU$esARX@7Nv`;!b((Dx`66+D5- zo|mCYB`vi5f6Rdt1*0i3{~<#~?>J_l1;~=azunPcWC()8@o(22Cpjii9Vt&w3rw0A zyh%+d4tK-Y``NN@$Ieb|{}aMWR6oW6JYoO4`|&}?{`YtH54ZOJ65|yNq?phQGZ;=m zkI@(`)NVjXuYWoqi3iX&ZvdK;J50dWC?&~oLQ+|jLq^k(d?_WSGNdA^zypPHf-=#l zv~O?;jYA>s)hU$;_|aJ8Si_q6LP(v!(b3V72QVZGf0xX_)#ugsyiY>jtAeCxcuScm zvq}`1z}4@UH|G~;w}a!WYaTq z2+yqdHy#JX$UdjGCh&fZ9v{7jhX67hQI6n~q6iI~55atfluSeD$_Qhr5WaUQg@JrG zK`Cj5@D;Qyc?$h~`$+Taax|i!!4G_>a3Rmkqkm^PJCR5<0+~@5m5fc{V@VhtQOs<# zG897Z13KImUKoO5TR6tPX)v>Uvaxssb;>dSUQ^N zv45VN>9PV@IlqpsnVR8wZTU|AvHoVxd7Np$AqlUXdfeKY&(_NgnJXmadIbJ2D)>eD z9bAs+`bTT|W9z^*cG6fzRk)a4w7Xdy4F|=@5ZQ_ywGi{|?26IUuzRkGG587+3r11| z|8G9{xBlj)Bl28u$DLZvotty)jgjS{8h=NY;{+Zafbx`;SzD0Mk!sH=WHx1ZTcHaZ zC!-SUxF~AL9v?lk=zeC2CQF=Eh7S)*mVAYerO?OU zt}Euhsi>}m!BX-rTkC4a8FaXuW6G5#Ci`mf+ccYs*&pTq7vq111ryU8`Lnfyo_~n{ zy|{PSiU0k0Z`=QQkQQ$lj8m=DTLFc3s-f5!_&0%- z1|*jBnpRO<-EH~~dUGUgvW1XZE#LaF)w;?pRm*siK}szkgDyr;euz`kS%hntm}s{f$}eg3pD>FoAzEk=`3Y(-f65?m-%5@8OD`shRK_pdlK~pJ|80qjtTr z^pU!;9|quO-SdJV@YXtlwvO1i5VZxwx+lnSyk=dp-uYN|tmc8$b8+@#iE5r=ZFX|M z+x{2*e^rM*megD(z_ZRPf4z~XPCB{FB&c1LNW=1%WNc4N0=JGNsxUT*v^00960w|?jE04x9i$IIGc From 56cfd49d5017558807d9ea144b25560454c7e196 Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Tue, 23 Jul 2024 11:29:25 -0400 Subject: [PATCH 27/29] formatting --- .../dsde/workbench/leonardo/app/JupyterAppInstall.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala index 593ca7c2b37..988f3386965 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/app/JupyterAppInstall.scala @@ -54,8 +54,8 @@ class JupyterAppInstall[F[_]](config: JupyterAppConfig, jupyterDao: JupyterDAO[F raw"persistence.resourceGroupName=${params.cloudContext.managedResourceGroupName.value}", // app resource requests - raw"resources.cpu=100", //${params.app.appResources}", - raw"resources.memory=128", //${disk.size.gb}", + raw"resources.cpu=100", // ${params.app.appResources}", + raw"resources.memory=128", // ${disk.size.gb}", // misc raw"serviceAccount.name=${params.ksaName.value}", From aa4267affdb3d2c2a10ce7f49391992b6ab0d26b Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Tue, 23 Jul 2024 16:33:50 -0400 Subject: [PATCH 28/29] adjust listener vals --- .../dsde/workbench/leonardo/util/BuildHelmChartValues.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/BuildHelmChartValues.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/BuildHelmChartValues.scala index 05eb8fe859e..b8e2e15d53a 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/BuildHelmChartValues.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/util/BuildHelmChartValues.scala @@ -260,7 +260,7 @@ private[leonardo] object BuildHelmChartValues { case AppType.HailBatch => "http://batch:8080" case AppType.WorkflowsApp => s"http://wfa-${release.asString}-reverse-proxy-service:8000/" case AppType.Jupyter => - s"http://jupyter-${release.asString}-reverse-proxy-service:8000/" // TODO (LM) may need to alter order http://jupyter:8000%{REQUEST_URI} + s"http://jupyter-${release.asString}:8888/" case _ => "unknown" } From 638883f9f842ac9fac1bc22fbd8ad3d40160d04a Mon Sep 17 00:00:00 2001 From: lmcnatt <85642387+lucymcnatt@users.noreply.github.com> Date: Wed, 31 Jul 2024 11:23:58 -0400 Subject: [PATCH 29/29] progress --- .../dsde/workbench/leonardo/JsonCodec.scala | 2 +- .../workbench/leonardo/kubernetesModels.scala | 12 +++-- .../leonardo/dao/HttpJupyterDAO.scala | 1 + .../workbench/leonardo/db/AppComponent.scala | 47 ++++++++----------- 4 files changed, 30 insertions(+), 32 deletions(-) diff --git a/core/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/JsonCodec.scala b/core/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/JsonCodec.scala index c2386a52507..1a63512fcf5 100644 --- a/core/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/JsonCodec.scala +++ b/core/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/JsonCodec.scala @@ -661,7 +661,7 @@ object JsonCodec { ComputeClass.stringToObject.get(s.toLowerCase).toRight(s"Invalid compute class ${s}") ) implicit val autopilotDecoder: Decoder[Autopilot] = - Decoder.forProduct4("computeClass", "cpuInMillicores", "memoryInGb", "ephemeralStorageInGb")(Autopilot.apply) + Decoder.forProduct2("computeClass", "ephemeralStorageInGb")(Autopilot.apply) implicit val locationDecoder: Decoder[Location] = Decoder.decodeString.map(Location) implicit val kubeClusterIdDecoder: Decoder[KubernetesClusterLeoId] = Decoder.decodeLong.map(KubernetesClusterLeoId) diff --git a/core/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/kubernetesModels.scala b/core/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/kubernetesModels.scala index 4cc34523479..52bf6f9497e 100644 --- a/core/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/kubernetesModels.scala +++ b/core/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/kubernetesModels.scala @@ -445,9 +445,9 @@ final case class App(id: AppId, descriptorPath: Option[Uri], extraArgs: List[String], sourceWorkspaceId: Option[WorkspaceId], - numOfReplicas: Option[Int], autodelete: Autodelete, - autopilot: Option[Autopilot], + autopilot: Boolean, + computeProfile: ComputeProfile, bucketNameToMount: Option[GcsBucketName] ) { @@ -604,7 +604,13 @@ object ComputeClass { val stringToObject = values.map(v => v.toString.toLowerCase -> v).toMap } final case class Autodelete(autodeleteEnabled: Boolean, autodeleteThreshold: Option[AutodeleteThreshold]) -final case class Autopilot(computeClass: ComputeClass, cpuInMillicores: Int, memoryInGb: Int, ephemeralStorageInGb: Int) + +final case class ComputeProfile(numOfReplicas: Option[Int], + cpuInMi: Option[Int], + memoryInGb: Option[Int], + computeClass: Option[ComputeClass], + ephemeralStorageInGb: Option[Int] +) final case class UpdateAppTableId(value: Long) extends AnyVal final case class UpdateAppJobId(value: UUID) extends AnyVal diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/HttpJupyterDAO.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/HttpJupyterDAO.scala index 6606b8300bd..ce6e93bf8b6 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/HttpJupyterDAO.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/dao/HttpJupyterDAO.scala @@ -61,6 +61,7 @@ class HttpJupyterDAO[F[_]](val runtimeDnsCache: RuntimeDnsCache[F], client: Clie Request[F]( method = Method.GET, // private def azureUri: Uri = Uri.unsafeFromString(s"https://${hostname.address()}/${path}") + // https://hostIp/runtimeName/api/status uri = x.toNotebooksUri / "api" / "status", headers = headers ) diff --git a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/db/AppComponent.scala b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/db/AppComponent.scala index 8c214d7405a..154c607ab83 100644 --- a/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/db/AppComponent.scala +++ b/http/src/main/scala/org/broadinstitute/dsde/workbench/leonardo/db/AppComponent.scala @@ -41,9 +41,9 @@ final case class AppRecord(id: AppId, descriptorPath: Option[Uri], extraArgs: Option[List[String]], sourceWorkspaceId: Option[WorkspaceId], - numOfReplicas: Option[Int], autodelete: Autodelete, - autopilot: Option[Autopilot], + autopilot: Boolean, + computeProfile: ComputeProfile, bucketNameToMount: Option[GcsBucketName] ) @@ -101,10 +101,10 @@ class AppTable(tag: Tag) extends Table[AppRecord](tag, "APP") { descriptorPath, extraArgs, sourceWorkspaceId, - numOfReplicas, // combine these values to allow tuple creation; longer than 22 elements is not allowed (autodeleteEnabled, autodeleteThreshold), - (autopilotEnabled, computeClass, cpu, memory, ephemeralStorage), + autopilotEnabled, + (numOfReplicas, cpu, memory, computeClass, ephemeralStorage), bucketNameToMount ) <> ({ case ( @@ -126,9 +126,9 @@ class AppTable(tag: Tag) extends Table[AppRecord](tag, "APP") { descriptorPath, extraArgs, sourceWorkspaceId, - numOfReplicas, autodelete, autopilot, + computeProfile, bucketNameToMount ) => AppRecord( @@ -156,23 +156,14 @@ class AppTable(tag: Tag) extends Table[AppRecord](tag, "APP") { descriptorPath, extraArgs, sourceWorkspaceId, - numOfReplicas, Autodelete(autodelete._1, autodelete._2), - if (autopilot._1) - for { - computeClass <- autopilot._2 - cpu <- autopilot._3 - memory <- autopilot._4 - ephemeralStorage <- autopilot._5 - } yield Autopilot(computeClass, cpu, memory, ephemeralStorage) - else None, + autopilot, + ComputeProfile(computeProfile._1, computeProfile._2, computeProfile._3, computeProfile._4, computeProfile._5), bucketNameToMount ) }, { r: AppRecord => - val autopilotComputeClass = r.autopilot.map(_.computeClass) - val autopilotCpu = r.autopilot.map(_.cpuInMillicores) - val autopilotMemory = r.autopilot.map(_.memoryInGb) - val autopilotEphemeralStorage = r.autopilot.map(_.ephemeralStorageInGb) +// val autopilotComputeClass = r.autopilot.map(_.computeClass) +// val autopilotEphemeralStorage = r.autopilot.map(_.ephemeralStorageInGb) Some( ( r.id, @@ -197,10 +188,15 @@ class AppTable(tag: Tag) extends Table[AppRecord](tag, "APP") { r.descriptorPath, r.extraArgs, r.sourceWorkspaceId, - r.numOfReplicas, // combine these values to allow tuple creation; longer than 22 elements is not allowed (r.autodelete.autodeleteEnabled, r.autodelete.autodeleteThreshold), - (r.autopilot.isDefined, autopilotComputeClass, autopilotCpu, autopilotMemory, autopilotEphemeralStorage), + r.autopilot, + (r.computeProfile.numOfReplicas, + r.computeProfile.cpuInMi, + r.computeProfile.memoryInGb, + r.computeProfile.computeClass, + r.computeProfile.ephemeralStorageInGb + ), r.bucketNameToMount ) ) @@ -229,20 +225,15 @@ object appQuery extends TableQuery(new AppTable(_)) { app.googleServiceAccount, app.auditInfo, labels, - AppResources( - namespace, - disk, - services, - app.kubernetesServiceAccount - ), + AppResources(namespace, disk, services, app.kubernetesServiceAccount), errors, app.customEnvironmentVariables.getOrElse(Map.empty), app.descriptorPath, app.extraArgs.getOrElse(List.empty), app.sourceWorkspaceId, - app.numOfReplicas, app.autodelete, app.autopilot, + app.computeProfile, app.bucketNameToMount ) @@ -310,9 +301,9 @@ object appQuery extends TableQuery(new AppTable(_)) { saveApp.app.descriptorPath, if (saveApp.app.extraArgs.isEmpty) None else Some(saveApp.app.extraArgs), saveApp.app.sourceWorkspaceId, - saveApp.app.numOfReplicas, saveApp.app.autodelete, saveApp.app.autopilot, + saveApp.app.computeProfile, saveApp.app.bucketNameToMount ) appId <- appQuery returning appQuery.map(_.id) += record