Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Collect license used to install cluster in support bundles #1601

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
Loading