diff --git a/cmd/installer/cli/install.go b/cmd/installer/cli/install.go index 3580f6976..9a20a5256 100644 --- a/cmd/installer/cli/install.go +++ b/cmd/installer/cli/install.go @@ -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, @@ -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 +} diff --git a/e2e/host-support-bundle_test.go b/e2e/host-support-bundle_test.go index 2919a69b4..101f7c534 100644 --- a/e2e/host-support-bundle_test.go +++ b/e2e/host-support-bundle_test.go @@ -1,6 +1,7 @@ package e2e import ( + "os" "testing" "time" @@ -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) } diff --git a/e2e/install_test.go b/e2e/install_test.go index 9336c1274..aea21a58d 100644 --- a/e2e/install_test.go +++ b/e2e/install_test.go @@ -33,7 +33,7 @@ func TestSingleNodeInstallation(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", "--admin-console-port", "30002"} + line := []string{"single-node-install.sh", "ui", os.Getenv("SHORT_SHA"), "--admin-console-port", "30002"} 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) } @@ -96,7 +96,7 @@ func TestSingleNodeInstallationAlmaLinux8(t *testing.T) { } 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) } @@ -143,7 +143,7 @@ func TestSingleNodeInstallationDebian12(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) } @@ -190,7 +190,7 @@ func TestSingleNodeInstallationDebian11(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) } @@ -243,7 +243,7 @@ func TestSingleNodeInstallationCentos9Stream(t *testing.T) { } 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) } @@ -342,7 +342,7 @@ func TestMultiNodeInstallation(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) } @@ -455,7 +455,7 @@ func TestInstallFromReplicatedApp(t *testing.T) { } 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) } @@ -500,13 +500,14 @@ func TestSingleNodeUpgradePreviousStable(t *testing.T) { defer tc.Cleanup() t.Logf("%s: downloading embedded-cluster on node 0", time.Now().Format(time.RFC3339)) - line := []string{"vandoor-prepare.sh", fmt.Sprintf("appver-%s-previous-stable", os.Getenv("SHORT_SHA")), os.Getenv("LICENSE_ID"), "false"} + initialVersion := fmt.Sprintf("appver-%s-previous-stable", os.Getenv("SHORT_SHA")) + line := []string{"vandoor-prepare.sh", initialVersion, os.Getenv("LICENSE_ID"), "false"} if stdout, stderr, err := tc.RunCommandOnNode(0, line); err != nil { t.Fatalf("fail to download embedded-cluster on node 0: %v: %s: %s", err, stdout, stderr) } 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", initialVersion} 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) } @@ -516,7 +517,7 @@ func TestSingleNodeUpgradePreviousStable(t *testing.T) { } t.Logf("%s: checking installation state", time.Now().Format(time.RFC3339)) - line = []string{"check-installation-state.sh", fmt.Sprintf("appver-%s-previous-stable", os.Getenv("SHORT_SHA")), k8sVersionPreviousStable()} + line = []string{"check-installation-state.sh", initialVersion, k8sVersionPreviousStable()} if stdout, stderr, err := tc.RunCommandOnNode(0, line); err != nil { t.Fatalf("fail to check installation state: %v: %s: %s", err, stdout, stderr) } @@ -550,14 +551,15 @@ func TestUpgradeFromReplicatedApp(t *testing.T) { }) defer tc.Cleanup() + initialVersion := fmt.Sprintf("appver-%s-previous-k0s", os.Getenv("SHORT_SHA")) t.Logf("%s: downloading embedded-cluster on node 0", time.Now().Format(time.RFC3339)) - line := []string{"vandoor-prepare.sh", fmt.Sprintf("appver-%s-previous-k0s", os.Getenv("SHORT_SHA")), os.Getenv("LICENSE_ID"), "false"} + line := []string{"vandoor-prepare.sh", initialVersion, os.Getenv("LICENSE_ID"), "false"} if stdout, stderr, err := tc.RunCommandOnNode(0, line); err != nil { t.Fatalf("fail to download embedded-cluster on node 0: %v: %s: %s", err, stdout, stderr) } 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", initialVersion} 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) } @@ -567,7 +569,7 @@ func TestUpgradeFromReplicatedApp(t *testing.T) { } t.Logf("%s: checking installation state", time.Now().Format(time.RFC3339)) - line = []string{"check-installation-state.sh", fmt.Sprintf("%s-previous-k0s", os.Getenv("SHORT_SHA")), k8sVersionPrevious()} + line = []string{"check-installation-state.sh", initialVersion, k8sVersionPrevious()} if stdout, stderr, err := tc.RunCommandOnNode(0, line); err != nil { t.Fatalf("fail to check installation state: %v: %s: %s", err, stdout, stderr) } @@ -625,7 +627,7 @@ func TestUpgradeEC18FromReplicatedApp(t *testing.T) { } t.Logf("%s: installing embedded-cluster %s on node 0", appVer, time.Now().Format(time.RFC3339)) - line = []string{"single-node-install.sh", "ui"} + line = []string{"single-node-install.sh", "ui", appVer} if stdout, stderr, err := tc.RunCommandOnNode(0, line, withEnv); err != nil { t.Fatalf("fail to install embedded-cluster on node 0: %v: %s: %s", err, stdout, stderr) } @@ -725,7 +727,7 @@ func TestResetAndReinstall(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) } @@ -750,7 +752,7 @@ func TestResetAndReinstall(t *testing.T) { time.Sleep(30 * time.Second) t.Logf("%s: installing embedded-cluster on node 0 after reset", 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) } @@ -802,7 +804,7 @@ func TestResetAndReinstallAirgap(t *testing.T) { } t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339)) - line = []string{"single-node-airgap-install.sh"} + line = []string{"single-node-airgap-install.sh", os.Getenv("SHORT_SHA")} if _, _, err := tc.RunCommandOnNode(0, line); err != nil { t.Fatalf("fail to install embedded-cluster on node %s: %v", tc.Nodes[0], err) } @@ -827,7 +829,7 @@ func TestResetAndReinstallAirgap(t *testing.T) { time.Sleep(30 * time.Second) t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339)) - line = []string{"single-node-airgap-install.sh"} + line = []string{"single-node-airgap-install.sh", os.Getenv("SHORT_SHA")} if _, _, err := tc.RunCommandOnNode(0, line); err != nil { t.Fatalf("fail to install embedded-cluster on node %s: %v", tc.Nodes[0], err) } @@ -901,9 +903,10 @@ func TestSingleNodeAirgapUpgrade(t *testing.T) { t.Logf("%s: downloading airgap files", time.Now().Format(time.RFC3339)) airgapInstallBundlePath := "/tmp/airgap-install-bundle.tar.gz" airgapUpgradeBundlePath := "/tmp/airgap-upgrade-bundle.tar.gz" + initialVersion := fmt.Sprintf("appver-%s-previous-k0s", os.Getenv("SHORT_SHA")) runInParallel(t, func(t *testing.T) error { - return downloadAirgapBundle(t, fmt.Sprintf("appver-%s-previous-k0s", os.Getenv("SHORT_SHA")), airgapInstallBundlePath, os.Getenv("AIRGAP_LICENSE_ID")) + return downloadAirgapBundle(t, initialVersion, airgapInstallBundlePath, os.Getenv("AIRGAP_LICENSE_ID")) }, func(t *testing.T) error { return downloadAirgapBundle(t, fmt.Sprintf("appver-%s-upgrade", os.Getenv("SHORT_SHA")), airgapUpgradeBundlePath, os.Getenv("AIRGAP_LICENSE_ID")) }, @@ -937,7 +940,7 @@ func TestSingleNodeAirgapUpgrade(t *testing.T) { } t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339)) - line = []string{"single-node-airgap-install.sh", "--local-artifact-mirror-port", "50001"} // choose an alternate lam port + line = []string{"single-node-airgap-install.sh", initialVersion, "--local-artifact-mirror-port", "50001"} // choose an alternate lam port if _, _, err := tc.RunCommandOnNode(0, line); err != nil { t.Fatalf("fail to install embedded-cluster on node %s: %v", tc.Nodes[0], err) } @@ -952,7 +955,7 @@ func TestSingleNodeAirgapUpgrade(t *testing.T) { } t.Logf("%s: checking installation state after app deployment", time.Now().Format(time.RFC3339)) - line = []string{"check-airgap-installation-state.sh", fmt.Sprintf("appver-%s-previous-k0s", os.Getenv("SHORT_SHA")), k8sVersionPrevious()} + line = []string{"check-airgap-installation-state.sh", initialVersion, k8sVersionPrevious()} if _, _, err := tc.RunCommandOnNode(0, line); err != nil { t.Fatalf("fail to check installation state: %v", err) } @@ -993,9 +996,10 @@ func TestSingleNodeAirgapUpgradeCustomCIDR(t *testing.T) { t.Logf("%s: downloading airgap files", time.Now().Format(time.RFC3339)) airgapInstallBundlePath := "/tmp/airgap-install-bundle.tar.gz" airgapUpgradeBundlePath := "/tmp/airgap-upgrade-bundle.tar.gz" + initialVersion := fmt.Sprintf("appver-%s-previous-k0s", os.Getenv("SHORT_SHA")) runInParallel(t, func(t *testing.T) error { - return downloadAirgapBundle(t, fmt.Sprintf("appver-%s-previous-k0s", os.Getenv("SHORT_SHA")), airgapInstallBundlePath, os.Getenv("AIRGAP_LICENSE_ID")) + return downloadAirgapBundle(t, initialVersion, airgapInstallBundlePath, os.Getenv("AIRGAP_LICENSE_ID")) }, func(t *testing.T) error { return downloadAirgapBundle(t, fmt.Sprintf("appver-%s-upgrade", os.Getenv("SHORT_SHA")), airgapUpgradeBundlePath, os.Getenv("AIRGAP_LICENSE_ID")) }, @@ -1029,7 +1033,7 @@ func TestSingleNodeAirgapUpgradeCustomCIDR(t *testing.T) { } t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339)) - line = []string{"single-node-airgap-install.sh"} + line = []string{"single-node-airgap-install.sh", initialVersion} line = append(line, "--cidr", "172.16.0.0/15") if _, _, err := tc.RunCommandOnNode(0, line); err != nil { t.Fatalf("fail to install embedded-cluster on node %s: %v", tc.Nodes[0], err) @@ -1045,7 +1049,7 @@ func TestSingleNodeAirgapUpgradeCustomCIDR(t *testing.T) { } t.Logf("%s: checking installation state after app deployment", time.Now().Format(time.RFC3339)) - line = []string{"check-airgap-installation-state.sh", fmt.Sprintf("appver-%s-previous-k0s", os.Getenv("SHORT_SHA")), k8sVersionPrevious()} + line = []string{"check-airgap-installation-state.sh", initialVersion, k8sVersionPrevious()} if _, _, err := tc.RunCommandOnNode(0, line); err != nil { t.Fatalf("fail to check installation state: %v", err) } @@ -1147,7 +1151,7 @@ func TestAirgapUpgradeFromEC18(t *testing.T) { } t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339)) - line = []string{"single-node-airgap-install.sh"} + line = []string{"single-node-airgap-install.sh", appVer} if _, _, err := tc.RunCommandOnNode(0, line, withEnv); err != nil { t.Fatalf("fail to install embedded-cluster on node %s: %v", tc.Nodes[0], err) } @@ -1316,7 +1320,7 @@ func TestMultiNodeAirgapUpgradeSameK0s(t *testing.T) { } t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339)) - line = []string{"single-node-airgap-install.sh"} + line = []string{"single-node-airgap-install.sh", os.Getenv("SHORT_SHA")} if _, _, err := tc.RunCommandOnNode(0, line); err != nil { t.Fatalf("fail to install embedded-cluster on node %s: %v", tc.Nodes[0], err) } @@ -1428,9 +1432,10 @@ func TestMultiNodeAirgapUpgrade(t *testing.T) { t.Logf("%s: downloading airgap files", time.Now().Format(time.RFC3339)) airgapInstallBundlePath := "/tmp/airgap-install-bundle.tar.gz" airgapUpgradeBundlePath := "/tmp/airgap-upgrade-bundle.tar.gz" + initialVersion := fmt.Sprintf("appver-%s-previous-k0s", os.Getenv("SHORT_SHA")) runInParallel(t, func(t *testing.T) error { - return downloadAirgapBundle(t, fmt.Sprintf("appver-%s-previous-k0s", os.Getenv("SHORT_SHA")), airgapInstallBundlePath, os.Getenv("AIRGAP_LICENSE_ID")) + return downloadAirgapBundle(t, initialVersion, airgapInstallBundlePath, os.Getenv("AIRGAP_LICENSE_ID")) }, func(t *testing.T) error { return downloadAirgapBundle(t, fmt.Sprintf("appver-%s-upgrade", os.Getenv("SHORT_SHA")), airgapUpgradeBundlePath, os.Getenv("AIRGAP_LICENSE_ID")) }, @@ -1470,7 +1475,7 @@ func TestMultiNodeAirgapUpgrade(t *testing.T) { } t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339)) - line = []string{"single-node-airgap-install.sh", "--local-artifact-mirror-port", "50001"} // choose an alternate lam port + line = []string{"single-node-airgap-install.sh", initialVersion, "--local-artifact-mirror-port", "50001"} // choose an alternate lam port if _, _, err := tc.RunCommandOnNode(0, line); err != nil { t.Fatalf("fail to install embedded-cluster on node %s: %v", tc.Nodes[0], err) } @@ -1529,7 +1534,7 @@ func TestMultiNodeAirgapUpgrade(t *testing.T) { } t.Logf("%s: checking installation state after app deployment", time.Now().Format(time.RFC3339)) - line = []string{"check-airgap-installation-state.sh", fmt.Sprintf("appver-%s-previous-k0s", os.Getenv("SHORT_SHA")), k8sVersionPrevious()} + line = []string{"check-airgap-installation-state.sh", initialVersion, k8sVersionPrevious()} if _, _, err := tc.RunCommandOnNode(0, line); err != nil { t.Fatalf("fail to check installation state: %v", err) } @@ -1574,9 +1579,10 @@ func TestMultiNodeAirgapUpgradePreviousStable(t *testing.T) { t.Logf("%s: downloading airgap files", time.Now().Format(time.RFC3339)) airgapInstallBundlePath := "/tmp/airgap-install-bundle.tar.gz" airgapUpgradeBundlePath := "/tmp/airgap-upgrade-bundle.tar.gz" + initialVersion := fmt.Sprintf("appver-%s-previous-stable", os.Getenv("SHORT_SHA")) runInParallel(t, func(t *testing.T) error { - return downloadAirgapBundle(t, fmt.Sprintf("appver-%s-previous-stable", os.Getenv("SHORT_SHA")), airgapInstallBundlePath, os.Getenv("AIRGAP_LICENSE_ID")) + return downloadAirgapBundle(t, initialVersion, airgapInstallBundlePath, os.Getenv("AIRGAP_LICENSE_ID")) }, func(t *testing.T) error { return downloadAirgapBundle(t, fmt.Sprintf("appver-%s-upgrade", os.Getenv("SHORT_SHA")), airgapUpgradeBundlePath, os.Getenv("AIRGAP_LICENSE_ID")) }, @@ -1616,7 +1622,7 @@ func TestMultiNodeAirgapUpgradePreviousStable(t *testing.T) { } t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339)) - line = []string{"single-node-airgap-install.sh", "--local-artifact-mirror-port", "50001"} // choose an alternate lam port + line = []string{"single-node-airgap-install.sh", initialVersion, "--local-artifact-mirror-port", "50001"} // choose an alternate lam port if _, _, err := tc.RunCommandOnNode(0, line); err != nil { t.Fatalf("fail to install embedded-cluster on node %s: %v", tc.Nodes[0], err) } @@ -1675,7 +1681,7 @@ func TestMultiNodeAirgapUpgradePreviousStable(t *testing.T) { } t.Logf("%s: checking installation state after app deployment", time.Now().Format(time.RFC3339)) - line = []string{"check-airgap-installation-state.sh", fmt.Sprintf("appver-%s-previous-stable", os.Getenv("SHORT_SHA")), k8sVersionPreviousStable()} + line = []string{"check-airgap-installation-state.sh", initialVersion, k8sVersionPreviousStable()} if _, _, err := tc.RunCommandOnNode(0, line); err != nil { t.Fatalf("fail to check installation state: %v", err) } @@ -1726,7 +1732,7 @@ func TestMultiNodeHAInstallation(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) } @@ -1880,7 +1886,7 @@ func TestMultiNodeAirgapHAInstallation(t *testing.T) { } t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339)) - line = []string{"single-node-airgap-install.sh"} + line = []string{"single-node-airgap-install.sh", os.Getenv("SHORT_SHA")} if _, _, err := tc.RunCommandOnNode(0, line); err != nil { t.Fatalf("fail to install embedded-cluster on node %s: %v", tc.Nodes[0], err) } @@ -2074,7 +2080,7 @@ func TestInstallSnapshotFromReplicatedApp(t *testing.T) { } 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) } @@ -2130,7 +2136,7 @@ func TestCustomCIDR(t *testing.T) { t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339)) // this uses the proxy install script because that accepts arbitrary install flags - line := []string{"single-node-install.sh", "ui"} + line := []string{"single-node-install.sh", "ui", os.Getenv("SHORT_SHA")} line = append(line, "--pod-cidr", "10.128.0.0/20") line = append(line, "--service-cidr", "10.129.0.0/20") if stdout, stderr, err := tc.RunCommandOnNode(0, line); err != nil { @@ -2226,7 +2232,7 @@ func TestSingleNodeInstallationNoopUpgrade(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) } @@ -2267,9 +2273,10 @@ func TestFiveNodesAirgapUpgrade(t *testing.T) { t.Logf("%s: downloading airgap files", time.Now().Format(time.RFC3339)) airgapInstallBundlePath := "/tmp/airgap-install-bundle.tar.gz" airgapUpgradeBundlePath := "/tmp/airgap-upgrade-bundle.tar.gz" + initialVersion := fmt.Sprintf("appver-%s-previous-k0s", os.Getenv("SHORT_SHA")) runInParallel(t, func(t *testing.T) error { - return downloadAirgapBundle(t, fmt.Sprintf("appver-%s-previous-k0s", os.Getenv("SHORT_SHA")), airgapInstallBundlePath, os.Getenv("AIRGAP_LICENSE_ID")) + return downloadAirgapBundle(t, initialVersion, airgapInstallBundlePath, os.Getenv("AIRGAP_LICENSE_ID")) }, func(t *testing.T) error { return downloadAirgapBundle(t, fmt.Sprintf("appver-%s-upgrade", os.Getenv("SHORT_SHA")), airgapUpgradeBundlePath, os.Getenv("AIRGAP_LICENSE_ID")) }, @@ -2295,7 +2302,7 @@ func TestFiveNodesAirgapUpgrade(t *testing.T) { t.Logf("%s: preparing and installing embedded cluster on node 0", time.Now().Format(time.RFC3339)) installCommands := [][]string{ {"airgap-prepare.sh"}, - {"single-node-airgap-install.sh"}, + {"single-node-airgap-install.sh", initialVersion}, {"rm", "/assets/release.airgap"}, {"rm", "/usr/local/bin/embedded-cluster"}, } @@ -2363,7 +2370,7 @@ func TestFiveNodesAirgapUpgrade(t *testing.T) { } t.Logf("%s: checking installation state after app deployment", time.Now().Format(time.RFC3339)) - line := []string{"check-airgap-installation-state.sh", fmt.Sprintf("appver-%s-previous-k0s", os.Getenv("SHORT_SHA")), k8sVersionPrevious()} + line := []string{"check-airgap-installation-state.sh", initialVersion, k8sVersionPrevious()} if _, _, err := tc.RunCommandOnNode(0, line); err != nil { t.Fatalf("fail to check installation state: %v", err) } @@ -2426,7 +2433,7 @@ func TestInstallWithPrivateCAs(t *testing.T) { }) t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339)) - line := []string{"single-node-install.sh", "ui", "--private-ca", "/tmp/ca.crt"} + line := []string{"single-node-install.sh", "ui", os.Getenv("SHORT_SHA"), "--private-ca", "/tmp/ca.crt"} if _, _, err := tc.RunCommandOnNode(0, line); err != nil { t.Fatalf("fail to install embedded-cluster on node %s: %v", tc.Nodes[0], err) } @@ -2501,7 +2508,7 @@ spec: } t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339)) - line = []string{"single-node-install.sh", "ui", "--config-values", "/assets/config-values.yaml"} + line = []string{"single-node-install.sh", "ui", os.Getenv("SHORT_SHA"), "--config-values", "/assets/config-values.yaml"} 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) } @@ -2549,9 +2556,10 @@ func TestSingleNodeAirgapUpgradeConfigValues(t *testing.T) { t.Logf("%s: downloading airgap files", time.Now().Format(time.RFC3339)) airgapInstallBundlePath := "/tmp/airgap-install-bundle.tar.gz" airgapUpgradeBundlePath := "/tmp/airgap-upgrade-bundle.tar.gz" + initialVersion := fmt.Sprintf("appver-%s-previous-k0s", os.Getenv("SHORT_SHA")) runInParallel(t, func(t *testing.T) error { - return downloadAirgapBundle(t, fmt.Sprintf("appver-%s-previous-k0s", os.Getenv("SHORT_SHA")), airgapInstallBundlePath, os.Getenv("AIRGAP_LICENSE_ID")) + return downloadAirgapBundle(t, initialVersion, airgapInstallBundlePath, os.Getenv("AIRGAP_LICENSE_ID")) }, func(t *testing.T) error { return downloadAirgapBundle(t, fmt.Sprintf("appver-%s-upgrade", os.Getenv("SHORT_SHA")), airgapUpgradeBundlePath, os.Getenv("AIRGAP_LICENSE_ID")) }, @@ -2610,7 +2618,7 @@ spec: } t.Logf("%s: installing embedded-cluster on node 0", time.Now().Format(time.RFC3339)) - line = []string{"single-node-airgap-install.sh", "--local-artifact-mirror-port", "50001", "--config-values", "/assets/config-values.yaml"} // choose an alternate lam port + line = []string{"single-node-airgap-install.sh", initialVersion, "--local-artifact-mirror-port", "50001", "--config-values", "/assets/config-values.yaml"} // choose an alternate lam port if _, _, err := tc.RunCommandOnNode(0, line); err != nil { t.Fatalf("fail to install embedded-cluster on node %s: %v", tc.Nodes[0], err) } @@ -2621,7 +2629,7 @@ spec: } t.Logf("%s: checking installation state after app deployment", time.Now().Format(time.RFC3339)) - line = []string{"check-airgap-installation-state.sh", fmt.Sprintf("appver-%s-previous-k0s", os.Getenv("SHORT_SHA")), k8sVersionPrevious()} + line = []string{"check-airgap-installation-state.sh", initialVersion, k8sVersionPrevious()} if _, _, err := tc.RunCommandOnNode(0, line); err != nil { t.Fatalf("fail to check installation state: %v", err) } diff --git a/e2e/proxy_test.go b/e2e/proxy_test.go index 4ece906b8..d4f612a5a 100644 --- a/e2e/proxy_test.go +++ b/e2e/proxy_test.go @@ -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 { @@ -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, ",")) @@ -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") diff --git a/e2e/reset_test.go b/e2e/reset_test.go index c5949d86e..1bad7e5ff 100644 --- a/e2e/reset_test.go +++ b/e2e/reset_test.go @@ -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) } diff --git a/e2e/restore_test.go b/e2e/restore_test.go index dc5c8c067..1e6d47ee5 100644 --- a/e2e/restore_test.go +++ b/e2e/restore_test.go @@ -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) } @@ -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) } @@ -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, ",")) @@ -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) } @@ -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 { @@ -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) } @@ -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) } diff --git a/e2e/scripts/common.sh b/e2e/scripts/common.sh index f4202693a..d1c11948d 100644 --- a/e2e/scripts/common.sh +++ b/e2e/scripts/common.sh @@ -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" @@ -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" @@ -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)" @@ -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" diff --git a/e2e/scripts/single-node-airgap-install.sh b/e2e/scripts/single-node-airgap-install.sh index b131040b4..f7ab3581a 100755 --- a/e2e/scripts/single-node-airgap-install.sh +++ b/e2e/scripts/single-node-airgap-install.sh @@ -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 @@ -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" diff --git a/e2e/scripts/single-node-install.sh b/e2e/scripts/single-node-install.sh index 67adc9a8b..22f948ff7 100755 --- a/e2e/scripts/single-node-install.sh +++ b/e2e/scripts/single-node-install.sh @@ -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 @@ -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" diff --git a/e2e/scripts/validate-support-bundle.sh b/e2e/scripts/validate-support-bundle.sh index 04138d9b1..177de69a1 100755 --- a/e2e/scripts/validate-support-bundle.sh +++ b/e2e/scripts/validate-support-bundle.sh @@ -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 "$@" diff --git a/e2e/support-bundle_test.go b/e2e/support-bundle_test.go index 41c3b17d6..cedc8e3c4 100644 --- a/e2e/support-bundle_test.go +++ b/e2e/support-bundle_test.go @@ -1,6 +1,7 @@ package e2e import ( + "os" "testing" "time" @@ -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) diff --git a/pkg/goods/support/host-support-bundle.tmpl.yaml b/pkg/goods/support/host-support-bundle.tmpl.yaml index f0801e2a9..a3a6614ed 100644 --- a/pkg/goods/support/host-support-bundle.tmpl.yaml +++ b/pkg/goods/support/host-support-bundle.tmpl.yaml @@ -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: