Skip to content

Add KSP CLI and Crossplane CLI to toolbox image#21

Open
Copilot wants to merge 28 commits intomainfrom
copilot/update-dockerfile-for-ksp-cli
Open

Add KSP CLI and Crossplane CLI to toolbox image#21
Copilot wants to merge 28 commits intomainfrom
copilot/update-dockerfile-for-ksp-cli

Conversation

Copy link

Copilot AI commented Jan 13, 2026

Summary: Add KSP CLI and Crossplane CLI to Dockerfile

  • Explore repository structure and understand Dockerfile pattern
  • Add KSP_VERSION ARG at the top of Dockerfile (set to pr-2-dd2ede1)
  • Add KSP CLI stage to pull from GHCR
  • Add COPY command to extract KSP CLI binary from GHCR image
  • Add CROSSPLANE_VERSION ARG (set to 2.1.3)
  • Add Crossplane CLI download from official releases (positioned after KSP CLI)
  • Create symlink from crossplane to crank for command compatibility
  • Add KSP_VERSION and CROSSPLANE_VERSION ARG to all build stages
  • Add version checks for KSP CLI and Crossplane CLI
  • Validate Crossplane installation with "crossplane version" command
  • Fix missing closing quote for VAULT_VERSION ARG
  • Fix cryptography package conflict with --ignore-installed flag
  • Dockerfile syntax validated successfully
  • Code review completed
  • Security checks completed

Changes Made

This PR adds the KubestackPlus CLI (KSP) and Crossplane CLI to the ztp-pipeline-toolbox Docker image.

Modified Files

  • Dockerfile: Added KSP CLI via GHCR multi-stage build, Crossplane CLI via direct download, and fixed cryptography conflict

Key Changes

  1. Added KSP_VERSION="pr-2-dd2ede1" ARG in toolchain versioning section
  2. Added CROSSPLANE_VERSION="2.1.3" ARG in toolchain versioning section
  3. Added KSP CLI stage: New build stage that pulls from ghcr.io/stakater/kubestackplus-cli:${KSP_VERSION}
  4. Multi-stage build for KSP: Uses COPY --from to extract the binary from the GHCR image
  5. Added Crossplane CLI download: Downloads crank binary from official Crossplane releases, positioned AFTER KSP CLI download
  6. Created crossplane symlink: Added symlink from crossplane to crank to support both command names
  7. Added version ARGs to all build stages (binary_downloader, base-image, final image)
  8. Added version verification checks for both KSP CLI and Crossplane CLI
  9. Crossplane validation: Uses crossplane version command to validate installation
  10. Fixed missing closing quote on VAULT_VERSION (line 20)
  11. Fixed cryptography conflict: Added --ignore-installed cryptography flag to prevent pip from trying to uninstall system package

Download and Extraction Logic

KSP CLI (from GHCR):

######################################################### KSP-CLI ######################################################
FROM ghcr.io/stakater/kubestackplus-cli:${KSP_VERSION} as ksp_cli

######################################################### BINARY-DOWNLOADER ############################################
FROM alpine as binary_downloader
...
#download KSP CLI from GHCR
COPY --from=ksp_cli /usr/local/bin/ksp /root/download/binaries/ksp

Crossplane CLI (from official releases, installed AFTER KSP CLI):

#download crossplane CLI
RUN if [[ ! -z ${CROSSPLANE_VERSION} ]] ; then \
      wget -q "https://releases.crossplane.io/stable/v${CROSSPLANE_VERSION}/bin/linux_${TARGETARCH}/crank" -O /root/download/crank && \
      mv "/root/download/crank" "/root/download/binaries/crank" && \
      ln -s /root/download/binaries/crank /root/download/binaries/crossplane; \
    fi

The implementation:

  • KSP CLI: Pulls the KSP CLI container image from GHCR (ghcr.io/stakater/kubestackplus-cli:pr-2-dd2ede1) and copies the binary from /usr/local/bin/ksp
  • Crossplane CLI: Downloads the crank binary (v2.1.3) directly from official Crossplane releases, positioned AFTER KSP CLI in the Dockerfile
  • Symlink for compatibility: Creates a symlink from crossplane to crank so both commands work
  • Both binaries are placed in /root/download/binaries/ for inclusion in the final image
  • Supports authentication via Docker registry credentials if needed (for KSP CLI)
  • Supports multi-architecture builds (amd64, arm64) for both CLIs
  • Follows multi-stage build pattern for clean separation

Build Fix

  1. Cryptography conflict: Added --ignore-installed cryptography flag to the pip install command. While cryptography was removed from the explicit install list, it's still installed as a dependency of pyOpenSSL, kubernetes, or openshift. The flag tells pip to ignore the system-installed version and install the dependency without trying to uninstall it.

  2. Crossplane validation: Uses crossplane version command for validation, with a symlink ensuring both command names work correctly.

Security Summary

No security vulnerabilities identified. CodeQL analysis completed with no findings.

Original prompt

In the provided repository, the Dockerfile located at @stakater/ztp-pipeline-toolbox/files/Dockerfile needs to be updated to include the installation of the KSP CLI (KubestackPlus CLI). The KSP CLI should be downloaded from its latest release, which can be found at https://github.com/stakater-ab/kubestackplus-cli/releases/tag/v1.8.0. Ensure that the KSP CLI binary is correctly downloaded and added to the binaries directory so it is accessible during runtime, adhering to the existing binary downloaing and usage philosophy of the repository.

This pull request was created from Copilot chat.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Co-authored-by: TehreemNisa <10060877+TehreemNisa@users.noreply.github.com>
Copilot AI changed the title [WIP] Update Dockerfile to install KSP CLI Add KSP CLI v1.8.0 to toolbox image Jan 13, 2026
Copilot AI requested a review from TehreemNisa January 13, 2026 14:07
@TehreemNisa
Copy link

@copilot when i unzip the ksp cli this is the path it is available on

tehreem@tehreem-ThinkPad-E16-Gen-2:$ cd ksp
tehreem@tehreem-ThinkPad-E16-Gen-2:
/ksp$ ls
ksp_linux_x86_64 ksp_linux_x86_64.tar.gz
tehreem@tehreem-ThinkPad-E16-Gen-2:/ksp$ cd ksp_linux_x86_64/
tehreem@tehreem-ThinkPad-E16-Gen-2:
/ksp/ksp_linux_x86_64$ ls
bin README.md
tehreem@tehreem-ThinkPad-E16-Gen-2:/ksp/ksp_linux_x86_64$ cd bin
tehreem@tehreem-ThinkPad-E16-Gen-2:
/ksp/ksp_linux_x86_64/bin$ ls
linux_amd64
tehreem@tehreem-ThinkPad-E16-Gen-2:/ksp/ksp_linux_x86_64/bin$ cd linux_amd64/
tehreem@tehreem-ThinkPad-E16-Gen-2:
/ksp/ksp_linux_x86_64/bin/linux_amd64$ ls
ksp
tehreem@tehreem-ThinkPad-E16-Gen-2:/ksp/ksp_linux_x86_64/bin/linux_amd64$ pwd
/home/tehreem/ksp/ksp_linux_x86_64/bin/linux_amd64
tehreem@tehreem-ThinkPad-E16-Gen-2:
/ksp/ksp_linux_x86_64/bin/linux_amd64$ ls
ksp
tehreem@tehreem-ThinkPad-E16-Gen-2:~/ksp/ksp_linux_x86_64/bin/linux_amd64$

Co-authored-by: TehreemNisa <10060877+TehreemNisa@users.noreply.github.com>
Copy link
Author

Copilot AI commented Jan 14, 2026

@copilot when i unzip the ksp cli this is the path it is available on

tehreem@tehreem-ThinkPad-E16-Gen-2:~$ cd ksp...

Updated in commit 18d7364. The KSP CLI download now properly handles the tar.gz extraction and uses the correct nested path ksp_linux_<arch>/bin/linux_<targetarch>/ksp. Also added architecture mapping for amd64x86_64 and arm64aarch64 to match the release file naming.

Co-authored-by: TehreemNisa <10060877+TehreemNisa@users.noreply.github.com>
@TehreemNisa
Copy link

@copilot > [binary_downloader 16/16] RUN if [[ ! -z 1.8.0 ]] ; then if [ "amd64" = "amd64" ]; then ARCH="x86_64"; elif [ "amd64" = "arm64" ]; then ARCH="aarch64"; else ARCH="amd64"; fi && wget -q https://github.com/stakater-ab/kubestackplus-cli/releases/download/v1.8.0/ksp_linux_${ARCH}.tar.gz && tar -xzf ksp_linux_${ARCH}.tar.gz && mv ksp_linux_${ARCH}/bin/linux_amd64/ksp /root/download/binaries/ksp && rm -rf ksp_linux_${ARCH}.tar.gz ksp_linux_${ARCH}; fi:

Dockerfile:131

