diff --git a/registry/AJ0070/.images/avtar.jpeg b/registry/AJ0070/.images/avtar.jpeg new file mode 100644 index 00000000..d47bfb80 Binary files /dev/null and b/registry/AJ0070/.images/avtar.jpeg differ diff --git a/registry/AJ0070/README.md b/registry/AJ0070/README.md new file mode 100644 index 00000000..fefac11f --- /dev/null +++ b/registry/AJ0070/README.md @@ -0,0 +1,7 @@ +--- +display_name: Jash +bio: Coder user and contributor. +github: AJ0070 +avatar: ./.images/avatar.png +status: community +--- diff --git a/registry/AJ0070/modules/pgadmin/README.md b/registry/AJ0070/modules/pgadmin/README.md new file mode 100644 index 00000000..397e11f2 --- /dev/null +++ b/registry/AJ0070/modules/pgadmin/README.md @@ -0,0 +1,23 @@ +--- +display_name: "pgAdmin" +description: "A web-based interface for managing PostgreSQL databases in your Coder workspace." +icon: "../../../../.icons/postgres.svg" +maintainer_github: "AJ0070" +verified: false +tags: ["database", "postgres", "pgadmin", "web-ide"] +--- + +# pgAdmin + +This module adds a pgAdmin app to your Coder workspace, providing a powerful web-based interface for managing PostgreSQL databases. + +It can be served on a Coder subdomain for easy access, or on `localhost` if you prefer to use port-forwarding. + +```tf +module "pgadmin" { + count = data.coder_workspace.me.start_count + source = "registry.coder.com/AJ0070/pgadmin/coder" + version = "1.0.0" + agent_id = coder_agent.example.id +} +``` diff --git a/registry/AJ0070/modules/pgadmin/main.test.ts b/registry/AJ0070/modules/pgadmin/main.test.ts new file mode 100644 index 00000000..71626375 --- /dev/null +++ b/registry/AJ0070/modules/pgadmin/main.test.ts @@ -0,0 +1,10 @@ +import { describe } from "bun:test"; +import { runTerraformInit, testRequiredVariables } from "~test"; + +describe("pgadmin", async () => { + await runTerraformInit(import.meta.dir); + + testRequiredVariables(import.meta.dir, { + agent_id: "foo", + }); +}); \ No newline at end of file diff --git a/registry/AJ0070/modules/pgadmin/main.tf b/registry/AJ0070/modules/pgadmin/main.tf new file mode 100644 index 00000000..b111c871 --- /dev/null +++ b/registry/AJ0070/modules/pgadmin/main.tf @@ -0,0 +1,108 @@ +terraform { + required_providers { + coder = { + source = "coder/coder" + } + } +} + +variable "agent_id" { + type = string + description = "The agent to install pgAdmin on." +} + +variable "port" { + type = number + description = "The port to run pgAdmin on." + default = 5050 +} + +variable "subdomain" { + type = bool + description = "If true, the app will be served on a subdomain." + default = true +} + +variable "config" { + type = any + description = "A map of pgAdmin configuration settings." + default = { + DEFAULT_EMAIL = "admin@coder.com" + DEFAULT_PASSWORD = "coderPASSWORD" + SERVER_MODE = false + MASTER_PASSWORD_REQUIRED = false + LISTEN_ADDRESS = "127.0.0.1" + } +} + +data "coder_workspace" "me" {} +data "coder_workspace_owner" "me" {} + +resource "coder_app" "pgadmin" { + count = data.coder_workspace.me.start_count + agent_id = var.agent_id + display_name = "pgAdmin" + slug = "pgadmin" + icon = "/icon/postgres.svg" + url = local.url + subdomain = var.subdomain + share = "owner" + + healthcheck { + url = local.healthcheck_url + interval = 5 + threshold = 6 + } +} + +resource "coder_script" "pgadmin" { + agent_id = var.agent_id + display_name = "Install and run pgAdmin" + icon = "/icon/postgres.svg" + run_on_start = true + script = templatefile("${path.module}/run.sh", { + PORT = var.port, + LOG_PATH = "/tmp/pgadmin.log", + SERVER_BASE_PATH = local.server_base_path, + CONFIG = local.config_content, + PGADMIN_DATA_DIR = local.pgadmin_data_dir, + PGADMIN_LOG_DIR = local.pgadmin_log_dir, + PGADMIN_VENV_DIR = local.pgadmin_venv_dir + }) +} + +locals { + server_base_path = var.subdomain ? "" : format("/@%s/%s/apps/%s", data.coder_workspace_owner.me.name, data.coder_workspace.me.name, "pgadmin") + url = "http://localhost:${var.port}${local.server_base_path}" + healthcheck_url = "http://localhost:${var.port}${local.server_base_path}/" + + # pgAdmin data directories (user-local paths) + pgadmin_data_dir = "$HOME/.pgadmin" + pgadmin_log_dir = "$HOME/.pgadmin/logs" + pgadmin_venv_dir = "$HOME/.pgadmin/venv" + + base_config = merge(var.config, { + LISTEN_PORT = var.port + # Override paths for user installation + DATA_DIR = local.pgadmin_data_dir + LOG_FILE = "${local.pgadmin_log_dir}/pgadmin4.log" + SQLITE_PATH = "${local.pgadmin_data_dir}/pgadmin4.db" + SESSION_DB_PATH = "${local.pgadmin_data_dir}/sessions" + STORAGE_DIR = "${local.pgadmin_data_dir}/storage" + # Disable initial setup prompts for automated deployment + SETUP_AUTH = false + }) + + config_with_path = var.subdomain ? local.base_config : merge(local.base_config, { + APPLICATION_ROOT = local.server_base_path + }) + + config_content = join("\n", [ + for key, value in local.config_with_path : + format("%s = %s", key, + can(regex("^(true|false)$", tostring(value))) ? (value ? "True" : "False") : + can(tonumber(value)) ? tostring(value) : + format("'%s'", tostring(value)) + ) + ]) +} \ No newline at end of file diff --git a/registry/AJ0070/modules/pgadmin/run.sh b/registry/AJ0070/modules/pgadmin/run.sh new file mode 100644 index 00000000..ee6d64ec --- /dev/null +++ b/registry/AJ0070/modules/pgadmin/run.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env bash + +set -euo pipefail + +PORT=${PORT} +LOG_PATH=${LOG_PATH} +SERVER_BASE_PATH=${SERVER_BASE_PATH} + +BOLD='\033[0;1m' + +printf "$${BOLD}Installing pgAdmin!\n" + +# Check if Python 3 is available +if ! command -v python3 > /dev/null 2>&1; then + echo "⚠️ Warning: Python 3 is not installed. Please install Python 3 before using this module." + exit 0 +fi + +# Setup pgAdmin directories (from Terraform configuration) +PGADMIN_DATA_DIR="${PGADMIN_DATA_DIR}" +PGADMIN_LOG_DIR="${PGADMIN_LOG_DIR}" +PGADMIN_VENV_DIR="${PGADMIN_VENV_DIR}" + +printf "Setting up pgAdmin directories...\n" +mkdir -p "$PGADMIN_DATA_DIR" +mkdir -p "$PGADMIN_LOG_DIR" + +# Check if pgAdmin virtual environment already exists and is working +if [ -f "$PGADMIN_VENV_DIR/bin/pgadmin4" ] && [ -f "$PGADMIN_VENV_DIR/bin/activate" ]; then + printf "🥳 pgAdmin virtual environment already exists\n\n" +else + printf "Creating Python virtual environment for pgAdmin...\n" + if ! python3 -m venv "$PGADMIN_VENV_DIR"; then + echo "⚠️ Warning: Failed to create virtual environment" + exit 0 + fi + + printf "Installing pgAdmin 4 in virtual environment...\n" + if ! "$PGADMIN_VENV_DIR/bin/pip" install pgadmin4; then + echo "⚠️ Warning: Failed to install pgAdmin4" + exit 0 + fi + + printf "🥳 pgAdmin has been installed successfully\n\n" +fi + +printf "$${BOLD}Configuring pgAdmin...\n" + +if [ -f "$PGADMIN_VENV_DIR/bin/pgadmin4" ]; then + # pgAdmin installs to a predictable location in the virtual environment + PYTHON_VERSION=$("$PGADMIN_VENV_DIR/bin/python" -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')") + PGADMIN_INSTALL_DIR="$PGADMIN_VENV_DIR/lib/python$PYTHON_VERSION/site-packages/pgadmin4" + + # Create pgAdmin config file in the correct location (next to config.py) + cat > "$PGADMIN_INSTALL_DIR/config_local.py" << EOF +# pgAdmin configuration for Coder workspace +${CONFIG} +EOF + + printf "📄 Config written to $PGADMIN_INSTALL_DIR/config_local.py\n" + + printf "$${BOLD}Starting pgAdmin in background...\n" + printf "📝 Check logs at $${LOG_PATH}\n" + printf "🌐 Serving at http://localhost:${PORT}${SERVER_BASE_PATH}\n" + + # Create required directories + mkdir -p "$PGADMIN_DATA_DIR/sessions" + mkdir -p "$PGADMIN_DATA_DIR/storage" + + # Start pgadmin4 from the virtual environment with proper environment + cd "$PGADMIN_DATA_DIR" + PYTHONPATH="$PGADMIN_INSTALL_DIR:$${PYTHONPATH:-}" "$PGADMIN_VENV_DIR/bin/pgadmin4" > "$${LOG_PATH}" 2>&1 & +else + printf "⚠️ Warning: pgAdmin4 virtual environment not found\n" + printf "📝 Installation may have failed - check logs above\n" +fi diff --git a/registry/coder/modules/filebrowser/main.test.ts b/registry/coder/modules/filebrowser/main.test.ts index 1d925c35..3d157c52 100644 --- a/registry/coder/modules/filebrowser/main.test.ts +++ b/registry/coder/modules/filebrowser/main.test.ts @@ -100,6 +100,9 @@ describe("filebrowser", async () => { "apk add bash", ); + const expectedUrl = "http://localhost:13339/@default/default/apps/filebrowser"; + const expectedLogLine = `📂 Serving /root at ${expectedUrl} `; + testBaseLine(output); }, 15000); }); diff --git a/registry/coder/modules/filebrowser/run.sh b/registry/coder/modules/filebrowser/run.sh index ea4b857a..dbeb8932 100644 --- a/registry/coder/modules/filebrowser/run.sh +++ b/registry/coder/modules/filebrowser/run.sh @@ -32,7 +32,7 @@ filebrowser config set --baseurl=${SERVER_BASE_PATH} --port=${PORT} --auth.metho printf "👷 Starting filebrowser in background... \n\n" -printf "📂 Serving $${ROOT_DIR} at http://localhost:${PORT} \n\n" +printf "📂 Serving $${ROOT_DIR} at http://localhost:${PORT}${SERVER_BASE_PATH} \n\n" filebrowser >>${LOG_PATH} 2>&1 &