Skip to content

Redesign download server UI and add Konflux Containerfile#158

Merged
Joeavaikath merged 5 commits intomigtools:oadp-devfrom
Joeavaikath:download-server-updates
Mar 19, 2026
Merged

Redesign download server UI and add Konflux Containerfile#158
Joeavaikath merged 5 commits intomigtools:oadp-devfrom
Joeavaikath:download-server-updates

Conversation

@Joeavaikath
Copy link
Contributor

@Joeavaikath Joeavaikath commented Mar 17, 2026

Summary

  • Redesign the download server page with templated HTML, separated CSS,
    and official Red Hat brand colors
  • Group downloads by OS (Linux/macOS/Windows) in table layout with
    architecture badges, SHA256 checksums (click to copy), and per-command
    copy buttons
  • Extract inline HTML into Go html/template with embed.FS for both
    templates and static assets
  • Optimize Containerfile.download to clean build cache within RUN steps
    and include .sha256 checksum files
  • Add konflux.Containerfile.download for hermetic downstream builds
    (FIPS-compliant, Hermeto-prefetched dependencies)

Test plan

  • Build container image: podman build -f Containerfile.download -t oadp-cli-binaries .
  • Run locally: ARCHIVE_DIR=cmd/downloads/test-archives go run ./cmd/downloads/
  • Verify download page at localhost:8080 renders correctly with OS grouping
  • Verify SHA256 checksums display and click-to-copy works
  • Verify copy buttons on install commands work
  • Verify download links serve archives correctly

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Platform-organized downloads page (Linux, macOS, Windows) with binary listings, SHA256 checksums, copy-to-clipboard for checksums and install commands, per-item downloads, and refreshed styling and responsive UI.
  • Chores

    • Added a self-contained build/runtime image for the download server and consolidated build/cleanup steps to remove build artifacts and temporary files during packaging.

Replace inline HTML with Go html/template and separated CSS using
embed.FS. Group downloads by OS (Linux/macOS/Windows) in table
layout with architecture badges, SHA256 checksums (click to copy),
and per-command copy buttons. Use official Red Hat brand colors.

Also optimize Containerfile to clean build cache within RUN steps
and include .sha256 checksum files in the image.

Signed-off-by: Joseph <jvaikath@redhat.com>
Uses the OSBS golang builder with FIPS-compliant build flags
(CGO_ENABLED=1, strictfipsruntime). Dependencies are prefetched
by the Konflux pipeline via Hermeto, so no go mod download is
needed. Includes Red Hat metadata labels and license copy.

Signed-off-by: Joseph <jvaikath@redhat.com>
@openshift-ci openshift-ci bot requested review from kaovilai and mpryc March 17, 2026 18:22
@coderabbitai
Copy link

coderabbitai bot commented Mar 17, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 28b312e0-0383-407a-bd82-2bd94b568bc9

📥 Commits

Reviewing files that changed from the base of the PR and between 89ed878 and 51c301b.

📒 Files selected for processing (1)
  • cmd/downloads/templates/index.html
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmd/downloads/templates/index.html

📝 Walkthrough

Walkthrough

Adds a hermetic, multi-stage container build and a templated download server: embeds static assets and CSS, catalogs platform-specific release archives with SHA256 checksums, serves index and downloads, and produces a UBI9 runtime image with archives and a non-root download-server binary. (≤50 words)

Changes