130 | #download KSP CLI
131 | >>> RUN if [[ ! -z ${KSP_VERSION} ]] ; then
132 | >>> if [ "${TARGETARCH}" = "amd64" ]; then
133 | >>> ARCH="x86_64";
134 | >>> elif [ "${TARGETARCH}" = "arm64" ]; then
135 | >>> ARCH="aarch64";
136 | >>> else
137 | >>> ARCH="${TARGETARCH}";
138 | >>> fi &&
139 | >>> wget -q https://github.com/stakater-ab/kubestackplus-cli/releases/download/v${KSP_VERSION}/ksp_linux_${ARCH}.tar.gz &&
140 | >>> tar -xzf ksp_linux_${ARCH}.tar.gz &&
141 | >>> mv ksp_linux_${ARCH}/bin/linux_${TARGETARCH}/ksp /root/download/binaries/ksp &&
142 | >>> rm -rf ksp_linux_${ARCH}.tar.gz ksp_linux_${ARCH};
143 | >>> fi
144 |

ERROR: failed to build: failed to solve: process "/bin/sh -c if [[ ! -z ${KSP_VERSION} ]] ; then if [ "${TARGETARCH}" = "amd64" ]; then ARCH="x86_64"; elif [ "${TARGETARCH}" = "arm64" ]; then ARCH="aarch64"; else ARCH="${TARGETARCH}"; fi && wget -q https://github.com/stakater-ab/kubestackplus-cli/releases/download/v${KSP_VERSION}/ksp_linux_${ARCH}.tar.gz && tar -xzf ksp_linux_${ARCH}.tar.gz && mv ksp_linux_${ARCH}/bin/linux_${TARGETARCH}/ksp /root/download/binaries/ksp && rm -rf ksp_linux_${ARCH}.tar.gz ksp_linux_${ARCH}; fi" did not complete successfully: exit code: 8
Reference
Check build summary support
Error: buildx failed with: ERROR: failed to build: failed to solve: process "/bin/sh -c if [[ ! -z ${KSP_VERSION} ]] ; then if [ "${TARGETARCH}" = "amd64" ]; then ARCH="x86_64"; elif [ "${TARGETARCH}" = "arm64" ]; then ARCH="aarch64"; else ARCH="${TARGETARCH}"; fi && wget -q https://github.com/stakater-ab/kubestackplus-cli/releases/download/v${KSP_VERSION}/ksp_linux_${ARCH}.tar.gz && tar -xzf ksp_linux_${ARCH}.tar.gz && mv ksp_linux_${ARCH}/bin/linux_${TARGETARCH}/ksp /root/download/binaries/ksp && rm -rf ksp_linux_${ARCH}.tar.gz ksp_linux_${ARCH}; fi" did not complete successfully: exit code: 8

Copy link
Author

Copilot AI commented Jan 16, 2026

@copilot > [binary_downloader 16/16] RUN if [[ ! -z 1.8.0 ]] ; then if [ "amd64" = "amd64" ]; then ARCH="x86_64"; elif [ "amd64" = "arm64" ]; then ARCH="aarch64"; els...

The build is failing because the KSP CLI release at https://github.com/stakater-ab/kubestackplus-cli/releases/download/v1.8.0/ksp_linux_x86_64.tar.gz returns a 404 error. It appears the repository is private or the release assets aren't publicly accessible.

Could you confirm:

  1. Is the stakater-ab/kubestackplus-cli repository private?
  2. If so, where should the Dockerfile download the KSP CLI from? (e.g., a public mirror, different repository, or should we use GitHub token authentication?)
  3. Or should the binaries be included in this repository instead?

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/stakater-ab/kubestackplus-cli/releases/tags/v1.8.0
    • Triggering command: /usr/bin/curl curl -sL REDACTED (http block)

If you need me to access, download, or install something from one of these locations, you can either:

@TehreemNisa
Copy link

@copilot can I add authentication to download ksp cli?

Copy link
Author

Copilot AI commented Jan 16, 2026

@copilot can I add authentication to download ksp cli?

Yes, you can add authentication. Here are the options:

Option 1: Build-time secret (recommended)
Use Docker BuildKit secrets to pass GitHub token at build time without exposing it in the image:

# Add --mount=secret for wget
RUN --mount=type=secret,id=github_token \
    if [[ ! -z ${KSP_VERSION} ]] ; then \
      TOKEN=$(cat /run/secrets/github_token) && \
      # ... architecture logic ... \
      wget -q --header="Authorization: token ${TOKEN}" \
        https://github.com/stakater-ab/kubestackplus-cli/releases/download/v${KSP_VERSION}/ksp_linux_${ARCH}.tar.gz && \
      # ... rest of commands ...

Build with: docker build --secret id=github_token,src=token.txt .

Option 2: Use GitHub Container Registry
If KSP CLI is published to GHCR, you can authenticate during build with registry credentials.

Option 3: Pre-download to public location
Host the KSP CLI binaries in a public location (S3, GHCR public, etc.) and download from there.

Which approach would you prefer?

@TehreemNisa
Copy link

@copilot yes it is published to ghcr

Copy link
Author

Copilot AI commented Jan 16, 2026

@copilot yes it is published to ghcr

Perfect! To update the Dockerfile to use GHCR, I need the specific image details. Could you provide:

  1. The GHCR image URL (e.g., ghcr.io/stakater-ab/kubestackplus-cli:v1.8.0 or similar)
  2. Does the GHCR package contain the binary directly, or is it still a tar.gz that needs extraction?
  3. Is the package public or does it require authentication?

Once I have these details, I'll update the download logic accordingly.

@TehreemNisa
Copy link

@copilot ghcr.io/stakater/kubestackplus-cli:pr-2-dd2ede1

Co-authored-by: TehreemNisa <10060877+TehreemNisa@users.noreply.github.com>
Copy link
Author

Copilot AI commented Jan 16, 2026

@copilot ghcr.io/stakater/kubestackplus-cli:pr-2-dd2ede1

Updated in commit 7d61a74. The Dockerfile now uses a multi-stage build to pull the KSP CLI from GHCR (ghcr.io/stakater/kubestackplus-cli:pr-2-dd2ede1) and copies the binary from /usr/local/bin/ksp to the binaries directory. This approach is cleaner and supports Docker registry authentication if needed.

@TehreemNisa
Copy link

@copilot install crossplane cli after ksp cli and also check at end by running command "crossplane version" to validate installation

…rsion

Co-authored-by: TehreemNisa <10060877+TehreemNisa@users.noreply.github.com>
Copy link
Author

Copilot AI commented Jan 22, 2026

@copilot install crossplane cli after ksp cli and also check at end by running command "crossplane version" to validate installation

Done in commit 9421097. The Crossplane CLI is now installed after KSP CLI and validated using the crossplane version command. I also created a symlink from crossplane to crank so both command names work, since the actual binary downloaded is named crank but you requested validation with crossplane version.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • releases.crossplane.io
    • Triggering command: /usr/bin/wget wget --spider REDACTED (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@github-actions
Copy link

@TehreemNisa Image is available for testing. docker pull ghcr.io/stakater/ztp-pipeline-toolbox:SNAPSHOT-PR-21-a62c4095

Removed version check for CROSSPLANE_VERSION in Dockerfile.
@github-actions
Copy link

@TehreemNisa Image is available for testing. docker pull ghcr.io/stakater/ztp-pipeline-toolbox:SNAPSHOT-PR-21-9d1913d2

@TehreemNisa TehreemNisa marked this pull request as ready for review January 22, 2026 19:18
@github-actions
Copy link

@TehreemNisa Image is available for testing. docker pull ghcr.io/stakater/ztp-pipeline-toolbox:SNAPSHOT-PR-21-e6b68f7c

@TehreemNisa
Copy link

@copilot Also install podman cli in this image

Co-authored-by: TehreemNisa <10060877+TehreemNisa@users.noreply.github.com>
Copy link
Author

Copilot AI commented Jan 26, 2026

@copilot Also install podman cli in this image

Done in commit b4014e0. Added Podman CLI v5.3.1 to the Dockerfile. The podman binary (podman-remote-static) is downloaded from official Podman releases and validated with podman --version. It's positioned after Crossplane CLI and supports multi-architecture builds (amd64, arm64).

Copilot AI changed the title Add KSP CLI and Crossplane CLI to toolbox image Add KSP CLI, Crossplane CLI, and Podman CLI to toolbox image Jan 26, 2026
Copilot AI requested a review from TehreemNisa January 26, 2026 18:29
@TehreemNisa
Copy link

@copilot revert the podman commit that you did , I dont need podman cli

Co-authored-by: TehreemNisa <10060877+TehreemNisa@users.noreply.github.com>
Copy link
Author

Copilot AI commented Jan 26, 2026

@copilot revert the podman commit that you did , I dont need podman cli

Done in commit f6c2b10. Reverted the Podman CLI installation - all Podman-related changes have been removed from the Dockerfile.

Copilot AI changed the title Add KSP CLI, Crossplane CLI, and Podman CLI to toolbox image Add KSP CLI and Crossplane CLI to toolbox image Jan 26, 2026
@github-actions
Copy link

@TehreemNisa Image is available for testing. docker pull ghcr.io/stakater/ztp-pipeline-toolbox:SNAPSHOT-PR-21-99dd587c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants