mattcasters opened a new issue, #8722:
URL: https://github.com/apache/hop/issues/8722

   ### What would you like to happen?
   
   Ran command: `find . -name "load-and-execute.sh" -o -name "Dockerfile*"`
   Viewed load-and-execute.sh:1-200
   Ran command: `git grep -i "marketplace" | grep -i "apply"`
   Ran command: `find plugins/misc/marketplace -type f -name "*Command*.java" 
-o -name "*Cli*.java"`
   Viewed MarketplaceCommand.java:1-150
   Viewed MarketplaceCommand.java:151-300
   Viewed MarketplaceCommand.java:301-450
   Viewed MarketplaceCommand.java:451-600
   Viewed MarketplaceCommand.java:630-750
   Viewed load-and-execute.sh:200-368
   Viewed HopInstallSpec.java:1-95
   Viewed HopInstallSpecLoader.java:1-100
   Ran command: `ls -la /home/matt/git/ProjectDataHopper/hopper-edw/`
   Viewed hop-marketplace-repo.yaml:1-65
   Ran command: `git grep -n "driver install"`
   Viewed run-web.sh:30-85
   Viewed docker-container.adoc:400-460
   Ran command: `find plugins/misc/marketplace/ -name "PluginInstaller.java" -o 
-name "PluginDiscovery.java" -o -name "MarketplaceConfig.java"`
   Viewed PluginInstaller.java:50-120
   Viewed PluginInstaller.java:121-200
   Viewed MarketplaceConfig.java:1-100
   Viewed MarketplaceRepository.java:1-100
   Ran command: `git grep "HOP_MARKETPLACE"`
   Viewed MarketplaceRepositoryDefinition.java:1-100
   Viewed PluginInstaller.java:195-250
   Viewed DriverInstallCommand.java:1-100
   Viewed PluginDiscovery.java:50-120
   Viewed PluginDiscovery.java:121-200
   Viewed MavenRepositoryClient.java:1-100
   Viewed MarketplaceCommand.java:725-760
   Viewed MarketplaceConfig.java:110-160
   Viewed MarketplaceConfig.java:161-210
   Viewed MarketplaceConfig.java:211-260
   
   Here is a structured feature request proposal to make installing marketplace 
plugins in the `apache/hop` Docker container seamless and declarative via 
environment variables.
   
   ---
   
   # Feature Request: Add Marketplace Plugin Auto-Installation to `apache/hop` 
Docker Container
   
   ## 1. Problem Statement & Motivation
   
   When deploying Apache Hop in containerized environments (Kubernetes, Docker 
Compose, Airflow, CI/CD runners), pipelines frequently require plugins hosted 
in corporate artifactories (JFrog Artifactory, Sonatype Nexus, AWS 
CodeArtifact) or community repositories (such as Project Data Hopper’s Nexus at 
`https://repository.data-hopper.com/repository/hop-community-plugins/`).
   
   Currently, installing a custom plugin in the standard `apache/hop` container 
requires one of the following:
   1. **Building a custom Docker image** inheriting from `apache/hop`, 
defeating the convenience of using standard official images with mounted 
projects.
   2. **Writing a custom entrypoint script** 
(`HOP_CUSTOM_ENTRYPOINT_EXTENSION_SHELL_FILE_PATH`).
   3. **Using indirect repository specs**: e.g., running `hop marketplace apply 
-f <spec-url>` or `hop marketplace repo import <yaml-url>`.
   
   As seen with specifications like `hop-marketplace-repo.yaml`, these files 
contain extensive catalog and GUI metadata (`kind`, `browse: true`, 
`categories`, `description`, `homepage`, `minHopVersion`, `installPath`). In 
the context of a headless runtime container, **all that extra metadata is 
unnecessary**. The container runtime only needs to know:
   - **Which plugin(s)** to install (coordinates / artifact IDs).
   - **Where** to fetch them (the Maven/Artifactory repository base URL).
   - **Credentials** (if the artifactory requires authentication).
   
   Apache Hop already has an established precedent for JDBC drivers: 
