Skip to content

Commit e29d414

Browse files
committed
Add argo workflow tool
Adds argo workflow tool - requested in incomplete PR #1253 which was rejected by automated code review. Additional capability was needed to work with gzipped binaries which are not also in a tar. Seems like first tool to have .gz without .tar.gz / .tgz. All tests pass. Work done by Codex, and it also ran the test tool and confirmed all architectures/OS combinations are correct. Signed-off-by: Alex Ellis (OpenFaaS Ltd) <[email protected]>
1 parent fe35b34 commit e29d414

File tree

5 files changed

+119
-6
lines changed

5 files changed

+119
-6
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,7 @@ There are 53 apps that you can install on your cluster.
774774
| [age-keygen](https://github.com/FiloSottile/age) | Key generation tool for age encryption. |
775775
| [alloy](https://github.com/grafana/alloy) | OpenTelemetry Collector distribution with programmable pipelines |
776776
| [amp](https://github.com/sourcegraph/amp) | Amp - the frontier coding agent for your terminal and editor. |
777+
| [argo](https://github.com/argoproj/argo-workflows) | Workflow Engine for Kubernetes. |
777778
| [argocd](https://github.com/argoproj/argo-cd) | Declarative, GitOps continuous delivery tool for Kubernetes. |
778779
| [argocd-autopilot](https://github.com/argoproj-labs/argocd-autopilot) | An opinionated way of installing Argo-CD and managing GitOps repositories. |
779780
| [arkade](https://github.com/alexellis/arkade) | Portable marketplace for downloading your favourite DevOps CLIs and installing helm charts, with a single command. |
@@ -882,7 +883,7 @@ There are 53 apps that you can install on your cluster.
882883
| [kubetail](https://github.com/johanhaleby/kubetail) | Bash script to tail Kubernetes logs from multiple pods at the same time. |
883884
| [kubetrim](https://github.com/alexellis/kubetrim) | Tidy up old Kubernetes clusters from kubeconfig. |
884885
| [kubeval](https://github.com/instrumenta/kubeval) | Validate your Kubernetes configuration files, supports multiple Kubernetes versions |
885-
| [kubie](https://github.com/sbstp/kubie) | A more powerful alternative to kubectx and kubens |
886+
| [kubie](https://github.com/kubie-org/kubie) | A more powerful alternative to kubectx and kubens |
886887
| [kumactl](https://github.com/kumahq/kuma) | kumactl is a CLI to interact with Kuma and its data |
887888
| [kustomize](https://github.com/kubernetes-sigs/kustomize) | Customization of kubernetes YAML configurations |
888889
| [kwok](https://github.com/kubernetes-sigs/kwok) | KWOK stands for Kubernetes WithOut Kubelet, responsible for simulating the lifecycle of fake nodes, pods, and other Kubernetes API resources |
@@ -961,7 +962,7 @@ There are 53 apps that you can install on your cluster.
961962
| [websocat](https://github.com/vi/websocat) | Command-line client for WebSockets, like netcat/socat but for WebSockets |
962963
| [yq](https://github.com/mikefarah/yq) | Portable command-line YAML processor. |
963964
| [yt-dlp](https://github.com/yt-dlp/yt-dlp) | Fork of youtube-dl with additional features and fixes |
964-
There are 193 tools, use `arkade get NAME` to download one.
965+
There are 194 tools, use `arkade get NAME` to download one.
965966
<!-- end of tool list -->
966967

967968

pkg/get/download.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package get
22

33
import (
44
"bytes"
5+
"compress/gzip"
56
"crypto/sha256"
67
"encoding/json"
78
"fmt"
@@ -814,11 +815,35 @@ func decompress(tool *Tool, downloadURL, outFilePath, operatingSystem, arch, ver
814815
if err := archive.Unzip(archiveFile, fInfo.Size(), outFilePathDir, forceQuiet); err != nil {
815816
return "", err
816817
}
818+
} else if strings.HasSuffix(downloadURL, ".gz") {
819+
if err := ungzip(archiveFile, outFilePath); err != nil {
820+
return "", err
821+
}
817822
}
818823

819824
return outFilePath, nil
820825
}
821826

827+
func ungzip(archiveFile *os.File, outFilePath string) error {
828+
gzReader, err := gzip.NewReader(archiveFile)
829+
if err != nil {
830+
return err
831+
}
832+
defer gzReader.Close()
833+
834+
out, err := os.OpenFile(outFilePath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0775)
835+
if err != nil {
836+
return err
837+
}
838+
839+
if _, err := io.Copy(out, gzReader); err != nil {
840+
out.Close()
841+
return err
842+
}
843+
844+
return out.Close()
845+
}
846+
822847
func fetchText(url string) (string, error) {
823848
return retryWithBackoff(func() (string, error) {
824849
req, err := http.NewRequest(http.MethodGet, url, nil)

pkg/get/get.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,8 @@ func isArchiveStr(downloadURL string) bool {
176176

177177
return strings.HasSuffix(downloadURL, "tar.gz") ||
178178
strings.HasSuffix(downloadURL, "zip") ||
179-
strings.HasSuffix(downloadURL, "tgz")
179+
strings.HasSuffix(downloadURL, "tgz") ||
180+
strings.HasSuffix(downloadURL, ".gz")
180181
}
181182

182183
// ResolveVersion determines the version for a tool. When version is
@@ -344,7 +345,7 @@ func getURLByGithubTemplate(tool Tool, os, arch, version string) (string, error)
344345
return "", err
345346
}
346347

347-
downloadName := strings.TrimSpace(buf.String())
348+
downloadName := sanitizeTemplateResult(buf.String())
348349

349350
return getBinaryURL(tool.Owner, tool.Repo, version, downloadName), nil
350351
}
@@ -448,7 +449,7 @@ func getByDownloadTemplate(tool Tool, os, arch, version string) (string, error)
448449
return "", err
449450
}
450451

451-
res := strings.TrimSpace(buf.String())
452+
res := sanitizeTemplateResult(buf.String())
452453
return res, nil
453454
}
454455

@@ -514,13 +515,17 @@ func GetBinaryName(tool *Tool, os, arch, version string) (string, error) {
514515
return "", err
515516
}
516517

517-
res := strings.TrimSpace(buf.String())
518+
res := sanitizeTemplateResult(buf.String())
518519
return res, nil
519520
}
520521

521522
return "", errors.New("BinaryTemplate is not set")
522523
}
523524

525+
func sanitizeTemplateResult(in string) string {
526+
return strings.Join(strings.Fields(strings.TrimSpace(in)), "")
527+
}
528+
524529
// GetDownloadURLs generates a list of URL for each tool, for download
525530
func GetDownloadURLs(tools Tools, toolArgs []string, version string) (Tools, error) {
526531
arkadeTools := []Tool{}

pkg/get/get_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,11 @@ func TestIsArchiveStr(t *testing.T) {
387387
downloadURL: "https://example.com/download.tgz",
388388
expected: true,
389389
},
390+
{
391+
description: "URL ends with '.gz'",
392+
downloadURL: "https://example.com/download.gz",
393+
expected: true,
394+
},
390395
{
391396
description: "URL does not end with any known archive extension",
392397
downloadURL: "https://example.com/download.txt",
@@ -2586,6 +2591,56 @@ func Test_DownloadArgocd(t *testing.T) {
25862591
}
25872592
}
25882593

2594+
func Test_DownloadArgo(t *testing.T) {
2595+
tools := MakeTools()
2596+
name := "argo"
2597+
version := "v4.0.1"
2598+
2599+
tool := getTool(name, tools)
2600+
2601+
tests := []test{
2602+
{
2603+
os: "ming",
2604+
arch: arch64bit,
2605+
version: version,
2606+
url: "https://github.com/argoproj/argo-workflows/releases/download/v4.0.1/argo-windows-amd64.exe.gz",
2607+
},
2608+
{
2609+
os: "linux",
2610+
arch: arch64bit,
2611+
version: version,
2612+
url: "https://github.com/argoproj/argo-workflows/releases/download/v4.0.1/argo-linux-amd64.gz",
2613+
},
2614+
{
2615+
os: "darwin",
2616+
arch: arch64bit,
2617+
version: version,
2618+
url: "https://github.com/argoproj/argo-workflows/releases/download/v4.0.1/argo-darwin-amd64.gz",
2619+
},
2620+
{
2621+
os: "darwin",
2622+
arch: archDarwinARM64,
2623+
version: version,
2624+
url: "https://github.com/argoproj/argo-workflows/releases/download/v4.0.1/argo-darwin-arm64.gz",
2625+
},
2626+
{
2627+
os: "linux",
2628+
arch: archARM64,
2629+
version: version,
2630+
url: "https://github.com/argoproj/argo-workflows/releases/download/v4.0.1/argo-linux-arm64.gz",
2631+
},
2632+
}
2633+
for _, tc := range tests {
2634+
got, _, err := tool.GetURL(tc.os, tc.arch, tc.version, false)
2635+
if err != nil {
2636+
t.Fatal(err)
2637+
}
2638+
if got != tc.url {
2639+
t.Errorf("want: %s, got: %s", tc.url, got)
2640+
}
2641+
}
2642+
}
2643+
25892644
func Test_DownloadNerdctl(t *testing.T) {
25902645
tools := MakeTools()
25912646
name := "nerdctl"

pkg/get/tools.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,6 +1785,33 @@ https://releases.hashicorp.com/{{.Name}}/{{.VersionNumber}}/{{.Name}}_{{.Version
17851785
{{.Version}}/argocd-{{$osStr}}-{{$arch}}{{$ext}}`,
17861786
})
17871787

1788+
tools = append(tools,
1789+
Tool{
1790+
Owner: "argoproj",
1791+
Repo: "argo-workflows",
1792+
Name: "argo",
1793+
Description: "Workflow Engine for Kubernetes.",
1794+
BinaryTemplate: `argo`,
1795+
URLTemplate: `
1796+
{{$arch := .Arch}}
1797+
{{- if eq .Arch "x86_64" -}}
1798+
{{$arch = "amd64"}}
1799+
{{- else if or (eq .Arch "aarch64") (eq .Arch "arm64") -}}
1800+
{{$arch = "arm64"}}
1801+
{{- end -}}
1802+
1803+
{{$osStr := ""}}
1804+
{{ if HasPrefix .OS "ming" -}}
1805+
{{$osStr = "windows"}}
1806+
{{- else if eq .OS "linux" -}}
1807+
{{$osStr = "linux"}}
1808+
{{- else if eq .OS "darwin" -}}
1809+
{{$osStr = "darwin"}}
1810+
{{- end -}}
1811+
1812+
https://github.com/{{.Owner}}/{{.Repo}}/releases/download/{{.Version}}/argo-{{$osStr}}-{{$arch}}{{if HasPrefix .OS "ming"}}.exe{{end}}.gz`,
1813+
})
1814+
17881815
tools = append(tools,
17891816
Tool{
17901817
Owner: "containerd",

0 commit comments

Comments
 (0)