Skip to content

Commit bb8a857

Browse files
committed
Merge remote-tracking branch 'origin/main' into k0s-1-29
2 parents 240907a + cc46758 commit bb8a857

File tree

53 files changed

+798
-672
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+798
-672
lines changed

.github/workflows/release-prod.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,14 +428,14 @@ jobs:
428428
LICENSE_ID: ${{ secrets.STAGING_EMBEDDED_CLUSTER_LICENSE_ID }}
429429
run: |
430430
export APP_VERSION="appver-${{ github.ref_name }}"
431-
curl -L "https://ec-e2e-replicated-app.testcluster.net/embedded/embedded-cluster-smoke-test-staging-app/ci/${APP_VERSION}" -H "Authorization: $LICENSE_ID" -o embedded-cluster-smoke-test-staging-app-ci.tgz
431+
curl --retry 5 --retry-all-errors -fL -o embedded-cluster-smoke-test-staging-app-ci.tgz "https://ec-e2e-replicated-app.testcluster.net/embedded/embedded-cluster-smoke-test-staging-app/ci/${APP_VERSION}" -H "Authorization: $LICENSE_ID"
432432
tar -xzf embedded-cluster-smoke-test-staging-app-ci.tgz
433433
mv embedded-cluster-smoke-test-staging-app embedded-cluster
434434
mkdir -p output/bin
435435
mv embedded-cluster output/bin
436436
437437
# download the embedded-cluster binary from the github release
438-
curl -L "https://github.com/replicatedhq/embedded-cluster/releases/download/${{ github.ref_name }}/embedded-cluster-linux-amd64.tgz" -o embedded-cluster-github.tgz
438+
curl --retry 5 --retry-all-errors -fL -o embedded-cluster-github.tgz "https://github.com/replicatedhq/embedded-cluster/releases/download/${{ github.ref_name }}/embedded-cluster-linux-amd64.tgz"
439439
tar -xzf embedded-cluster-github.tgz
440440
mv embedded-cluster output/bin/embedded-cluster-original
441441

pkg/logging/logging.go renamed to cmd/installer/cli/logging.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
// Package logging manages setup of common logging interfaces and settings. We set the log
2-
// level to all levels but we only show on stdout the info, error, and fatal levels. All
3-
// other error levels are written only to a log file.
4-
package logging
1+
package cli
52

