Skip to content

Commit

Permalink
Add spec.hosts.k0sDownloadURL
Browse files Browse the repository at this point in the history
Signed-off-by: Kimmo Lehto <[email protected]>
  • Loading branch information
kke committed Apr 12, 2024
1 parent cd5b8ef commit edfba8a
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 7 deletions.
21 changes: 21 additions & 0 deletions .github/workflows/smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,27 @@ jobs:
- name: Run OS override smoke test
run: make smoke-os-override

smoke-downloadurl:
name: k0sDownloadURL smoke test
needs: build
runs-on: ubuntu-20.04

steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true

- {"name":"Compiled binary cache","uses":"actions/download-artifact@v4","with":{"name":"k0sctl","path":"."}}
- {"name":"K0sctl cache","uses":"actions/cache@v3","with":{"path":"/var/cache/k0sctl/k0s\n~/.cache/k0sctl/k0s\n","key":"k0sctl-cache"}}
- {"name":"Kubectl cache","uses":"actions/cache@v3","with":{"path":"smoke-test/kubectl\n","key":"kubectl-${{ hashFiles('smoke-test/smoke.common.sh') }}","restore-keys":"kubectl-"}}
- {"name":"Make binaries executable","run":"chmod +x k0sctl || true\nchmod +x smoke-test/kubectl || true"}

- name: Run OS override smoke test
run: make smoke-downloadurl

smoke-upgrade:
strategy:
matrix:
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ build-all: $(addprefix bin/,$(bins)) bin/checksums.md
clean:
rm -rf bin/ k0sctl

smoketests := smoke-basic smoke-files smoke-upgrade smoke-reset smoke-os-override smoke-init smoke-backup-restore smoke-dynamic smoke-basic-openssh smoke-dryrun
smoketests := smoke-basic smoke-files smoke-upgrade smoke-reset smoke-os-override smoke-init smoke-backup-restore smoke-dynamic smoke-basic-openssh smoke-dryrun smoke-downloadurl
.PHONY: $(smoketests)
$(smoketests): k0sctl
$(MAKE) -C smoke-test $@
Expand Down
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,10 @@ When `false`, the k0s binary downloading is performed on the target host itself

A path to a file on the local host that contains a k0s binary to be uploaded to the host. Can be used to test drive a custom development build of k0s.

###### `spec.hosts[*].k0sDownloadURL` &lt;string&gt; (optional)

A URL to download the k0s binary from. The default is to download from the [k0s repository](https://github.com/k0sproject/k0s). The URL can contain '%'-prefixed tokens that will be replaced with the host's information, see [tokens](#tokens).

###### `spec.hosts[*].hostname` &lt;string&gt; (optional)

Override host's hostname. When not set, the hostname reported by the operating system is used.
Expand Down Expand Up @@ -341,7 +345,7 @@ Example:
```

* `name`: name of the file "bundle", used only for logging purposes (optional)
* `src`: File path, an URL or [Glob pattern](https://golang.org/pkg/path/filepath/#Match) to match files to be uploaded. URL sources will be directly downloaded using the target host (required)
* `src`: File path, an URL or [Glob pattern](https://golang.org/pkg/path/filepath/#Match) to match files to be uploaded. URL sources will be directly downloaded using the target host. If the value is a URL, '%'-prefixed tokens can be used, see [tokens](#tokens). (required)
* `dstDir`: Destination directory for the file(s). `k0sctl` will create full directory structure if it does not already exist on the host (default: user home)
* `dst`: Destination filename for the file. Only usable for single file uploads (default: basename of file)
* `perm`: File permission mode for uploaded file(s) (default: same as local)
Expand Down Expand Up @@ -595,3 +599,23 @@ See also:
Embedded k0s cluster configuration. See [k0s configuration documentation](https://docs.k0sproject.io/main/configuration/) for details.

When left out, the output of `k0s config create` will be used.

#### Tokens

The following tokens can be used in the `k0sDownloadURL` and `files.[*].src` fields:

- `%%` - literal `%`
- `%p` - host architecture (arm, arm64, amd64)
- `%v` - k0s version (v1.21.0+k0s.0)
- `%x` - k0s binary extension (currently always empty)

Any other tokens will be output as-is including the `%` character.

Example:

```yaml
- role: controller
k0sDownloadURL: https://files.example.com/k0s%20files/k0s-%v-%p%x
# Expands to https://files.example.com/k0s%20files/k0s-v1.21.0+k0s.0-amd64
```

9 changes: 8 additions & 1 deletion phase/download_k0s.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,16 @@ func (p *DownloadK0s) downloadK0s(h *cluster.Host) error {
}

log.Infof("%s: downloading k0s %s", h, p.Config.Spec.K0s.Version)
if err := h.Configurer.DownloadK0s(h, tmp, p.Config.Spec.K0s.Version, h.Metadata.Arch); err != nil {
if h.K0sDownloadURL != "" {
expandedURL := h.ExpandTokens(h.K0sDownloadURL, p.Config.Spec.K0s.Version)
log.Infof("%s: downloading k0s binary from %s", h, expandedURL)
if err := h.Configurer.DownloadURL(h, expandedURL, tmp); err != nil {
return fmt.Errorf("failed to download k0s binary: %w", err)
}
} else if err := h.Configurer.DownloadK0s(h, tmp, p.Config.Spec.K0s.Version, h.Metadata.Arch); err != nil {
return err
}

if err := h.Execf(`chmod +x "%s"`, tmp, exec.Sudo(h)); err != nil {
logrus.Warnf("%s: failed to chmod k0s temp binary: %v", h, err.Error())
}
Expand Down
6 changes: 3 additions & 3 deletions phase/uploadfiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,9 @@ func (p *UploadFiles) uploadURL(h *cluster.Host, f *cluster.UploadFile) error {
return err
}

err := p.Wet(h, fmt.Sprintf("download file %s => %s", f.Source, f.DestinationFile), func() error {

return h.Configurer.DownloadURL(h, f.Source, f.DestinationFile, exec.Sudo(h))
expandedURL := h.ExpandTokens(f.Source, p.Config.Spec.K0s.Version)
err := p.Wet(h, fmt.Sprintf("download file %s => %s", expandedURL, f.DestinationFile), func() error {
return h.Configurer.DownloadURL(h, expandedURL, f.DestinationFile, exec.Sudo(h))
})
if err != nil {
return err
Expand Down
55 changes: 54 additions & 1 deletion pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cluster

import (
"fmt"
"net/url"
gos "os"
gopath "path"
"regexp"
Expand Down Expand Up @@ -36,6 +37,7 @@ type Host struct {
Environment map[string]string `yaml:"environment,flow,omitempty"`
UploadBinary bool `yaml:"uploadBinary,omitempty"`
K0sBinaryPath string `yaml:"k0sBinaryPath,omitempty"`
K0sDownloadURL string `yaml:"k0sDownloadURL,omitempty"`
InstallFlags Flags `yaml:"installFlags,omitempty"`
Files []*UploadFile `yaml:"files,omitempty"`
OSIDOverride string `yaml:"os,omitempty"`
Expand Down Expand Up @@ -448,7 +450,6 @@ func (h *Host) CheckHTTPStatus(url string, expected ...int) error {
}

return fmt.Errorf("expected response code %d but received %d", expected, status)

}

// NeedCurl returns true when the curl package is needed on the host
Expand Down Expand Up @@ -515,3 +516,55 @@ func (h *Host) FileChanged(lpath, rpath string) bool {

return false
}

// ExpandTokens expands percent-sign prefixed tokens in a string, mainly for the download URLs.
// The supported tokens are:
//
// - %% - literal %
// - %p - host architecture (arm, arm64, amd64)
// - %v - k0s version (v1.21.0+k0s.0)
// - %x - k0s binary extension (.exe on Windows)
//
// Any unknown token is output as-is with the leading % included.
func (h *Host) ExpandTokens(input string, k0sVersion *version.Version) string {
if input == "" {
return ""
}
builder := strings.Builder{}
var inPercent bool
for i := 0; i < len(input); i++ {
currCh := input[i]
if inPercent {
inPercent = false
switch currCh {
case '%':
// Literal %.
builder.WriteByte('%')
case 'p':
// Host architecture (arm, arm64, amd64).
builder.WriteString(h.Metadata.Arch)
case 'v':
// K0s version (v1.21.0+k0s.0)
builder.WriteString(url.QueryEscape(k0sVersion.String()))
case 'x':
// K0s binary extension (.exe on Windows).
if h.IsConnected() && h.IsWindows() {
builder.WriteString(".exe")
}
default:
// Unknown token, just output it with the leading %.
builder.WriteByte('%')
builder.WriteByte(currCh)
}
} else if currCh == '%' {
inPercent = true
} else {
builder.WriteByte(currCh)
}
}
if inPercent {
// Trailing %.
builder.WriteByte('%')
}
return builder.String()
}
12 changes: 12 additions & 0 deletions pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster/host_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/k0sproject/rig"
"github.com/k0sproject/rig/exec"
"github.com/k0sproject/rig/os"
"github.com/k0sproject/version"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -144,3 +145,14 @@ func TestBinaryPath(t *testing.T) {
h.Configurer.SetPath("K0sBinaryPath", "/foo/bar/k0s")
require.Equal(t, "/foo/bar", h.k0sBinaryPathDir())
}

func TestExpandTokens(t *testing.T) {
h := Host{
Metadata: HostMetadata{
Arch: "amd64",
},
}
ver, err := version.NewVersion("v1.0.0+k0s.0")
require.NoError(t, err)
require.Equal(t, "test%20expand/k0s-v1.0.0%2Bk0s.0-amd64", h.ExpandTokens("test%20expand/k0s-%v-%p%x", ver))
}
3 changes: 3 additions & 0 deletions smoke-test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ smoke-reset: $(bootloose) id_rsa_k0s k0sctl
smoke-os-override: $(bootloose) id_rsa_k0s k0sctl
BOOTLOOSE_TEMPLATE=bootloose.yaml.osoverride.tpl K0SCTL_CONFIG=k0sctl-single.yaml OS_RELEASE_PATH=$(realpath os-release) OS_OVERRIDE="ubuntu" ./smoke-basic.sh

smoke-downloadurl: $(bootloose) id_rsa_k0s k0sctl
BOOTLOOSE_TEMPLATE=bootloose.yaml.osoverride.tpl K0SCTL_CONFIG=k0sctl-downloadurl.yaml ./smoke-basic.sh

smoke-backup-restore: $(bootloose) id_rsa_k0s k0sctl
./smoke-backup-restore.sh

Expand Down
15 changes: 15 additions & 0 deletions smoke-test/k0sctl-downloadurl.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: k0sctl.k0sproject.io/v1beta1
kind: cluster
spec:
hosts:
- role: single
k0sDownloadURL: https://github.com/k0sproject/k0s/releases/download/%v/k0s-%v-%p
ssh:
address: "127.0.0.1"
port: 9022
keyPath: ./id_rsa_k0s
k0s:
config:
spec:
telemetry:
enabled: false

0 comments on commit edfba8a

Please sign in to comment.