Skip to content

Commit 98261f3

Browse files
Merge remote-tracking branch 'origin/main' into k0s-1-28-7
2 parents e6ed679 + 00ddf9d commit 98261f3

File tree

25 files changed

+234
-774
lines changed

25 files changed

+234
-774
lines changed

.github/actions/e2e/action.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ inputs:
1313
license:
1414
description: 'license (b64) to use for e2e tests'
1515
required: true
16+
testim-access-token:
17+
description: 'testim access token'
18+
required: true
19+
testim-branch:
20+
description: 'testim branch'
21+
required: true
1622

1723
runs:
1824
using: composite
@@ -52,4 +58,6 @@ runs:
5258
export LICENSE_ID=${{ inputs.license-id }}
5359
export AIRGAP_LICENSE_ID=${{ inputs.airgap-license-id }}
5460
echo "${{ inputs.license }}" | base64 --decode > e2e/license.yaml
61+
export TESTIM_ACCESS_TOKEN=${{ inputs.testim-access-token }}
62+
export TESTIM_BRANCH=${{ inputs.testim-branch }}
5563
make e2e-test TEST_NAME=${{ inputs.test-name }}

.github/workflows/pull-request.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ jobs:
4141
build:
4242
name: Build
4343
runs-on: ubuntu-latest
44+
permissions:
45+
pull-requests: write
4446
steps:
4547
- name: Checkout
4648
uses: actions/checkout@v4
@@ -86,6 +88,7 @@ jobs:
8688
export SHORT_SHA=dev-$(git rev-parse --short=7 HEAD)
8789
echo "# channel release object" > e2e/kots-release-install/release.yaml
8890
echo 'channelID: "2cHXb1RCttzpR0xvnNWyaZCgDBP"' >> e2e/kots-release-install/release.yaml
91+
echo 'channelSlug: "ci"' >> e2e/kots-release-install/release.yaml
8992
echo 'appSlug: "embedded-cluster-smoke-test-staging-app"' >> e2e/kots-release-install/release.yaml
9093
echo "versionLabel: \"appver-${SHORT_SHA}\"" >> e2e/kots-release-install/release.yaml
9194
cat e2e/kots-release-install/release.yaml
@@ -117,6 +120,22 @@ jobs:
117120
rm e2e/kots-release-install/release.yaml
118121
replicated release create --yaml-dir e2e/kots-release-install --promote CI-airgap --version "appver-${SHORT_SHA}"
119122
123+
- name: Create download link message text
124+
run: |
125+
export SHORT_SHA=dev-$(git rev-parse --short=7 HEAD)
126+
127+
echo "This PR has been released (on staging) and is available for download with a embedded-cluster-smoke-test-staging-app [license ID](https://vendor.staging.replicated.com/apps/embedded-cluster-smoke-test-staging-app/customers?sort=name-asc)." > download-link.txt
128+
echo "\`\`\`" >> download-link.txt
129+
echo "curl https://staging.replicated.app/embedded/embedded-cluster-smoke-test-staging-app/ci/${SHORT_SHA} -H \"Authorization: \$EC_SMOKE_TEST_LICENSE_ID\" -o embedded-cluster-smoke-test-staging-app-ci.tgz" >> download-link.txt
130+
echo "\`\`\`" >> download-link.txt
131+
echo "Happy debugging!" >> download-link.txt
132+
cat download-link.txt
133+
134+
- name: comment download link
135+
uses: mshick/add-pr-comment@v2
136+
with:
137+
message-path: download-link.txt
138+
120139
- name: upload binary
121140
uses: actions/upload-artifact@v4
122141
with:
@@ -166,3 +185,5 @@ jobs:
166185
airgap-license-id: ${{ secrets.STAGING_EMBEDDED_CLUSTER_AIRGAP_LICENSE_ID }}
167186
license-id: ${{ secrets.STAGING_EMBEDDED_CLUSTER_LICENSE_ID }}
168187
license: ${{ secrets.STAGING_EMBEDDED_CLUSTER_LICENSE }}
188+
testim-access-token: ${{ secrets.TESTIM_ACCESS_TOKEN }}
189+
testim-branch: ${{ github.head_ref == 'main' && 'master' || github.head_ref }}