Cohort / File(s) Summary
Container build files
Containerfile.download, konflux.Containerfile.download
New/updated multi-stage Containerfiles: build release archives for all platforms, place *.tar.gz and corresponding *.sha256 into /archives, build download-server from ./cmd/downloads/, run go clean and extra cleanup (/root/.cache/go-build, /go/pkg, /tmp/*, release-build/), and produce a UBI9 runtime image with OpenSSL/tzdata, non-root user, port and labels.
Server implementation
cmd/downloads/server.go
Reworked HTTP server: embedded templates and static FS, archiveFile model, platform parsing (linux/darwin/windows), checksum reading, env vars (ARCHIVE_DIR, PORT), static /static/ route, template-based index rendering, and improved logging/error handling.
Frontend assets
cmd/downloads/templates/index.html, cmd/downloads/static/style.css
Adds HTML template for per-OS file lists, copy-to-clipboard UX for checksums and install commands, and a new CSS stylesheet implementing layout, branding, and responsive table/UI styles.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Server
    participant FS as Archive_FileSystem
    participant Template as Template_Renderer
    participant Static as Static_Assets

    Client->>Server: GET /
    Server->>FS: List files in /archives
    Server->>FS: Read `*.sha256` checksums
    Server->>Server: Parse platforms & build archiveFile collections
    Server->>Template: Render index.html with categorized files
    Template-->>Server: HTML
    Server-->>Client: 200 OK + HTML
    Client->>Static: GET /static/style.css
    Static-->>Client: CSS
    Client->>Server: GET /download/{archive}
    Server->>FS: Stream archive file
    FS-->>Client: Archive bytes
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hopped through builds and tidy stacks,

I paired each tar with its checksum tracks,
Templates sewn and styles applied,
Archives lined up, doors opened wide,
Click to fetch — a joyful hop, no hacks!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the two main changes: redesigning the download server UI and adding a Konflux Containerfile, which aligns with the substantial changes across multiple files.
Description check ✅ Passed The description includes a comprehensive summary of changes and a detailed test plan with specific commands and verification steps, but lacks a dedicated 'Why the changes were made' section explaining the motivation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Joeavaikath
Copy link
Contributor Author

/cherry-pick release-1.6

@openshift-cherrypick-robot

@Joeavaikath: once the present PR merges, I will cherry-pick it on top of release-1.6 in a new PR and assign it to you.

Details

In response to this:

/cherry-pick release-1.6

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
konflux.Containerfile.download (1)

5-5: Pin immutable base images in the hermetic variant.

Floating tags, especially registry.redhat.io/ubi9/ubi:latest, make repeated builds resolve different base layers over time, which works against the stated hermetic goal. Please pin digests here, or document where Konflux resolves and locks them before build.

Also applies to: 24-24

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@konflux.Containerfile.download` at line 5, The FROM line uses a floating tag
for the hermetic builder image ("FROM
brew.registry.redhat.io/rh-osbs/openshift-golang-builder:rhel_9_golang_1.24");
update this to pin the image to an immutable digest (sha256) or add
documentation pointing to where Konflux resolves and locks the digest before
builds. Locate the FROM statement in the Containerfile (the builder stage) and
replace the tag with the corresponding image@sha256:<digest> OR add a short
comment and/or README note explaining the digest-resolution/locking process and
where artifacts storing the locked digests live so hermetic builds are
reproducible.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@cmd/downloads/server.go`:
- Around line 80-92: The switch on osName in the loop that builds archiveFile
entries (using parsePlatform, readChecksum and archiveFile) silently defaults
unknown OS values into linuxFiles; change this so unknown/malformed results are
not misclassified: detect when parsePlatform returns an unexpected osName and
either skip adding the archiveFile and log a warning (including the filename and
osName) or append it to a new unknownFiles slice for later inspection instead of
falling through to the linuxFiles case; update the switch/default to perform the
skip/log or push to unknownFiles and ensure any callers that expected only
linux/darwin/windows handle the new behavior.

In `@cmd/downloads/templates/index.html`:
- Line 38: The template currently shows only a checksum prefix and attaches copy
behavior to a non-interactive span; update the markup to render the full SHA256
string in the DOM (use {{.Checksum}} instead of {{slice .Checksum 0 16}}...),
replace the clickable span with a real button (e.g. class "copy-checksum" or
similar) that uses navigator.clipboard.writeText(this.dataset.checksum) or reads
the full checksum from a data-checksum attribute, include an accessible
label/aria-label like "Copy full checksum" and keep the visible short display
handled via CSS if you want truncation, and apply this same change for the other
occurrences referenced (lines 66 and 94) so keyboard users and manual
verification can access the complete digest.
- Around line 103-133: Replace the hard-coded POSIX install block in the
template with OS- and client-specific blocks: detect the OS/template variable
and render a Linux/macOS section that keeps the tar/chmod/mv commands (replace
static strings like "tar -xzf kubectl-oadp_*.tar.gz", "chmod +x kubectl-oadp",
"sudo mv kubectl-oadp /usr/local/bin/") and a Windows section that uses
zip/unzip or .exe guidance and PATH instructions instead of POSIX commands;
update the final verification line so it is neutral or client-aware (use
"kubectl-oadp --help" by default and render "oc oadp --help" only when the oc
client is the advertised artifact) and ensure the copy buttons' data-cmd values
and onclick="copyCmd(this)" targets are set per-platform/command.

---

Nitpick comments:
In `@konflux.Containerfile.download`:
- Line 5: The FROM line uses a floating tag for the hermetic builder image
("FROM
brew.registry.redhat.io/rh-osbs/openshift-golang-builder:rhel_9_golang_1.24");
update this to pin the image to an immutable digest (sha256) or add
documentation pointing to where Konflux resolves and locks the digest before
builds. Locate the FROM statement in the Containerfile (the builder stage) and
replace the tag with the corresponding image@sha256:<digest> OR add a short
comment and/or README note explaining the digest-resolution/locking process and
where artifacts storing the locked digests live so hermetic builds are
reproducible.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 25cfad9b-e61b-41b2-a54f-6b8bb4f632fa

📥 Commits

Reviewing files that changed from the base of the PR and between 55ece75 and 05310b9.

📒 Files selected for processing (5)
  • Containerfile.download
  • cmd/downloads/server.go
  • cmd/downloads/static/style.css
  • cmd/downloads/templates/index.html
  • konflux.Containerfile.download

mpryc
mpryc previously approved these changes Mar 17, 2026
@mpryc
Copy link
Contributor

mpryc commented Mar 17, 2026

/lgtm

Add RHEL technology icon (Red RGB) and Windows logo SVGs to static
assets. Update section headers to use img tags with proper sizing
instead of Unicode emoji characters.

Signed-off-by: Joseph <jvaikath@redhat.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
cmd/downloads/static/style.css (1)

48-58: Consider contrast for subtitle and binary-note text.

The reduced-opacity white text (rgba(255,255,255,0.8) and rgba(255,255,255,0.65)) on the red header may fall below WCAG AA contrast ratio (4.5:1), especially the .binary-note at 0.8rem font size. If accessibility compliance is required, consider increasing opacity or using solid white.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/downloads/static/style.css` around lines 48 - 58, The translucent white
text colors for .subtitle (rgba(255,255,255,0.8)) and .binary-note
(rgba(255,255,255,0.65)) may not meet WCAG AA contrast on the red header; update
the CSS rules for .subtitle and .binary-note to use higher-contrast color values
(e.g., increase opacity to 1.0 or switch to solid `#ffffff`) or adjust
font-size/weight for .binary-note so the computed contrast ratio meets at least
4.5:1 (verify with a contrast checker) while keeping the selectors .subtitle and
.binary-note unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@cmd/downloads/static/style.css`:
- Around line 169-183: Add accessible keyboard focus styles for interactive
selectors by adding corresponding :focus and/or :focus-visible rules that mirror
the :hover visual feedback and provide a clear visible indicator (e.g., outline
or focus ring and/or matching background change). Update the CSS for
.download-btn, .copy-btn, .logo-link, and .footer a to include these focus
selectors (or a shared utility focus style) so keyboard users see focus; prefer
using :focus-visible to avoid showing the ring on mouse interactions and ensure
contrast and thickness are sufficient for visibility.

---

Nitpick comments:
In `@cmd/downloads/static/style.css`:
- Around line 48-58: The translucent white text colors for .subtitle
(rgba(255,255,255,0.8)) and .binary-note (rgba(255,255,255,0.65)) may not meet
WCAG AA contrast on the red header; update the CSS rules for .subtitle and
.binary-note to use higher-contrast color values (e.g., increase opacity to 1.0
or switch to solid `#ffffff`) or adjust font-size/weight for .binary-note so the
computed contrast ratio meets at least 4.5:1 (verify with a contrast checker)
while keeping the selectors .subtitle and .binary-note unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a36d214d-5baa-4326-b92a-5dd7da62976a

📥 Commits

Reviewing files that changed from the base of the PR and between 05310b9 and 3981ec4.

⛔ Files ignored due to path filters (2)
  • cmd/downloads/static/rhel-icon.svg is excluded by !**/*.svg
  • cmd/downloads/static/windows-logo.svg is excluded by !**/*.svg
📒 Files selected for processing (2)
  • cmd/downloads/static/style.css
  • cmd/downloads/templates/index.html
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmd/downloads/templates/index.html

@kaovilai
Copy link
Member

/cherry-pick oadp-1.6

@openshift-cherrypick-robot

@kaovilai: once the present PR merges, I will cherry-pick it on top of oadp-1.6 in a new PR and assign it to you.

Details

In response to this:

/cherry-pick oadp-1.6

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

Signed-off-by: Joseph <jvaikath@redhat.com>
@kaovilai
Copy link
Member

/lgtm

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
konflux.Containerfile.download (2)

24-24: Consider pinning base image for reproducible builds.

Using ubi9/ubi:latest may produce different images over time as the latest tag is updated. For a hermetic/reproducible Konflux build, consider pinning to a specific version tag (e.g., ubi9/ubi:9.4) or using a digest reference.

♻️ Suggested change
-FROM registry.redhat.io/ubi9/ubi:latest
+FROM registry.redhat.io/ubi9/ubi:9.4

Or use a digest for maximum reproducibility:

FROM registry.redhat.io/ubi9/ubi@sha256:<specific-digest>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@konflux.Containerfile.download` at line 24, The Docker base image in the
Containerfile currently uses an unpinned tag "FROM
registry.redhat.io/ubi9/ubi:latest"; change this to a specific, immutable
reference to ensure reproducible builds by replacing the ":latest" tag with a
concrete version tag (e.g., ":9.4") or, even better, a digest reference
("@sha256:<digest>") so the FROM line in the Containerfile always resolves to
the exact same image.

26-26: Consider simplifying package installation.

The reinstall tzdata approach works but could be replaced with a simpler install command. If tzdata is already in the base image, installing it again is a no-op; if it's missing, install will add it.

♻️ Optional simplification
-RUN dnf -y install openssl && dnf -y reinstall tzdata && dnf clean all
+RUN dnf -y install openssl tzdata && dnf clean all
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@konflux.Containerfile.download` at line 26, Replace the RUN line that
currently uses "dnf -y reinstall tzdata" with a simpler install invocation:
change "RUN dnf -y install openssl && dnf -y reinstall tzdata && dnf clean all"
to use "dnf -y install tzdata" (or combine into a single install command such as
"dnf -y install openssl tzdata && dnf clean all"); update the command containing
"dnf -y reinstall tzdata" so tzdata is installed if missing and avoids an
unnecessary reinstall when present.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@konflux.Containerfile.download`:
- Line 24: The Docker base image in the Containerfile currently uses an unpinned
tag "FROM registry.redhat.io/ubi9/ubi:latest"; change this to a specific,
immutable reference to ensure reproducible builds by replacing the ":latest" tag
with a concrete version tag (e.g., ":9.4") or, even better, a digest reference
("@sha256:<digest>") so the FROM line in the Containerfile always resolves to
the exact same image.
- Line 26: Replace the RUN line that currently uses "dnf -y reinstall tzdata"
with a simpler install invocation: change "RUN dnf -y install openssl && dnf -y
reinstall tzdata && dnf clean all" to use "dnf -y install tzdata" (or combine
into a single install command such as "dnf -y install openssl tzdata && dnf
clean all"); update the command containing "dnf -y reinstall tzdata" so tzdata
is installed if missing and avoids an unnecessary reinstall when present.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3d0ac5eb-c69f-4068-bc9f-4df78802fa5b

📥 Commits

Reviewing files that changed from the base of the PR and between 3981ec4 and 89ed878.

📒 Files selected for processing (1)
  • konflux.Containerfile.download

kaovilai
kaovilai previously approved these changes Mar 18, 2026
Replace icon+label section headers with plain text labels:
"Download for Linux & Unix", "Download for macOS", and
"Download for Windows". Delete unused rhel-icon.svg and
windows-logo.svg assets.

Signed-off-by: Joseph <jvaikath@redhat.com>
@openshift-ci openshift-ci bot removed the lgtm label Mar 19, 2026
@mpryc
Copy link
Contributor

mpryc commented Mar 19, 2026

/lgtm

@openshift-ci openshift-ci bot added the lgtm label Mar 19, 2026
@mpryc
Copy link
Contributor

mpryc commented Mar 19, 2026

/cherry-pick oadp-1.6

@openshift-cherrypick-robot

@mpryc: once the present PR merges, I will cherry-pick it on top of oadp-1.6 in a new PR and assign it to you.

Details

In response to this:

/cherry-pick oadp-1.6

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@openshift-ci
Copy link

openshift-ci bot commented Mar 19, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Joeavaikath, kaovilai, mpryc

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:
  • OWNERS [Joeavaikath,kaovilai,mpryc]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@Joeavaikath Joeavaikath merged commit 7d8bf8e into migtools:oadp-dev Mar 19, 2026
17 checks passed
@openshift-cherrypick-robot

@mpryc: new pull request created: #163

Details

In response to this:

/cherry-pick oadp-1.6

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@openshift-cherrypick-robot

@Joeavaikath: cannot checkout release-1.6: error checking out "release-1.6": exit status 1 error: pathspec 'release-1.6' did not match any file(s) known to git

Details

In response to this:

/cherry-pick release-1.6

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants