Skip to content

Commit

Permalink
feat: Collect license used to install cluster in support bundles (#1601)
Browse files Browse the repository at this point in the history
* Copy license to data directory

Signed-off-by: Evans Mungai <[email protected]>

* Collect license file in support bundle

Signed-off-by: Evans Mungai <[email protected]>

* Update license file permissions on disk

Signed-off-by: Evans Mungai <[email protected]>

* Test to check license.yaml in data dir

Signed-off-by: Evans Mungai <[email protected]>

---------

Signed-off-by: Evans Mungai <[email protected]>
  • Loading branch information
banjoh authored Dec 30, 2024
1 parent 8a95fbc commit 1bf2f6b
Show file tree
Hide file tree
Showing 12 changed files with 131 additions and 65 deletions.
20 changes: 20 additions & 0 deletions cmd/installer/cli/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,12 @@ func InstallCmd(ctx context.Context, name string) *cobra.Command {
return err
}

logrus.Debugf("copy license file to %s", dataDir)
if err := copyLicenseFileToDataDir(licenseFile, dataDir); err != nil {
// We have decided not to report this error
logrus.Warnf("unable to copy license file to %s: %v", dataDir, err)
}

opts := addonsApplierOpts{
assumeYes: assumeYes,
license: licenseFile,
Expand Down Expand Up @@ -934,3 +940,17 @@ func normalizeNoPromptToYes(f *pflag.FlagSet, name string) pflag.NormalizedName
}
return pflag.NormalizedName(name)
}

func copyLicenseFileToDataDir(licenseFile, dataDir string) error {
if licenseFile == "" {
return nil
}
licenseData, err := os.ReadFile(licenseFile)
if err != nil {
return fmt.Errorf("unable to read license file: %w", err)
}
if err := os.WriteFile(filepath.Join(dataDir, "license.yaml"), licenseData, 0400); err != nil {
return fmt.Errorf("unable to write license file: %w", err)
}
return nil
}
3 changes: 2 additions & 1 deletion e2e/host-support-bundle_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package e2e

import (
"os"
"testing"
"time"

Expand All @@ -22,7 +23,7 @@ func TestHostCollectSupportBundleInCluster(t *testing.T) {
defer tc.Cleanup()

t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339))
line := []string{"single-node-install.sh", "cli"}
line := []string{"single-node-install.sh", "cli", os.Getenv("SHORT_SHA")}
if stdout, stderr, err := tc.RunCommandOnNode(0, line); err != nil {
t.Fatalf("fail to install embedded-cluster: %v: %s: %s", err, stdout, stderr)
}
Expand Down
98 changes: 53 additions & 45 deletions e2e/install_test.go

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions e2e/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func TestProxiedEnvironment(t *testing.T) {
// bootstrap the first node and makes sure it is healthy. also executes the kots
// ssl certificate configuration (kurl-proxy).
t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339))
line := []string{"single-node-install.sh", "ui"}
line := []string{"single-node-install.sh", "ui", os.Getenv("SHORT_SHA")}
line = append(line, "--http-proxy", lxd.HTTPProxy)
line = append(line, "--https-proxy", lxd.HTTPProxy)
if _, _, err := tc.RunCommandOnNode(0, line, lxd.WithProxyEnv(tc.IPs)); err != nil {
Expand Down Expand Up @@ -158,7 +158,7 @@ func TestProxiedCustomCIDR(t *testing.T) {
// bootstrap the first node and makes sure it is healthy. also executes the kots
// ssl certificate configuration (kurl-proxy).
t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339))
line := []string{"single-node-install.sh", "ui"}
line := []string{"single-node-install.sh", "ui", os.Getenv("SHORT_SHA")}
line = append(line, "--http-proxy", lxd.HTTPProxy)
line = append(line, "--https-proxy", lxd.HTTPProxy)
line = append(line, "--no-proxy", strings.Join(tc.IPs, ","))
Expand Down Expand Up @@ -279,7 +279,7 @@ func TestInstallWithMITMProxy(t *testing.T) {
// bootstrap the first node and makes sure it is healthy. also executes the kots
// ssl certificate configuration (kurl-proxy).
t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339))
line := []string{"single-node-install.sh", "ui"}
line := []string{"single-node-install.sh", "ui", os.Getenv("SHORT_SHA")}
line = append(line, "--http-proxy", lxd.HTTPMITMProxy)
line = append(line, "--https-proxy", lxd.HTTPMITMProxy)
line = append(line, "--private-ca", "/usr/local/share/ca-certificates/proxy/ca.crt")
Expand Down
2 changes: 1 addition & 1 deletion e2e/reset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestMultiNodeReset(t *testing.T) {
defer tc.Cleanup()

t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339))
if stdout, stderr, err := tc.RunCommandOnNode(0, []string{"single-node-install.sh", "ui"}); err != nil {
if stdout, stderr, err := tc.RunCommandOnNode(0, []string{"single-node-install.sh", "ui", os.Getenv("SHORT_SHA")}); err != nil {
t.Fatalf("fail to install embedded-cluster on node 0: %v: %s: %s", err, stdout, stderr)
}

Expand Down
14 changes: 7 additions & 7 deletions e2e/restore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func TestSingleNodeDisasterRecovery(t *testing.T) {
defer tc.Cleanup()

t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339))
line := []string{"single-node-install.sh", "ui"}
line := []string{"single-node-install.sh", "ui", os.Getenv("SHORT_SHA")}
if stdout, stderr, err := tc.RunCommandOnNode(0, line); err != nil {
t.Fatalf("fail to install embedded-cluster on node 0: %v: %s: %s", err, stdout, stderr)
}
Expand Down Expand Up @@ -136,7 +136,7 @@ func TestSingleNodeLegacyDisasterRecovery(t *testing.T) {
defer tc.Cleanup()

t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339))
line := []string{"single-node-install.sh", "ui"}
line := []string{"single-node-install.sh", "ui", os.Getenv("SHORT_SHA")}
if stdout, stderr, err := tc.RunCommandOnNode(0, line); err != nil {
t.Fatalf("fail to install embedded-cluster on node 0: %v: %s: %s", err, stdout, stderr)
}
Expand Down Expand Up @@ -224,7 +224,7 @@ func TestSingleNodeDisasterRecoveryWithProxy(t *testing.T) {
tc.InstallTestDependenciesDebian(t, 0, true)

t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339))
line := []string{"single-node-install.sh", "ui"}
line := []string{"single-node-install.sh", "ui", os.Getenv("SHORT_SHA")}
line = append(line, "--http-proxy", lxd.HTTPProxy)
line = append(line, "--https-proxy", lxd.HTTPProxy)
line = append(line, "--no-proxy", strings.Join(tc.IPs, ","))
Expand Down Expand Up @@ -307,7 +307,7 @@ func TestSingleNodeResumeDisasterRecovery(t *testing.T) {
defer tc.Cleanup()

t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339))
line := []string{"single-node-install.sh", "ui"}
line := []string{"single-node-install.sh", "ui", os.Getenv("SHORT_SHA")}
if stdout, stderr, err := tc.RunCommandOnNode(0, line); err != nil {
t.Fatalf("fail to install embedded-cluster on node 0: %v: %s: %s", err, stdout, stderr)
}
Expand Down Expand Up @@ -404,7 +404,7 @@ func TestSingleNodeAirgapDisasterRecovery(t *testing.T) {
t.Fatalf("fail to prepare airgap files on node %s: %v", tc.Nodes[0], err)
}
t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339))
line = []string{"single-node-airgap-install.sh", "--proxy"}
line = []string{"single-node-airgap-install.sh", os.Getenv("SHORT_SHA"), "--proxy"}
line = append(line, "--pod-cidr", "10.128.0.0/20")
line = append(line, "--service-cidr", "10.129.0.0/20")
if _, _, err := tc.RunCommandOnNode(0, line, lxd.WithProxyEnv(tc.IPs)); err != nil {
Expand Down Expand Up @@ -514,7 +514,7 @@ func TestMultiNodeHADisasterRecovery(t *testing.T) {
defer tc.Cleanup()

t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339))
if stdout, stderr, err := tc.RunCommandOnNode(0, []string{"single-node-install.sh", "ui"}); err != nil {
if stdout, stderr, err := tc.RunCommandOnNode(0, []string{"single-node-install.sh", "ui", os.Getenv("SHORT_SHA")}); err != nil {
t.Fatalf("fail to install embedded-cluster on node 0: %v: %s: %s", err, stdout, stderr)
}

Expand Down Expand Up @@ -740,7 +740,7 @@ func TestMultiNodeAirgapHADisasterRecovery(t *testing.T) {
}

t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339))
line = []string{"single-node-airgap-install.sh", "--proxy", "--data-dir", "/var/lib/ec"}
line = []string{"single-node-airgap-install.sh", os.Getenv("SHORT_SHA"), "--proxy", "--data-dir", "/var/lib/ec"}
if _, _, err := tc.RunCommandOnNode(0, line, withEnv, lxd.WithProxyEnv(tc.IPs)); err != nil {
t.Fatalf("fail to install embedded-cluster on node %s: %v", tc.Nodes[0], err)
}
Expand Down
16 changes: 13 additions & 3 deletions e2e/scripts/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,16 @@ ensure_binary_copy() {
fi
}

ensure_license_in_data_dir() {
local expected_license_path="$EMBEDDED_CLUSTER_BASE_DIR/license.yaml"
if [ -e "$expected_license_path" ]; then
echo "license file exists in $expected_license_path"
else
echo "license file does not exist in $expected_license_path"
return 1
fi
}

ensure_node_config() {
if ! kubectl describe node | grep "controller-label" ; then
echo "Failed to find controller-label"
Expand Down Expand Up @@ -362,7 +372,7 @@ validate_data_dirs() {
if kubectl -n kube-system get charts k0s-addon-chart-openebs -oyaml >/dev/null 2>&1 ; then
echo "found openebs chart"

openebsdatadir=$(kubectl -n kube-system get charts k0s-addon-chart-openebs -oyaml | grep -v apiVersion | grep "basePath:" | awk '{print $2}')
openebsdatadir=$(kubectl -n kube-system get charts k0s-addon-chart-openebs -oyaml | grep -v apiVersion | grep "basePath:" | awk '{print $2}')
echo "found openebsdatadir $openebsdatadir, want $expected_openebsdatadir"
if [ "$openebsdatadir" != "$expected_openebsdatadir" ]; then
echo "got unexpected openebsdatadir $openebsdatadir, want $expected_openebsdatadir"
Expand All @@ -378,7 +388,7 @@ validate_data_dirs() {
if kubectl -n kube-system get charts k0s-addon-chart-seaweedfs -oyaml >/dev/null 2>&1 ; then
echo "found seaweedfs chart"

seaweefdatadir=$(kubectl -n kube-system get charts k0s-addon-chart-seaweedfs -oyaml| grep -v apiVersion | grep -m 1 "hostPathPrefix:" | awk '{print $2}')
seaweefdatadir=$(kubectl -n kube-system get charts k0s-addon-chart-seaweedfs -oyaml| grep -v apiVersion | grep -m 1 "hostPathPrefix:" | awk '{print $2}')
echo "found seaweefdatadir $seaweefdatadir, want $expected_datadir/seaweedfs/(ssd|storage)"
if ! echo "$seaweefdatadir" | grep -qE "^$expected_datadir/seaweedfs/(ssd|storage)$" ; then
echo "got unexpected seaweefdatadir $seaweefdatadir, want $expected_datadir/seaweedfs/(ssd|storage)"
Expand All @@ -394,7 +404,7 @@ validate_data_dirs() {
if kubectl -n kube-system get charts k0s-addon-chart-velero -oyaml >/dev/null 2>&1 ; then
echo "found velero chart"

velerodatadir=$(kubectl -n kube-system get charts k0s-addon-chart-velero -oyaml | grep -v apiVersion | grep "podVolumePath:" | awk '{print $2}')
velerodatadir=$(kubectl -n kube-system get charts k0s-addon-chart-velero -oyaml | grep -v apiVersion | grep "podVolumePath:" | awk '{print $2}')
echo "found velerodatadir $velerodatadir, want $expected_k0sdatadir/kubelet/pods"
if [ "$velerodatadir" != "$expected_k0sdatadir/kubelet/pods" ]; then
echo "got unexpected velerodatadir $velerodatadir, want $expected_openebsdatadir/kubelet/pods"
Expand Down
12 changes: 10 additions & 2 deletions e2e/scripts/single-node-airgap-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ check_airgap_pvc() {
}

main() {
local version="$1"
local additional_args=
if [ -n "${1:-}" ]; then
additional_args="$*"
if [ -n "${2:-}" ]; then
additional_args="${*:2}"
echo "Running install with additional args: $additional_args"
fi

Expand Down Expand Up @@ -98,6 +99,13 @@ main() {
exit 1
fi

# if this is the current version in CI
if echo "$version" | grep -qvE "(pre-minio-removal|1.8.0-k8s|previous-stable)" ; then
if ! ensure_license_in_data_dir; then
exit 1
fi
fi

echo "kotsadm logs"
kubectl logs -n kotsadm -l app=kotsadm --tail=50 || true
echo "previous kotsadm logs"
Expand Down
12 changes: 10 additions & 2 deletions e2e/scripts/single-node-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,11 @@ check_openebs_storage_class() {

main() {
local app_deploy_method="$1"
local version="$2"

local additional_args=
if [ -n "${2:-}" ]; then
additional_args="${*:2}"
if [ -n "${3:-}" ]; then
additional_args="${*:3}"
echo "Running install with additional args: $additional_args"
fi

Expand Down Expand Up @@ -156,6 +157,13 @@ main() {
exit 1
fi

# if this is the current version in CI
if echo "$version" | grep -qvE "(pre-minio-removal|1.8.0-k8s|previous-stable)" ; then
if ! ensure_license_in_data_dir; then
exit 1
fi
fi

echo "kotsadm logs"
kubectl logs -n kotsadm -l app=kotsadm --tail=50 || true
echo "previous kotsadm logs"
Expand Down
7 changes: 7 additions & 0 deletions e2e/scripts/validate-support-bundle.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,23 @@ main() {
tar -zxvf support-bundle-*.tar.gz
rm -rf support-bundle-*.tar.gz

echo "checking for the k0s sysinfo file"
if ! ls support-bundle-*/host-collectors/run-host/k0s-sysinfo.txt; then
echo "Failed to find 'k0s sysinfo' inside the support bundle generated with the embedded cluster binary"
return 1
fi

echo "checking for the embedded-cluster-operator logs"
if ! ls support-bundle-*/podlogs/embedded-cluster-operator; then
echo "Failed to find operator logs inside the support bundle generated with the embedded cluster binary"
return 1
fi

echo "checking for the license file inside the support bundle"
if ! ls support-bundle-*/host-collectors/embedded-cluster/license.yaml; then
echo "Failed to find license file inside the support bundle generated with the embedded cluster binary"
return 1
fi
}

main "$@"
3 changes: 2 additions & 1 deletion e2e/support-bundle_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package e2e

import (
"os"
"testing"
"time"

Expand All @@ -23,7 +24,7 @@ func TestCollectSupportBundle(t *testing.T) {
defer tc.Cleanup()

t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339))
line := []string{"single-node-install.sh", "cli"}
line := []string{"single-node-install.sh", "cli", os.Getenv("SHORT_SHA")}
stdout, stderr, err := tc.RunCommandOnNode(0, line)
assert.NoErrorf(t, err, "fail to install embedded-cluster: %v: %s: %s", err, stdout, stderr)

Expand Down
3 changes: 3 additions & 0 deletions pkg/goods/support/host-support-bundle.tmpl.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,9 @@ spec:
collectorName: "localhost-ips"
command: "sh"
args: ["-c", "host localhost"]
- copy:
collectorName: embedded-cluster # Directory to copy license file to
path: {{ .DataDir }}/license.yaml
hostAnalyzers:
- ipv4Interfaces:
outcomes:
Expand Down

0 comments on commit 1bf2f6b

Please sign in to comment.