From 52ad90dc4209c8f9df7fe827ebfcf60eb7a2079d Mon Sep 17 00:00:00 2001 From: CodeMan62 Date: Sun, 24 Aug 2025 21:53:53 +0530 Subject: [PATCH] add conda to Jfron modules --- registry/coder/modules/jfrog-oauth/README.md | 1 + .../modules/jfrog-oauth/conda.conf.tftpl | 6 +++++ .../coder/modules/jfrog-oauth/main.test.ts | 24 ++++++++++++++++++ registry/coder/modules/jfrog-oauth/main.tf | 8 ++++++ registry/coder/modules/jfrog-oauth/run.sh | 13 ++++++++++ registry/coder/modules/jfrog-token/README.md | 12 ++++++--- .../modules/jfrog-token/conda.conf.tftpl | 6 +++++ .../coder/modules/jfrog-token/main.test.ts | 25 +++++++++++++++++++ registry/coder/modules/jfrog-token/main.tf | 8 ++++++ registry/coder/modules/jfrog-token/run.sh | 13 ++++++++++ 10 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 registry/coder/modules/jfrog-oauth/conda.conf.tftpl create mode 100644 registry/coder/modules/jfrog-token/conda.conf.tftpl diff --git a/registry/coder/modules/jfrog-oauth/README.md b/registry/coder/modules/jfrog-oauth/README.md index 5d149832f..b29996c82 100644 --- a/registry/coder/modules/jfrog-oauth/README.md +++ b/registry/coder/modules/jfrog-oauth/README.md @@ -26,6 +26,7 @@ module "jfrog" { go = ["go", "another-go-repo"] pypi = ["pypi", "extra-index-pypi"] docker = ["example-docker-staging.jfrog.io", "example-docker-production.jfrog.io"] + conda = ["conda", "conda-local"] } } ``` diff --git a/registry/coder/modules/jfrog-oauth/conda.conf.tftpl b/registry/coder/modules/jfrog-oauth/conda.conf.tftpl new file mode 100644 index 000000000..7d9ea6737 --- /dev/null +++ b/registry/coder/modules/jfrog-oauth/conda.conf.tftpl @@ -0,0 +1,6 @@ +channels: +%{ for REPO in REPOS ~} + - https://${ARTIFACTORY_USERNAME}:${ARTIFACTORY_ACCESS_TOKEN}@${JFROG_HOST}/artifactory/api/conda/${REPO} +%{ endfor ~} + - defaults +ssl_verify: true diff --git a/registry/coder/modules/jfrog-oauth/main.test.ts b/registry/coder/modules/jfrog-oauth/main.test.ts index 20ace6971..093f34c36 100644 --- a/registry/coder/modules/jfrog-oauth/main.test.ts +++ b/registry/coder/modules/jfrog-oauth/main.test.ts @@ -126,4 +126,28 @@ EOF`; 'if [ -z "YES" ]; then\n not_configured go', ); }); + + it("generates a conda config with multiple repos", async () => { + const state = await runTerraformApply(import.meta.dir, { + agent_id: "some-agent-id", + jfrog_url: fakeFrogUrl, + package_managers: JSON.stringify({ + conda: ["conda-main", "conda-secondary", "conda-local"], + }), + }); + const coderScript = findResourceInstance(state, "coder_script"); + const condaStanza = `cat << EOF > ~/.condarc +channels: + - https://${user}:@${fakeFrogApi}/conda/conda-main + - https://${user}:@${fakeFrogApi}/conda/conda-secondary + - https://${user}:@${fakeFrogApi}/conda/conda-local + - defaults +ssl_verify: true + +EOF`; + expect(coderScript.script).toContain(condaStanza); + expect(coderScript.script).toContain( + 'if [ -z "YES" ]; then\n not_configured conda', + ); + }); }); diff --git a/registry/coder/modules/jfrog-oauth/main.tf b/registry/coder/modules/jfrog-oauth/main.tf index 0bc22568b..ad7dbfdb1 100644 --- a/registry/coder/modules/jfrog-oauth/main.tf +++ b/registry/coder/modules/jfrog-oauth/main.tf @@ -58,6 +58,7 @@ variable "package_managers" { go = optional(list(string), []) pypi = optional(list(string), []) docker = optional(list(string), []) + conda = optional(list(string), []) }) description = <<-EOF A map of package manager names to their respective artifactory repositories. Unused package managers can be omitted. @@ -67,6 +68,7 @@ variable "package_managers" { go = ["YOUR_GO_REPO_KEY", "ANOTHER_GO_REPO_KEY"] pypi = ["YOUR_PYPI_REPO_KEY", "ANOTHER_PYPI_REPO_KEY"] docker = ["YOUR_DOCKER_REPO_KEY", "ANOTHER_DOCKER_REPO_KEY"] + conda = ["YOUR_CONDA_REPO_KEY", "ANOTHER_CONDA_REPO_KEY"] } EOF } @@ -98,6 +100,9 @@ locals { pip_conf = templatefile( "${path.module}/pip.conf.tftpl", merge(local.common_values, { REPOS = var.package_managers.pypi }) ) + conda_conf = templatefile( + "${path.module}/conda.conf.tftpl", merge(local.common_values, { REPOS = var.package_managers.conda }) + ) } data "coder_workspace" "me" {} @@ -125,6 +130,9 @@ resource "coder_script" "jfrog" { REPOSITORY_PYPI = try(element(var.package_managers.pypi, 0), "") HAS_DOCKER = length(var.package_managers.docker) == 0 ? "" : "YES" REGISTER_DOCKER = join("\n", formatlist("register_docker \"%s\"", var.package_managers.docker)) + HAS_CONDA = length(var.package_managers.conda) == 0 ? "" : "YES" + CONDA_CONF = local.conda_conf + REPOSITORY_CONDA = try(element(var.package_managers.conda, 0), "") } )) run_on_start = true diff --git a/registry/coder/modules/jfrog-oauth/run.sh b/registry/coder/modules/jfrog-oauth/run.sh index 7d36e47c7..38b041885 100644 --- a/registry/coder/modules/jfrog-oauth/run.sh +++ b/registry/coder/modules/jfrog-oauth/run.sh @@ -81,6 +81,19 @@ else fi fi +# Configure conda to use the Artifactory "conda" repository. +if [ -z "${HAS_CONDA}" ]; then + not_configured conda +else + echo "🐍 Configuring conda..." + # Create conda config directory if it doesn't exist + mkdir -p ~/.conda + cat << EOF > ~/.condarc +${CONDA_CONF} +EOF + config_complete +fi + # Install the JFrog vscode extension for code-server. if [ "${CONFIGURE_CODE_SERVER}" == "true" ]; then while ! [ -x /tmp/code-server/bin/code-server ]; do diff --git a/registry/coder/modules/jfrog-token/README.md b/registry/coder/modules/jfrog-token/README.md index 4eb4fe103..dad8ed3c3 100644 --- a/registry/coder/modules/jfrog-token/README.md +++ b/registry/coder/modules/jfrog-token/README.md @@ -22,6 +22,7 @@ module "jfrog" { go = ["go", "another-go-repo"] pypi = ["pypi", "extra-index-pypi"] docker = ["example-docker-staging.jfrog.io", "example-docker-production.jfrog.io"] + conda = ["conda", "conda-local"] } } ``` @@ -45,25 +46,28 @@ module "jfrog" { jfrog_url = "https://YYYY.jfrog.io" artifactory_access_token = var.artifactory_access_token # An admin access token package_managers = { - npm = ["npm-local"] - go = ["go-local"] - pypi = ["pypi-local"] + npm = ["npm-local"] + go = ["go-local"] + pypi = ["pypi-local"] + conda = ["conda-local"] } } ``` -You should now be able to install packages from Artifactory using both the `jf npm`, `jf go`, `jf pip` and `npm`, `go`, `pip` commands. +You should now be able to install packages from Artifactory using both the `jf npm`, `jf go`, `jf pip` and `npm`, `go`, `pip`, `conda` commands. ```shell jf npm install prettier jf go get github.com/golang/example/hello jf pip install requests +conda install numpy ``` ```shell npm install prettier go get github.com/golang/example/hello pip install requests +conda install numpy ``` ### Configure code-server with JFrog extension diff --git a/registry/coder/modules/jfrog-token/conda.conf.tftpl b/registry/coder/modules/jfrog-token/conda.conf.tftpl new file mode 100644 index 000000000..7d9ea6737 --- /dev/null +++ b/registry/coder/modules/jfrog-token/conda.conf.tftpl @@ -0,0 +1,6 @@ +channels: +%{ for REPO in REPOS ~} + - https://${ARTIFACTORY_USERNAME}:${ARTIFACTORY_ACCESS_TOKEN}@${JFROG_HOST}/artifactory/api/conda/${REPO} +%{ endfor ~} + - defaults +ssl_verify: true diff --git a/registry/coder/modules/jfrog-token/main.test.ts b/registry/coder/modules/jfrog-token/main.test.ts index 4aeaba35d..58d32a055 100644 --- a/registry/coder/modules/jfrog-token/main.test.ts +++ b/registry/coder/modules/jfrog-token/main.test.ts @@ -162,4 +162,29 @@ EOF`; 'if [ -z "YES" ]; then\n not_configured go', ); }); + + it("generates a conda config with multiple repos", async () => { + const state = await runTerraformApply(import.meta.dir, { + agent_id: "some-agent-id", + jfrog_url: fakeFrogUrl, + artifactory_access_token: "XXXX", + package_managers: JSON.stringify({ + conda: ["conda-main", "conda-secondary", "conda-local"], + }), + }); + const coderScript = findResourceInstance(state, "coder_script"); + const condaStanza = `cat << EOF > ~/.condarc +channels: + - https://${user}:${token}@${fakeFrogApi}/conda/conda-main + - https://${user}:${token}@${fakeFrogApi}/conda/conda-secondary + - https://${user}:${token}@${fakeFrogApi}/conda/conda-local + - defaults +ssl_verify: true + +EOF`; + expect(coderScript.script).toContain(condaStanza); + expect(coderScript.script).toContain( + 'if [ -z "YES" ]; then\n not_configured conda', + ); + }); }); diff --git a/registry/coder/modules/jfrog-token/main.tf b/registry/coder/modules/jfrog-token/main.tf index 720e2d8c1..227220772 100644 --- a/registry/coder/modules/jfrog-token/main.tf +++ b/registry/coder/modules/jfrog-token/main.tf @@ -91,6 +91,7 @@ variable "package_managers" { go = optional(list(string), []) pypi = optional(list(string), []) docker = optional(list(string), []) + conda = optional(list(string), []) }) description = <<-EOF A map of package manager names to their respective artifactory repositories. Unused package managers can be omitted. @@ -100,6 +101,7 @@ variable "package_managers" { go = ["YOUR_GO_REPO_KEY", "ANOTHER_GO_REPO_KEY"] pypi = ["YOUR_PYPI_REPO_KEY", "ANOTHER_PYPI_REPO_KEY"] docker = ["YOUR_DOCKER_REPO_KEY", "ANOTHER_DOCKER_REPO_KEY"] + conda = ["YOUR_CONDA_REPO_KEY", "ANOTHER_CONDA_REPO_KEY"] } EOF } @@ -131,6 +133,9 @@ locals { pip_conf = templatefile( "${path.module}/pip.conf.tftpl", merge(local.common_values, { REPOS = var.package_managers.pypi }) ) + conda_conf = templatefile( + "${path.module}/conda.conf.tftpl", merge(local.common_values, { REPOS = var.package_managers.conda }) + ) } # Configure the Artifactory provider @@ -171,6 +176,9 @@ resource "coder_script" "jfrog" { REPOSITORY_PYPI = try(element(var.package_managers.pypi, 0), "") HAS_DOCKER = length(var.package_managers.docker) == 0 ? "" : "YES" REGISTER_DOCKER = join("\n", formatlist("register_docker \"%s\"", var.package_managers.docker)) + HAS_CONDA = length(var.package_managers.conda) == 0 ? "" : "YES" + CONDA_CONF = local.conda_conf + REPOSITORY_CONDA = try(element(var.package_managers.conda, 0), "") } )) run_on_start = true diff --git a/registry/coder/modules/jfrog-token/run.sh b/registry/coder/modules/jfrog-token/run.sh index d3a1a74c3..5f6e59c4a 100644 --- a/registry/coder/modules/jfrog-token/run.sh +++ b/registry/coder/modules/jfrog-token/run.sh @@ -80,6 +80,19 @@ else fi fi +# Configure conda to use the Artifactory "conda" repository. +if [ -z "${HAS_CONDA}" ]; then + not_configured conda +else + echo "🐍 Configuring conda..." + # Create conda config directory if it doesn't exist + mkdir -p ~/.conda + cat << EOF > ~/.condarc +${CONDA_CONF} +EOF + config_complete +fi + # Install the JFrog vscode extension for code-server. if [ "${CONFIGURE_CODE_SERVER}" == "true" ]; then while ! [ -x /tmp/code-server/bin/code-server ]; do