Skip to content

Commit 233d9dd

Browse files
authored
Merge pull request #163 from openshift-cherrypick-robot/cherry-pick-158-to-oadp-1.6
[oadp-1.6] Redesign download server UI and add Konflux Containerfile
2 parents 55ece75 + 088024f commit 233d9dd

File tree

5 files changed

+534
-25
lines changed

5 files changed

+534
-25
lines changed

Containerfile.download

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,13 @@ COPY . .
1515

1616
RUN make release-archives && \
1717
mkdir -p /archives && \
18-
mv *.tar.gz /archives/
18+
mv *.tar.gz *.sha256 /archives/ && \
19+
rm -rf /root/.cache/go-build /tmp/* release-build/
1920

2021
# Build the download server for the TARGET platform (the arch this container will run on)
21-
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o download-server ./cmd/downloads/server.go
22-
23-
# Clean up to reduce layer size
24-
RUN go clean -cache -modcache -testcache && \
25-
rm -rf /root/.cache/go-build && \
26-
rm -rf /go/pkg
22+
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o download-server ./cmd/downloads/ && \
23+
go clean -cache -modcache -testcache && \
24+
rm -rf /root/.cache/go-build /go/pkg
2725

2826
FROM registry.access.redhat.com/ubi9/ubi-minimal:latest
2927

cmd/downloads/server.go

Lines changed: 79 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,56 @@
11
package main
22

33
import (
4+
"embed"
45
"fmt"
6+
"html/template"
7+
"io/fs"
58
"log"
69
"net/http"
710
"os"
811
"path/filepath"
912
"strings"
1013
)
1114

12-
const (
13-
archiveDir = "/archives"
14-
port = "8080"
15+
//go:embed templates/*.html
16+
var templateFS embed.FS
17+
18+
//go:embed static/*
19+
var staticFS embed.FS
20+
21+
var (
22+
archiveDir = getEnv("ARCHIVE_DIR", "/archives")
23+
port = getEnv("PORT", "8080")
24+
pageTemplate = template.Must(template.ParseFS(templateFS, "templates/index.html"))
1525
)
1626

27+
func getEnv(key, fallback string) string {
28+
if v := os.Getenv(key); v != "" {
29+
return v
30+
}
31+
return fallback
32+
}
33+
34+
type archiveFile struct {
35+
Name string
36+
Size float64
37+
OS string
38+
Arch string
39+
Checksum string
40+
}
41+
1742
func main() {
18-
// Verify archives exist
1943
files, err := filepath.Glob(filepath.Join(archiveDir, "*.tar.gz"))
2044
if err != nil || len(files) == 0 {
2145
log.Fatal("No archives found in ", archiveDir)
2246
}
2347
log.Printf("Found %d archives", len(files))
2448

49+
staticContent, err := fs.Sub(staticFS, "static")
50+
if err != nil {
51+
log.Fatal("Failed to load static files: ", err)
52+
}
53+
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(staticContent))))
2554
http.HandleFunc("/", listBinaries)
2655
http.HandleFunc("/download/", downloadBinary)
2756

@@ -40,40 +69,72 @@ func listBinaries(w http.ResponseWriter, r *http.Request) {
4069
return
4170
}
4271

43-
w.Header().Set("Content-Type", "text/html")
44-
fmt.Fprintf(w, "<html><head><title>kubectl-oadp Downloads</title></head><body>")
45-
fmt.Fprintf(w, "<h1>kubectl-oadp Binary Downloads</h1>")
46-
fmt.Fprintf(w, "<p>Download pre-built binaries for your platform:</p><ul>")
47-
72+
var linuxFiles, darwinFiles, windowsFiles []archiveFile
4873
for _, file := range files {
4974
name := filepath.Base(file)
5075
info, err := os.Stat(file)
5176
if err != nil {
5277
continue
5378
}
54-
size := float64(info.Size()) / (1024 * 1024) // MB
55-
fmt.Fprintf(w, `<li><a href="/download/%s">%s</a> (%.2f MB)</li>`, name, name, size)
79+
size := float64(info.Size()) / (1024 * 1024)
80+
osName, arch := parsePlatform(name)
81+
checksum := readChecksum(file + ".sha256")
82+
af := archiveFile{Name: name, Size: size, OS: osName, Arch: arch, Checksum: checksum}
83+
switch osName {
84+
case "linux":
85+
linuxFiles = append(linuxFiles, af)
86+
case "darwin":
87+
darwinFiles = append(darwinFiles, af)
88+
case "windows":
89+
windowsFiles = append(windowsFiles, af)
90+
default:
91+
linuxFiles = append(linuxFiles, af)
92+
}
5693
}
5794

58-
fmt.Fprintf(w, "</ul>")
59-
fmt.Fprintf(w, "<h3>Installation:</h3>")
60-
fmt.Fprintf(w, "<pre>tar -xzf kubectl-oadp_*.tar.gz\n")
61-
fmt.Fprintf(w, "chmod +x kubectl-oadp\n")
62-
fmt.Fprintf(w, "sudo mv kubectl-oadp /usr/local/bin/</pre>")
95+
data := struct {
96+
LinuxFiles []archiveFile
97+
DarwinFiles []archiveFile
98+
WindowsFiles []archiveFile
99+
}{linuxFiles, darwinFiles, windowsFiles}
100+
101+
w.Header().Set("Content-Type", "text/html")
102+
if err := pageTemplate.Execute(w, data); err != nil {
103+
log.Printf("Template error: %v", err)
104+
}
105+
}
106+
107+
func readChecksum(path string) string {
108+
data, err := os.ReadFile(path)
109+
if err != nil {
110+
return ""
111+
}
112+
fields := strings.Fields(string(data))
113+
if len(fields) > 0 {
114+
return fields[0]
115+
}
116+
return ""
117+
}
118+
119+
func parsePlatform(filename string) (string, string) {
120+
name := strings.TrimSuffix(filename, ".tar.gz")
121+
parts := strings.Split(name, "_")
122+
if len(parts) >= 3 {
123+
return parts[len(parts)-2], parts[len(parts)-1]
124+
}
125+
return "unknown", "unknown"
63126
}
64127

65128
func downloadBinary(w http.ResponseWriter, r *http.Request) {
66129
filename := filepath.Base(r.URL.Path[len("/download/"):])
67130

68-
// Security: ensure filename is just the archive name
69131
if filepath.Dir(filename) != "." || !strings.HasSuffix(filename, ".tar.gz") {
70132
http.Error(w, "Invalid filename", http.StatusBadRequest)
71133
return
72134
}
73135

74136
filePath := filepath.Join(archiveDir, filename)
75137

76-
// Verify file exists
77138
if _, err := os.Stat(filePath); os.IsNotExist(err) {
78139
http.Error(w, "Archive not found", http.StatusNotFound)
79140
return

0 commit comments

Comments
 (0)