[`HOP_DRIVERS_DOWNLOAD`](file:///home/matt/git/mattcasters/hop/docker/resources/load-and-execute.sh#L32-L76)
 and `HOP_DRIVERS_MAVEN_REPO`. We should provide an equivalent mechanism for 
marketplace plugins.
   
   ---
   
   ## 2. Proposed Container Environment Variables
   
   Following the convention established by `HOP_DRIVERS_*`:
   
   | Environment Variable | Description | Example |
   | :--- | :--- | :--- |
   | **`HOP_PLUGINS_DOWNLOAD`** | Comma-separated list of plugin coordinates to 
install before Hop starts. Supports short names, `artifactId`, 
`artifactId:version`, or `groupId:artifactId:version`. | 
`hopper-edw:0.10.0`<br>`org.hopper:hopper-edw:0.10.0,hop-tech-parquet` |
   | **`HOP_PLUGINS_MAVEN_REPO`** | Optional corporate Artifactory / Nexus base 
Maven repository URL. If omitted, uses the default Hop marketplace repositories 
(ASF & Central). | 
`https://repository.data-hopper.com/repository/hop-community-plugins/`<br>`https://artifactory.corp/artifactory/hop-plugins/`
 |
   | **`HOP_PLUGINS_REPO_ID`** | Optional identifier for the repository in Hop 
configuration (default: `corporate-repo`). | `data-hopper-community` |
   | **`HOP_PLUGINS_REPO_AUTH_TYPE`** | Optional authentication type: `auto` 
(default), `basic`, or `token`. | `basic`, `token` |
   | **`HOP_PLUGINS_REPO_USERNAME`** | Optional username for authenticated 
repositories (can also fall back to `HOP_MARKETPLACE_USERNAME`). | 
`svc-hop-runner` |
   | **`HOP_PLUGINS_REPO_PASSWORD`** | Optional password or bearer token (can 
also fall back to `HOP_MARKETPLACE_PASSWORD`). | `${ARTIFACTORY_TOKEN}` |
   
   *(Optional declarative fallback)*:
   - **`HOP_PLUGINS_ENV_FILE`**: If a team *does* already have a `hop-env.yaml` 
or `hop-marketplace-repo.yaml` available via HTTP(S) or local volume, setting 
this variable could trigger `hop marketplace apply -f 
"${HOP_PLUGINS_ENV_FILE}"`.
   
   ---
   
   ## 3. Implementation in Container Scripts
   
   Both 
[`load-and-execute.sh`](file:///home/matt/git/mattcasters/hop/docker/resources/load-and-execute.sh)
 and 
[`run-web.sh`](file:///home/matt/git/mattcasters/hop/docker/resources/run-web.sh)
 would add a helper function `install_marketplace_plugins` that executes before 
Hop starts (alongside `install_jdbc_drivers`).
   
   ### Proposed Function: `install_marketplace_plugins()`
   
   ```bash
   # Download Marketplace plugins on container start, before Hop is launched.
   # Driven by environment variables:
   #   HOP_PLUGINS_DOWNLOAD          comma-separated plugin coordinates:
   #                                 e.g. 
"hopper-edw:0.10.0,org.apache.hop:hop-tech-parquet:2.19.0"
   #   HOP_PLUGINS_MAVEN_REPO        optional Maven/Artifactory repository base 
URL
   #   HOP_PLUGINS_REPO_ID           optional repository ID (default: 
"corporate-repo")
   #   HOP_PLUGINS_REPO_USERNAME     optional username for the repository
   #   HOP_PLUGINS_REPO_PASSWORD     optional password / token for the 
repository
   #   HOP_PLUGINS_REPO_AUTH_TYPE    optional auth type: auto (default), basic, 
token
   #   HOP_PLUGINS_ENV_FILE          optional URL or path to a hop-env.yaml / 
hop-marketplace-repo.yaml
   install_marketplace_plugins() {
     local plugins="${HOP_PLUGINS_DOWNLOAD:-}"
     local env_file="${HOP_PLUGINS_ENV_FILE:-}"
   
     # 1. Alternative: Apply full install spec if specified
     if [ -n "${env_file}" ]; then
       log "Applying Hop marketplace environment file: ${env_file}"
       if ! "${DEPLOYMENT_PATH}"/hop marketplace apply -f "${env_file}"; then
         log "Error: failed to apply marketplace environment file '${env_file}'"
         exitWithCode 8
       fi
     fi
   
     if [ -z "${plugins}" ]; then
       return 0
     fi
   
     local repo_url="${HOP_PLUGINS_MAVEN_REPO:-}"
     local repo_id="${HOP_PLUGINS_REPO_ID:-corporate-repo}"
   
     # 2. Register repository if a custom URL is provided
     if [ -n "${repo_url}" ]; then
       log "Configuring marketplace repository '${repo_id}' (${repo_url})"
       local repo_args=("--id=${repo_id}" "--url=${repo_url}" "--primary")
       [ -n "${HOP_PLUGINS_REPO_USERNAME:-}" ]  && 
repo_args+=("--username=${HOP_PLUGINS_REPO_USERNAME}")
       [ -n "${HOP_PLUGINS_REPO_PASSWORD:-}" ]  && 
repo_args+=("--password=${HOP_PLUGINS_REPO_PASSWORD}")
       [ -n "${HOP_PLUGINS_REPO_AUTH_TYPE:-}" ] && 
repo_args+=("--auth-type=${HOP_PLUGINS_REPO_AUTH_TYPE}")
   
       # Register in hop-config.json (or update if already exists)
       if ! "${DEPLOYMENT_PATH}"/hop marketplace repo add "${repo_args[@]}"; 
then
         log "Warning: failed to add repository '${repo_id}' (may already 
exist, proceeding to install)"
       fi
     fi
   
     # 3. Install each requested plugin
     log "Installing marketplace plugins: ${plugins}"
     local spec
     for spec in ${plugins//,/ }; do
       spec="$(echo "${spec}" | tr -d '[:space:]')"
       [ -z "${spec}" ] && continue
   
       log "Installing marketplace plugin '${spec}'"
       local install_args=("${spec}")
       if [ -n "${repo_url}" ]; then
         install_args+=("--repo=${repo_id}")
       fi
   
       # shellcheck disable=SC2086
       if ! "${DEPLOYMENT_PATH}"/hop marketplace install "${install_args[@]}"; 
then
         log "Error: failed to install marketplace plugin '${spec}'"
         exitWithCode 8
       fi
     done
   }
   ```
   
   ### Execution Location
   
   In 
[`load-and-execute.sh`](file:///home/matt/git/mattcasters/hop/docker/resources/load-and-execute.sh#L158-L160):
   ```bash
   # Download requested JDBC drivers (HOP_DRIVERS_DOWNLOAD) before Hop starts.
   install_jdbc_drivers
   
   # Download requested Marketplace plugins (HOP_PLUGINS_DOWNLOAD) before Hop 
starts.
   install_marketplace_plugins
   ```
   
   ---
   
   ## 4. Complementary CLI Improvement: Add `--repo-url` to `hop marketplace 
install`
   
   In 
[`MarketplaceCommand.java`](file:///home/matt/git/mattcasters/hop/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java#L156-L161):
   - Currently, `hop marketplace install` only accepts `--repo <repo-id>`, 
which requires the repository to be registered beforehand in `hop-config.json`.
   - In contrast, 
[`DriverInstallCommand.java`](file:///home/matt/git/mattcasters/hop/engine/src/main/java/org/apache/hop/driver/DriverInstallCommand.java#L69-L71)
 accepts `--repo <url>` (a direct repository URL).
   
   **Suggestion for Marketplace CLI**:
   Add an option `--repo-url <url>` to `hop marketplace install` (or permit 
passing a full URL to `--repo`).
   When `--repo-url` is passed:
   ```shell
   hop marketplace install org.hopper:hopper-edw:0.10.0 --repo-url 
https://repository.data-hopper.com/repository/hop-community-plugins/
   ```
   The installer uses an ad-hoc, in-memory `MarketplaceRepository` directly 
without needing a separate `repo add` step in `hop-config.json`. This makes 
marketplace plugin installation completely stateless.
   
   ---
   
   ## 5. Usage Examples
   
   ### Example 1: Installing Data Hopper EDW from community repository
   ```bash
   docker run -it --rm \
     --env HOP_PLUGINS_DOWNLOAD="org.hopper:hopper-edw:0.10.0" \
     --env 
HOP_PLUGINS_MAVEN_REPO="https://repository.data-hopper.com/repository/hop-community-plugins/";
 \
     --env HOP_PROJECT_FOLDER=/project \
     --env HOP_PROJECT_NAME=edw-project \
     --env HOP_RUN_CONFIG=local \
     --env HOP_FILE_PATH='${PROJECT_HOME}/load_data_vault.hpl' \
     --mount type=bind,source=/path/to/project,target=/project \
     apache/hop:latest
   ```
   
   ### Example 2: Installing multiple plugins from an authenticated corporate 
Artifactory
   ```bash
   docker run -it --rm \
     --env 
HOP_PLUGINS_DOWNLOAD="com.mycorp:custom-pipeline-transform:1.4.0,org.hopper:hopper-edw:0.10.0"
 \
     --env 
HOP_PLUGINS_MAVEN_REPO="https://artifactory.mycompany.corp/artifactory/hop-plugins-release/";
 \
     --env HOP_PLUGINS_REPO_USERNAME="ci-runner" \
     --env HOP_PLUGINS_REPO_PASSWORD="${ARTIFACTORY_TOKEN}" \
     --env HOP_PLUGINS_REPO_AUTH_TYPE="token" \
     --env HOP_PROJECT_FOLDER=/project \
     --env HOP_PROJECT_NAME=etl \
     --env HOP_FILE_PATH='${PROJECT_HOME}/main.hwf' \
     --env HOP_RUN_CONFIG=local \
     --mount type=bind,source=/opt/etl,target=/project \
     apache/hop:latest
   ```
   
   ---
   
   ## 6. Documentation Section
   
   Add a new section `Downloading Marketplace Plugins` in 
[`docker-container.adoc`](file:///home/matt/git/mattcasters/hop/docs/hop-user-manual/modules/ROOT/pages/docker-container.adoc)
 directly following the `Downloading JDBC drivers` section, documenting:
   1. The `HOP_PLUGINS_DOWNLOAD` and `HOP_PLUGINS_MAVEN_REPO` variables.
   2. Coordinate formats (`groupId:artifactId:version`, `artifactId:version`, 
and short names).
   3. Authentication parameters for private repositories.
   
   ### Issue Priority
   
   Priority: 2
   
   ### Issue Component
   
   Component: Containers, Component: Marketplace


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to