.github/workflows/release-dev.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ jobs:
6565
export SHORT_SHA=dev-$(git rev-parse --short=7 HEAD)
6666
echo "# channel release object" > e2e/kots-release-install/release.yaml
6767
echo 'channelID: "2cHXb1RCttzpR0xvnNWyaZCgDBP"' >> e2e/kots-release-install/release.yaml
68+
echo 'channelSlug: "ci"' >> e2e/kots-release-install/release.yaml
6869
echo 'appSlug: "embedded-cluster-smoke-test-staging-app"' >> e2e/kots-release-install/release.yaml
6970
echo "versionLabel: \"appver-${SHORT_SHA}\"" >> e2e/kots-release-install/release.yaml
7071
cat e2e/kots-release-install/release.yaml
@@ -143,3 +144,5 @@ jobs:
143144
airgap-license-id: ${{ secrets.STAGING_EMBEDDED_CLUSTER_AIRGAP_LICENSE_ID }}
144145
license-id: ${{ secrets.STAGING_EMBEDDED_CLUSTER_LICENSE_ID }}
145146
license: ${{ secrets.STAGING_EMBEDDED_CLUSTER_LICENSE }}
147+
testim-access-token: ${{ secrets.TESTIM_ACCESS_TOKEN }}
148+
testim-branch: 'master'

Makefile

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ ARCH := $(shell uname -m)
44
APP_NAME = embedded-cluster
55
ADMIN_CONSOLE_CHART_URL = oci://registry.replicated.com/library
66
ADMIN_CONSOLE_CHART_NAME = admin-console
7-
ADMIN_CONSOLE_CHART_VERSION = 1.108.3-build.1
7+
ADMIN_CONSOLE_CHART_VERSION = 1.108.5
88
ADMIN_CONSOLE_IMAGE_OVERRIDE =
99
ADMIN_CONSOLE_MIGRATIONS_IMAGE_OVERRIDE =
1010
EMBEDDED_OPERATOR_CHART_URL = oci://registry.replicated.com/library
1111
EMBEDDED_OPERATOR_CHART_NAME = embedded-cluster-operator
12-
EMBEDDED_OPERATOR_CHART_VERSION = 0.26.0
12+
EMBEDDED_OPERATOR_CHART_VERSION = 0.27.0
1313
EMBEDDED_OPERATOR_UTILS_IMAGE = busybox:1.36.1
14+
EMBEDDED_CLUSTER_OPERATOR_IMAGE_OVERRIDE =
1415
OPENEBS_CHART_URL = https://openebs.github.io/charts
1516
OPENEBS_CHART_NAME = openebs/openebs
1617
OPENEBS_CHART_VERSION = 3.10.0
@@ -22,7 +23,7 @@ REGISTRY_IMAGE_VERSION = 2.8.3
2223
KUBECTL_VERSION = v1.28.7
2324
K0S_VERSION = v1.28.7+k0s.0
2425
K0S_BINARY_SOURCE_OVERRIDE =
25-
TROUBLESHOOT_VERSION = v0.84.1
26+
TROUBLESHOOT_VERSION = v0.86.0
2627
KOTS_VERSION = v$(shell echo $(ADMIN_CONSOLE_CHART_VERSION) | sed 's/\([0-9]\+\.[0-9]\+\.[0-9]\+\).*/\1/')
2728
LD_FLAGS = -X github.com/replicatedhq/embedded-cluster/pkg/defaults.K0sVersion=$(K0S_VERSION) \
2829
-X github.com/replicatedhq/embedded-cluster/pkg/defaults.Version=$(VERSION) \
@@ -38,6 +39,7 @@ LD_FLAGS = -X github.com/replicatedhq/embedded-cluster/pkg/defaults.K0sVersion=$
3839
-X github.com/replicatedhq/embedded-cluster/pkg/addons/embeddedclusteroperator.ChartName=$(EMBEDDED_OPERATOR_CHART_NAME) \
3940
-X github.com/replicatedhq/embedded-cluster/pkg/addons/embeddedclusteroperator.Version=$(EMBEDDED_OPERATOR_CHART_VERSION) \
4041
-X github.com/replicatedhq/embedded-cluster/pkg/addons/embeddedclusteroperator.UtilsImage=$(EMBEDDED_OPERATOR_UTILS_IMAGE) \
42+
-X github.com/replicatedhq/embedded-cluster/pkg/addons/embeddedclusteroperator.ImageOverride=$(EMBEDDED_CLUSTER_OPERATOR_IMAGE_OVERRIDE) \
4143
-X github.com/replicatedhq/embedded-cluster/pkg/addons/openebs.ChartURL=$(OPENEBS_CHART_URL) \
4244
-X github.com/replicatedhq/embedded-cluster/pkg/addons/openebs.ChartName=$(OPENEBS_CHART_NAME) \
4345
-X github.com/replicatedhq/embedded-cluster/pkg/addons/openebs.Version=$(OPENEBS_CHART_VERSION) \

cmd/embedded-cluster/join_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010

1111
"github.com/k0sproject/dig"
1212
k0sconfig "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1"
13-
embeddedclusterv1beta1 "github.com/replicatedhq/embedded-cluster-operator/api/v1beta1"
13+
embeddedclusterv1beta1 "github.com/replicatedhq/embedded-cluster-kinds/apis/v1beta1"
1414
"github.com/stretchr/testify/assert"
1515
"github.com/stretchr/testify/require"
1616
"gopkg.in/yaml.v3"

cmd/local-artifact-mirror/pull.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
"k8s.io/apimachinery/pkg/types"
1414
"sigs.k8s.io/controller-runtime/pkg/client"
1515

16-
"github.com/replicatedhq/embedded-cluster-operator/api/v1beta1"
16+
"github.com/replicatedhq/embedded-cluster-kinds/apis/v1beta1"
1717
"github.com/replicatedhq/embedded-cluster/pkg/defaults"
1818
"github.com/replicatedhq/embedded-cluster/pkg/helpers"
1919
"github.com/replicatedhq/embedded-cluster/pkg/kubeutils"
@@ -189,6 +189,15 @@ var binariesCommand = &cli.Command{
189189
}
190190

191191
logrus.Infof("embedded cluster binaries materialized")
192+
193+
targetBinaryName := filepath.Join(defaults.EmbeddedClusterBinsSubDir(), EmbeddedClusterBinaryArtifactName)
194+
if in.Spec.BinaryName != "" {
195+
targetBinaryName = filepath.Join(defaults.EmbeddedClusterBinsSubDir(), in.Spec.BinaryName)
196+
}
197+
198+
if err := helpers.MoveFile(bin, targetBinaryName); err != nil {
199+
return fmt.Errorf("unable to move embedded-cluster binary: %w", err)
200+
}
192201
return nil
193202
},
194203
}

e2e/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,21 @@ https://vendor.staging.replicated.com/apps/embedded-cluster-smoke-test-staging-a
6666
Make sure to update the application yaml files under kots-release-onmerge
6767
and kots-release-onpr directories if you create a new release of the remote
6868
application.
69+
70+
### Testim
71+
72+
We use [Testim](https://www.testim.io/) to run end to end tests on the UI. The tests live within the
73+
"Embedded Cluster" Testim project.
74+
75+
When a git branch is pushed to GitHub, a cooresponding branch is created in
76+
Testim. The on-PR tests will run against the matching branch in Testim, so if you need
77+
to make changes to the tests as part of your PR, you should make those updates in your
78+
Testim branch.
79+
80+
When a PR is merged, the on-merge tests will run against the master branch in Testim.
81+
If you have made changes to the tests in your Testim branch, you should merge those changes
82+
to the master branch in Testim when merging your PR. Similarly, if you rebase your git
83+
branch from main, you may need to "rebase" your Testim branch (merge changes from master)
84+
if there have been changes to the tests.
85+
86+
For more details on version control in Testim, refer to the [Testim documentation](https://help.testim.io/docs/version-control-branches).

e2e/install_test.go

Lines changed: 19 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package e2e
22

33
import (
4-
"encoding/json"
54
"fmt"
65
"net/http"
76
"os"
@@ -12,15 +11,6 @@ import (
1211
"github.com/replicatedhq/embedded-cluster/e2e/cluster"
1312
)
1413

15-
type clusterStatusResponse struct {
16-
App string `json:"app"`
17-
Cluster string `json:"cluster"`
18-
}
19-
20-
type nodeJoinResponse struct {
21-
Command string `json:"command"`
22-
}
23-
2414
func TestSingleNodeInstallation(t *testing.T) {
2515
t.Parallel()
2616
tc := cluster.NewTestCluster(&cluster.Input{
@@ -37,7 +27,7 @@ func TestSingleNodeInstallation(t *testing.T) {
3727
t.Fatalf("fail to install embedded-cluster on node %s: %v", tc.Nodes[0], err)
3828
}
3929

40-
runPuppeteerAppStatusCheck(t, 0, tc)
30+
installTestimAndDeploy(t, 0, tc)
4131

4232
t.Logf("%s: checking installation state after upgrade", time.Now().Format(time.RFC3339))
4333
line = []string{"check-postupgrade-state.sh", os.Getenv("SHORT_SHA")}
@@ -217,39 +207,35 @@ func TestMultiNodeInstallation(t *testing.T) {
217207
t.Fatalf("fail to install embedded-cluster on node %s: %v", tc.Nodes[0], err)
218208
}
219209

220-
runPuppeteerAppStatusCheck(t, 0, tc)
210+
installTestimAndDeploy(t, 0, tc)
221211

222212
// generate all node join commands (2 for controllers and 1 for worker).
223213
t.Logf("%s: generating two new controller token commands", time.Now().Format(time.RFC3339))
224214
controllerCommands := []string{}
225215
for i := 0; i < 2; i++ {
226-
line := []string{"puppeteer.sh", "generate-controller-join-token.js", "10.0.0.2"}
216+
line := []string{"testim.sh", os.Getenv("TESTIM_ACCESS_TOKEN"), os.Getenv("TESTIM_BRANCH"), "get-join-controller-command"}
227217
stdout, stderr, err := RunCommandOnNode(t, tc, 0, line)
228218
if err != nil {
229-
t.Fatalf("fail to generate controller join token: %s", stdout)
219+
t.Fatalf("fail to generate controller join token:\nstdout: %s\nstderr: %s", stdout, stderr)
230220
}
231-
var r nodeJoinResponse
232-
if err := json.Unmarshal([]byte(stdout), &r); err != nil {
233-
t.Logf("stdout: %s\nstderr: %s", stdout, stderr)
234-
t.Fatalf("fail to parse script response: %v", err)
221+
command, err := findJoinCommandInOutput(stdout)
222+
if err != nil {
223+
t.Fatalf("fail to find the join command in the output: %v", err)
235224
}
236-
// trim down the "./" and the "sudo" command as those are not needed. we run as
237-
// root and the embedded-cluster binary is on the PATH.
238-
command := strings.TrimPrefix(r.Command, "sudo ./")
239225
controllerCommands = append(controllerCommands, command)
240226
t.Log("controller join token command:", command)
241227
}
242228
t.Logf("%s: generating a new worker token command", time.Now().Format(time.RFC3339))
243-
line := []string{"puppeteer.sh", "generate-worker-join-token.js", "10.0.0.2"}
229+
line := []string{"testim.sh", os.Getenv("TESTIM_ACCESS_TOKEN"), os.Getenv("TESTIM_BRANCH"), "get-join-worker-command"}
244230
stdout, stderr, err := RunCommandOnNode(t, tc, 0, line)
245231
if err != nil {
246-
t.Fatalf("fail to generate controller join token: %s", stdout)
232+
t.Fatalf("fail to generate controller join token:\nstdout: %s\nstderr: %s", stdout, stderr)
247233
}
248-
var jr nodeJoinResponse
249-
if err := json.Unmarshal([]byte(stdout), &jr); err != nil {
250-
t.Logf("stdout: %s\nstderr: %s", stdout, stderr)
251-
t.Fatalf("fail to parse script response: %v", err)
234+
command, err := findJoinCommandInOutput(stdout)
235+
if err != nil {
236+
t.Fatalf("fail to find the join command in the output: %v", err)
252237
}
238+
t.Log("worker join token command:", command)
253239

254240
// join the nodes.
255241
for i, cmd := range controllerCommands {
@@ -267,8 +253,6 @@ func TestMultiNodeInstallation(t *testing.T) {
267253
t.Logf("node %d joined, sleeping...", node)
268254
time.Sleep(30 * time.Second)
269255
}
270-
command := strings.TrimPrefix(jr.Command, "sudo ./")
271-
t.Log("worker join token command:", command)
272256
t.Logf("%s: joining node 3 to the cluster as a worker", time.Now().Format(time.RFC3339))
273257
if _, _, err := RunCommandOnNode(t, tc, 3, strings.Split(command, " ")); err != nil {
274258
t.Fatalf("fail to join node 3 to the cluster as a worker: %v", err)
@@ -479,14 +463,15 @@ func TestSingleNodeAirgapInstallationUbuntuJammy(t *testing.T) {
479463
t.Logf("%s: test complete", time.Now().Format(time.RFC3339))
480464
}
481465

482-
func runPuppeteerAppStatusCheck(t *testing.T, node int, tc *cluster.Output) {
483-
t.Logf("%s: installing puppeteer on node %d", time.Now().Format(time.RFC3339), node)
484-
line := []string{"install-puppeteer.sh"}
466+
func installTestimAndDeploy(t *testing.T, node int, tc *cluster.Output) {
467+
t.Logf("%s: installing testim on node %d", time.Now().Format(time.RFC3339), node)
468+
line := []string{"install-testim.sh"}
485469
if _, _, err := RunCommandOnNode(t, tc, 0, line); err != nil {
486-
t.Fatalf("fail to install puppeteer on node %s: %v", tc.Nodes[0], err)
470+
t.Fatalf("fail to install testim on node %s: %v", tc.Nodes[0], err)
487471
}
472+
488473
t.Logf("%s: accessing kotsadm interface and deploying app", time.Now().Format(time.RFC3339))
489-
line = []string{"puppeteer.sh", "deploy-kots-application.js", "10.0.0.2"}
474+
line = []string{"testim.sh", os.Getenv("TESTIM_ACCESS_TOKEN"), os.Getenv("TESTIM_BRANCH"), "deploy-kots-application"}
490475
if _, _, err := RunCommandOnNode(t, tc, 0, line); err != nil {
491476
t.Fatalf("fail to access kotsadm interface and state: %v", err)
492477
}

e2e/reset_test.go

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package e2e
22

33
import (
4-
"encoding/json"
4+
"os"
55
"strings"
66
"testing"
77
"time"
@@ -28,39 +28,35 @@ func TestMultiNodeReset(t *testing.T) {
2828
t.Fatalf("fail to install embedded-cluster on node %s: %v", tc.Nodes[0], err)
2929
}
3030

31-
runPuppeteerAppStatusCheck(t, 0, tc)
31+
installTestimAndDeploy(t, 0, tc)
3232

3333
// generate all node join commands (2 for controllers and 1 for worker).
3434
t.Logf("%s: generating two new controller token commands", time.Now().Format(time.RFC3339))
3535
controllerCommands := []string{}
3636
for i := 0; i < 2; i++ {
37-
line := []string{"puppeteer.sh", "generate-controller-join-token.js", "10.0.0.2"}
37+
line := []string{"testim.sh", os.Getenv("TESTIM_ACCESS_TOKEN"), os.Getenv("TESTIM_BRANCH"), "get-join-controller-command"}
3838
stdout, stderr, err := RunCommandOnNode(t, tc, 0, line)
3939
if err != nil {
40-
t.Fatalf("fail to generate controller join token: %s", stdout)
40+
t.Fatalf("fail to generate controller join token:\nstdout: %s\nstderr: %s", stdout, stderr)
4141
}
42-
var r nodeJoinResponse
43-
if err := json.Unmarshal([]byte(stdout), &r); err != nil {
44-
t.Logf("stdout: %s\nstderr: %s", stdout, stderr)
45-
t.Fatalf("fail to parse script response: %v", err)
42+
command, err := findJoinCommandInOutput(stdout)
43+
if err != nil {
44+
t.Fatalf("fail to find the join command in the output: %v", err)
4645
}
47-
// trim down the "./" and the "sudo" command as those are not needed. we run as
48-
// root and the embedded-cluster binary is on the PATH.
49-
command := strings.TrimPrefix(r.Command, "sudo ./")
5046
controllerCommands = append(controllerCommands, command)
5147
t.Log("controller join token command:", command)
5248
}
5349
t.Logf("%s: generating a new worker token command", time.Now().Format(time.RFC3339))
54-
line := []string{"puppeteer.sh", "generate-worker-join-token.js", "10.0.0.2"}
50+
line := []string{"testim.sh", os.Getenv("TESTIM_ACCESS_TOKEN"), os.Getenv("TESTIM_BRANCH"), "get-join-worker-command"}
5551
stdout, stderr, err := RunCommandOnNode(t, tc, 0, line)
5652
if err != nil {
57-
t.Fatalf("fail to generate controller join token: %s", stdout)
53+
t.Fatalf("fail to generate worker join token:\nstdout: %s\nstderr: %s", stdout, stderr)
5854
}
59-
var jr nodeJoinResponse
60-
if err := json.Unmarshal([]byte(stdout), &jr); err != nil {
61-
t.Logf("stdout: %s\nstderr: %s", stdout, stderr)
62-
t.Fatalf("fail to parse script response: %v", err)
55+
command, err := findJoinCommandInOutput(stdout)
56+
if err != nil {
57+
t.Fatalf("fail to find the join command in the output: %v", err)
6358
}
59+
t.Log("worker join token command:", command)
6460

6561
// join the nodes.
6662
for i, cmd := range controllerCommands {
@@ -78,8 +74,6 @@ func TestMultiNodeReset(t *testing.T) {
7874
t.Logf("node %d joined, sleeping...", node)
7975
time.Sleep(30 * time.Second)
8076
}
81-
command := strings.TrimPrefix(jr.Command, "sudo ./")
82-
t.Log("worker join token command:", command)
8377
t.Logf("%s: joining node 3 to the cluster as a worker", time.Now().Format(time.RFC3339))
8478
if _, _, err := RunCommandOnNode(t, tc, 3, strings.Split(command, " ")); err != nil {
8579
t.Fatalf("fail to join node 3 to the cluster as a worker: %v", err)

0 commit comments

Comments
 (0)