63
import (
74
"fmt"
@@ -13,6 +10,9 @@ import (
1310
"github.com/fatih/color"
1411
"github.com/replicatedhq/embedded-cluster/pkg/runtimeconfig"
1512
"github.com/sirupsen/logrus"
13+
ctrllog "sigs.k8s.io/controller-runtime/pkg/log"
14+
"sigs.k8s.io/controller-runtime/pkg/log/zap"
15+
ctrlzap "sigs.k8s.io/controller-runtime/pkg/log/zap"
1616
)
1717

1818
// MaxLogFiles is the maximum number of log files we keep.
@@ -111,11 +111,22 @@ func SetupLogging() {
111111
logpath := runtimeconfig.PathToLog(fname)
112112
logfile, err := os.OpenFile(logpath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0400)
113113
if err != nil {
114-
logrus.Warnf("unable to setup logging: %v", err)
114+
logrus.Warnf("Unable to setup logging: %v", err)
115115
return
116116
}
117117
logrus.SetOutput(logfile)
118118
logrus.AddHook(&StdoutLogger{})
119119
logrus.Debugf("command line: %v", os.Args)
120+
121+
setupCtrlLogging(logfile)
122+
120123
trimLogDir()
121124
}
125+
126+
// setupCtrlLogging sets up the logging for the controller-runtime package to the writer specified.
127+
func setupCtrlLogging(w io.Writer) {
128+
k8slogger := ctrlzap.New(func(o *zap.Options) {
129+
o.DestWriter = w
130+
})
131+
ctrllog.SetLogger(k8slogger)
132+
}

cmd/installer/cli/restore_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ import (
1111
k0sv1beta1 "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1"
1212
clitesting "github.com/replicatedhq/embedded-cluster/cmd/installer/cli/testing"
1313
"github.com/replicatedhq/embedded-cluster/pkg/disasterrecovery"
14+
"github.com/replicatedhq/embedded-cluster/pkg/kubeutils"
1415
"github.com/replicatedhq/embedded-cluster/pkg/release"
1516
"github.com/stretchr/testify/assert"
1617
"github.com/stretchr/testify/require"
1718
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
1819
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
19-
"k8s.io/kubectl/pkg/scheme"
2020
"k8s.io/utils/ptr"
2121
"sigs.k8s.io/controller-runtime/pkg/client"
2222
"sigs.k8s.io/controller-runtime/pkg/client/fake"
@@ -193,8 +193,7 @@ func Test_isReplicatedBackupRestorable(t *testing.T) {
193193
}
194194

195195
func Test_waitForBackups(t *testing.T) {
196-
scheme := scheme.Scheme
197-
velerov1.AddToScheme(scheme)
196+
scheme := kubeutils.Scheme
198197

199198
appendCommonAnnotations := func(annotations map[string]string) map[string]string {
200199
annotations["kots.io/embedded-cluster-version"] = "v0.0.0"

cmd/installer/cli/testing/assets/release-restore-newdr/restore.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ spec:
1717
- init:
1818
initContainers:
1919
- name: restore-hook-init1
20-
image: proxy.replicated.com/anonymous/nginx:1.24-alpine
20+
image: 'repl{{ LocalImageName "proxy.replicated.com/anonymous/nginx:1.24-alpine" }}'
2121
command:
2222
- /bin/ash
2323
- -c

cmd/installer/main.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,14 @@ import (
66
"path"
77

88
"github.com/mattn/go-isatty"
9-
109
"github.com/replicatedhq/embedded-cluster/cmd/installer/cli"
11-
"github.com/replicatedhq/embedded-cluster/pkg/logging"
1210
"github.com/replicatedhq/embedded-cluster/pkg/prompts"
1311
)
1412

1513
func main() {
1614
ctx := context.Background()
1715

18-
logging.SetupLogging()
16+
cli.SetupLogging()
1917

2018
prompts.SetTerminal(isatty.IsTerminal(os.Stdout.Fd()))
2119

e2e/kots-release-install-failing-preflights/restore.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ spec:
2020
- init:
2121
initContainers:
2222
- name: restore-hook-init1
23-
image: proxy.replicated.com/anonymous/nginx:1.24-alpine
23+
image: 'repl{{ LocalImageName "proxy.replicated.com/anonymous/nginx:1.24-alpine" }}'
2424
command:
2525
- /bin/ash
2626
- -c

e2e/kots-release-install-warning-preflights/restore.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ spec:
2020
- init:
2121
initContainers:
2222
- name: restore-hook-init1
23-
image: proxy.replicated.com/anonymous/nginx:1.24-alpine
23+
image: 'repl{{ LocalImageName "proxy.replicated.com/anonymous/nginx:1.24-alpine" }}'
2424
command:
2525
- /bin/ash
2626
- -c

e2e/kots-release-install/restore.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ spec:
2020
- init:
2121
initContainers:
2222
- name: restore-hook-init1
23-
image: proxy.replicated.com/anonymous/nginx:1.24-alpine
23+
image: 'repl{{ LocalImageName "proxy.replicated.com/anonymous/nginx:1.24-alpine" }}'
2424
command:
2525
- /bin/ash
2626
- -c

e2e/kots-release-unsupported-overrides/restore.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ spec:
2020
- init:
2121
initContainers:
2222
- name: restore-hook-init1
23-
image: proxy.replicated.com/anonymous/nginx:1.24-alpine
23+
image: 'repl{{ LocalImageName "proxy.replicated.com/anonymous/nginx:1.24-alpine" }}'
2424
command:
2525
- /bin/ash
2626
- -c

e2e/kots-release-upgrade/restore.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ spec:
2020
- init:
2121
initContainers:
2222
- name: restore-hook-init1
23-
image: proxy.replicated.com/anonymous/nginx:1.24-alpine
23+
image: 'repl{{ LocalImageName "proxy.replicated.com/anonymous/nginx:1.24-alpine" }}'
2424
command:
2525
- /bin/ash
2626
- -c

e2e/playwright/tests/deploy-upgrade/test.spec.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { test, expect, Page, FrameLocator } from '@playwright/test';
2-
import { login } from '../shared';
2+
import { login, vaidateAppAndClusterReady } from '../shared';
33

44
test('deploy upgrade', async ({ page }) => {
55
test.setTimeout(15 * 60 * 1000); // 15 minutes
@@ -59,7 +59,5 @@ async function verifyUpgradeSuccess(page: Page) {
5959
await expect(page.locator('.VersionHistoryRow', { hasText: process.env.APP_UPGRADE_VERSION })).toContainText('Currently deployed version', { timeout: 90 * 1000 });
6060
await page.getByRole('link', { name: 'Dashboard', exact: true }).click();
6161
await expect(page.locator('.VersionCard-content--wrapper')).toContainText(process.env.APP_UPGRADE_VERSION);
62-
await expect(page.locator('#app')).toContainText('Currently deployed version');
63-
await expect(page.locator('#app')).toContainText('Ready', { timeout: 30 * 1000 });
64-
await expect(page.locator('#app')).toContainText('Up to date');
62+
await vaidateAppAndClusterReady(page, expect, 10 * 1000);
6563
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { Page, Expect } from '@playwright/test';
2+
3+
export const vaidateAppAndClusterReady = async (page: Page, expect: Expect, initialTimeout: number) => {
4+
await page.getByRole('link', { name: 'Dashboard', exact: true }).click();
5+
await expect(page.locator('#app')).toContainText('Currently deployed version', { timeout: initialTimeout });
6+
await expect(page.locator('#app')).toContainText('Ready', { timeout: 45000 });
7+
await expect(page.locator('#app')).toContainText('Up to date');
8+
};

e2e/playwright/tests/shared/deploy-app.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Page, Expect } from '@playwright/test';
2+
import { vaidateAppAndClusterReady } from '.';
23

34
export const deployApp = async (page: Page, expect: Expect) => {
45
await expect(page.getByText('Optionally add nodes to the cluster'),).toBeVisible();
@@ -16,7 +17,5 @@ export const deployApp = async (page: Page, expect: Expect) => {
1617
await expect(page.getByRole('button', { name: 'Rerun' })).toBeVisible({ timeout: 10 * 1000 });
1718
await expect(page.locator('#app')).toContainText('The Volume Snapshots CRD exists');
1819
await page.getByRole('button', { name: 'Deploy' }).click();
19-
await expect(page.locator('#app')).toContainText('Currently deployed version', { timeout: 90000 });
20-
await expect(page.locator('#app')).toContainText('Ready', { timeout: 45000 });
21-
await expect(page.locator('#app')).toContainText('Up to date');
20+
await vaidateAppAndClusterReady(page, expect, 90000);
2221
};
Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
import { Page, Expect } from '@playwright/test';
2+
import { vaidateAppAndClusterReady } from '.';
23

34
export const deployEC18AppVersion = async (page: Page, expect: Expect) => {
4-
await expect(page.getByRole('button', { name: 'Add node', exact: true })).toBeVisible();
5-
await page.getByRole('button', { name: 'Continue' }).click();
6-
await expect(page.locator('h3')).toContainText('The First Config Group');
7-
await page.locator('input[type="text"]').click();
8-
await page.locator('input[type="text"]').fill('initial-hostname.com');
9-
await page.locator('input[type="password"]').click();
10-
await page.locator('input[type="password"]').fill('password');
11-
await page.getByRole('button', { name: 'Continue' }).click();
12-
await expect(page.getByText('Preflight checks', { exact: true })).toBeVisible({ timeout: 10 * 1000 });
13-
await expect(page.getByRole('button', { name: 'Re-run' })).toBeVisible({ timeout: 10 * 1000 });
14-
await expect(page.locator('#app')).toContainText('Embedded Cluster Installation CRD exists');
15-
await expect(page.locator('#app')).toContainText('Embedded Cluster Config CRD exists');
16-
await page.getByRole('button', { name: 'Deploy' }).click();
17-
await expect(page.locator('#app')).toContainText('Currently deployed version', { timeout: 90000 });
18-
await expect(page.locator('#app')).toContainText('Ready', { timeout: 45000 });
19-
await expect(page.locator('#app')).toContainText('Up to date');
20-
};
5+
await expect(page.getByRole('button', { name: 'Add node', exact: true })).toBeVisible();
6+
await page.getByRole('button', { name: 'Continue' }).click();
7+
await expect(page.locator('h3')).toContainText('The First Config Group');
8+
await page.locator('input[type="text"]').click();
9+
await page.locator('input[type="text"]').fill('initial-hostname.com');
10+
await page.locator('input[type="password"]').click();
11+
await page.locator('input[type="password"]').fill('password');
12+
await page.getByRole('button', { name: 'Continue' }).click();
13+
await expect(page.getByText('Preflight checks', { exact: true })).toBeVisible({ timeout: 10 * 1000 });
14+
await expect(page.getByRole('button', { name: 'Re-run' })).toBeVisible({ timeout: 10 * 1000 });
15+
await expect(page.locator('#app')).toContainText('Embedded Cluster Installation CRD exists');
16+
await expect(page.locator('#app')).toContainText('Embedded Cluster Config CRD exists');
17+
await page.getByRole('button', { name: 'Deploy' }).click();
18+
await vaidateAppAndClusterReady(page, expect, 90000);
19+
};

e2e/playwright/tests/shared/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from './login';
22
export * from './deploy-app';
3-
export * from './deploy-ec18-app-version';
3+
export * from './deploy-ec18-app-version';
4+
export * from './app-state';
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { test, expect } from '@playwright/test';
2+
import { login, vaidateAppAndClusterReady } from '../shared';
3+
4+
test('validate restore app', async ({ page }) => {
5+
test.setTimeout(5 * 60 * 1000); // 5 minutes
6+
await login(page);
7+
await vaidateAppAndClusterReady(page, expect, 90 * 1000);
8+
});

e2e/restore_test.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,14 @@ func TestSingleNodeDisasterRecovery(t *testing.T) {
9191
t.Fatalf("fail to check post-restore state: %v: %s: %s", err, stdout, stderr)
9292
}
9393

94+
t.Logf("%s: validating restored app", time.Now().Format(time.RFC3339))
95+
if err := tc.SetupPlaywright(); err != nil {
96+
t.Fatalf("fail to setup playwright: %v", err)
97+
}
98+
if _, _, err := tc.RunPlaywrightTest("validate-restore-app"); err != nil {
99+
t.Fatalf("fail to run playwright test validate-restore-app: %v", err)
100+
}
101+
94102
appUpgradeVersion := fmt.Sprintf("appver-%s-upgrade", os.Getenv("SHORT_SHA"))
95103
testArgs = []string{appUpgradeVersion}
96104

@@ -190,6 +198,14 @@ func TestSingleNodeLegacyDisasterRecovery(t *testing.T) {
190198
t.Fatalf("fail to check installation state: %v: %s: %s", err, stdout, stderr)
191199
}
192200

201+
t.Logf("%s: validating restored app", time.Now().Format(time.RFC3339))
202+
if err := tc.SetupPlaywright(); err != nil {
203+
t.Fatalf("fail to setup playwright: %v", err)
204+
}
205+
if _, _, err := tc.RunPlaywrightTest("validate-restore-app"); err != nil {
206+
t.Fatalf("fail to run playwright test validate-restore-app: %v", err)
207+
}
208+
193209
t.Logf("%s: test complete", time.Now().Format(time.RFC3339))
194210
}
195211

@@ -279,6 +295,14 @@ func TestSingleNodeDisasterRecoveryWithProxy(t *testing.T) {
279295
t.Fatalf("fail to check post-restore state: %v: %s: %s", err, stdout, stderr)
280296
}
281297

298+
t.Logf("%s: validating restored app", time.Now().Format(time.RFC3339))
299+
if err := tc.SetupPlaywright(); err != nil {
300+
t.Fatalf("fail to setup playwright: %v", err)
301+
}
302+
if _, _, err := tc.RunPlaywrightTest("validate-restore-app"); err != nil {
303+
t.Fatalf("fail to run playwright test validate-restore-app: %v", err)
304+
}
305+
282306
t.Logf("%s: test complete", time.Now().Format(time.RFC3339))
283307
}
284308

@@ -350,6 +374,20 @@ func TestSingleNodeResumeDisasterRecovery(t *testing.T) {
350374
t.Fatalf("fail to check installation state: %v: %s: %s", err, stdout, stderr)
351375
}
352376

377+
t.Logf("%s: checking post-restore state", time.Now().Format(time.RFC3339))
378+
line = []string{"check-post-restore.sh"}
379+
if stdout, stderr, err := tc.RunCommandOnNode(0, line); err != nil {
380+
t.Fatalf("fail to check post-restore state: %v: %s: %s", err, stdout, stderr)
381+
}
382+
383+
t.Logf("%s: validating restored app", time.Now().Format(time.RFC3339))
384+
if err := tc.SetupPlaywright(); err != nil {
385+
t.Fatalf("fail to setup playwright: %v", err)
386+
}
387+
if _, _, err := tc.RunPlaywrightTest("validate-restore-app"); err != nil {
388+
t.Fatalf("fail to run playwright test validate-restore-app: %v", err)
389+
}
390+
353391
t.Logf("%s: test complete", time.Now().Format(time.RFC3339))
354392
}
355393

@@ -461,6 +499,14 @@ func TestSingleNodeAirgapDisasterRecovery(t *testing.T) {
461499
t.Fatalf("fail to check post-restore state: %v: %s: %s", err, stdout, stderr)
462500
}
463501

502+
t.Logf("%s: validating restored app", time.Now().Format(time.RFC3339))
503+
if err := tc.SetupPlaywright(); err != nil {
504+
t.Fatalf("fail to setup playwright: %v", err)
505+
}
506+
if _, _, err := tc.RunPlaywrightTest("validate-restore-app"); err != nil {
507+
t.Fatalf("fail to run playwright test validate-restore-app: %v", err)
508+
}
509+
464510
t.Logf("%s: running airgap update", time.Now().Format(time.RFC3339))
465511
line = []string{"airgap-update.sh"}
466512
if _, _, err := tc.RunCommandOnNode(0, line); err != nil {
@@ -671,6 +717,14 @@ func TestMultiNodeHADisasterRecovery(t *testing.T) {
671717
t.Fatalf("fail to check post-restore state: %v: %s: %s", err, stdout, stderr)
672718
}
673719

720+
t.Logf("%s: validating restored app", time.Now().Format(time.RFC3339))
721+
if err := tc.SetupPlaywright(); err != nil {
722+
t.Fatalf("fail to setup playwright: %v", err)
723+
}
724+
if _, _, err := tc.RunPlaywrightTest("validate-restore-app"); err != nil {
725+
t.Fatalf("fail to run playwright test validate-restore-app: %v", err)
726+
}
727+
674728
appUpgradeVersion := fmt.Sprintf("appver-%s-upgrade", os.Getenv("SHORT_SHA"))
675729
testArgs = []string{appUpgradeVersion}
676730

@@ -947,6 +1001,14 @@ func TestMultiNodeAirgapHADisasterRecovery(t *testing.T) {
9471001
t.Fatalf("fail to check post-restore state: %v: %s: %s", err, stdout, stderr)
9481002
}
9491003

1004+
t.Logf("%s: validating restored app", time.Now().Format(time.RFC3339))
1005+
if err := tc.SetupPlaywright(withEnv); err != nil {
1006+
t.Fatalf("fail to setup playwright: %v", err)
1007+
}
1008+
if _, _, err := tc.RunPlaywrightTest("validate-restore-app"); err != nil {
1009+
t.Fatalf("fail to run playwright test validate-restore-app: %v", err)
1010+
}
1011+
9501012
t.Logf("%s: running airgap update", time.Now().Format(time.RFC3339))
9511013
line = []string{"airgap-update.sh"}
9521014
if _, _, err := tc.RunCommandOnNode(0, line); err != nil {

e2e/scripts/common.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,6 @@ check_pod_install_order() {
347347
local ingress_install_time=
348348
ingress_install_time=$(kubectl get pods --no-headers=true -n ingress-nginx -o jsonpath='{.items[*].metadata.creationTimestamp}' | sort | head -n 1)
349349

350-
351350
local openebs_install_time=
352351
openebs_install_time=$(kubectl get pods --no-headers=true -n openebs -o jsonpath='{.items[*].metadata.creationTimestamp}' | sort | head -n 1)
353352

@@ -377,7 +376,9 @@ install_kots_cli() {
377376
echo "installing kots cli"
378377
local ec_version=
379378
ec_version=$(embedded-cluster version | grep AdminConsole | awk '{print substr($4,2)}' | cut -d'-' -f1)
380-
curl "https://kots.io/install/$ec_version" | bash
379+
curl --retry 5 -fL -o /tmp/kotsinstall.sh "https://kots.io/install/$ec_version"
380+
chmod +x /tmp/kotsinstall.sh
381+
/tmp/kotsinstall.sh
381382
}
382383

383384
maybe_install_curl() {

0 commit comments

Comments
 (0)