Skip to content

Commit 76c2b2e

Browse files
committed
Merge remote-tracking branch 'origin/main' into k0s-1-28-10
2 parents f105536 + 0a5e7fc commit 76c2b2e

34 files changed

+701
-110
lines changed

.github/workflows/pull-request.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,10 @@ jobs:
5252
go-version-file: go.mod
5353

5454
- name: Set up Docker Buildx
55-
uses: docker/setup-buildx-action@v2
55+
uses: docker/setup-buildx-action@v3
5656

5757
- name: Login to Registry
58-
uses: docker/login-action@v2
58+
uses: docker/login-action@v3
5959
with:
6060
registry: registry.staging.replicated.com
6161
username: ${{ secrets.REGISTRY_USERNAME_STAGING }}

.github/workflows/release-dev.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ jobs:
1919
go-version-file: go.mod
2020

2121
- name: Set up Docker Buildx
22-
uses: docker/setup-buildx-action@v2
22+
uses: docker/setup-buildx-action@v3
2323

2424
- name: Login to Registry
25-
uses: docker/login-action@v2
25+
uses: docker/login-action@v3
2626
with:
2727
registry: registry.staging.replicated.com
2828
username: ${{ secrets.REGISTRY_USERNAME_STAGING }}

.github/workflows/release-prod.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ jobs:
2727
go-version-file: go.mod
2828

2929
- name: Set up Docker Buildx
30-
uses: docker/setup-buildx-action@v2
30+
uses: docker/setup-buildx-action@v3
3131

3232
- name: Login to Registry
33-
uses: docker/login-action@v2
33+
uses: docker/login-action@v3
3434
with:
3535
registry: registry.replicated.com
3636
username: ${{ secrets.REGISTRY_USERNAME_PRODUCTION }}
@@ -41,7 +41,7 @@ jobs:
4141
make build-and-push-local-artifact-mirror-image VERSION=$TAG_NAME
4242
4343
- name: Login to Registry
44-
uses: docker/login-action@v2
44+
uses: docker/login-action@v3
4545
with:
4646
registry: registry.staging.replicated.com
4747
username: ${{ secrets.REGISTRY_USERNAME_STAGING }}

Makefile

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +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.109.12
7+
ADMIN_CONSOLE_CHART_VERSION = 1.109.13
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
1212
EMBEDDED_OPERATOR_CHART_VERSION = 0.36.2
1313
EMBEDDED_OPERATOR_UTILS_IMAGE = busybox:1.36.1
14-
EMBEDDED_CLUSTER_OPERATOR_IMAGE_OVERRIDE =
14+
EMBEDDED_CLUSTER_OPERATOR_IMAGE_OVERRIDE =
1515
OPENEBS_CHART_URL = https://openebs.github.io/openebs
1616
OPENEBS_CHART_NAME = openebs/openebs
1717
OPENEBS_CHART_VERSION = 4.0.1
@@ -34,7 +34,7 @@ K0S_GO_VERSION = v1.28.10+k0s.0
3434
PREVIOUS_K0S_VERSION ?= v1.28.8+k0s.0
3535
K0S_BINARY_SOURCE_OVERRIDE =
3636
PREVIOUS_K0S_BINARY_SOURCE_OVERRIDE =
37-
TROUBLESHOOT_VERSION = v0.92.1
37+
TROUBLESHOOT_VERSION = v0.93.1
3838
KOTS_VERSION = v$(shell echo $(ADMIN_CONSOLE_CHART_VERSION) | sed 's/\([0-9]\+\.[0-9]\+\.[0-9]\+\).*/\1/')
3939
KOTS_BINARY_URL_OVERRIDE =
4040
LOCAL_ARTIFACT_MIRROR_IMAGE ?= registry.replicated.com/library/embedded-cluster-local-artifact-mirror
@@ -135,6 +135,7 @@ output/bin/embedded-cluster-release-builder:
135135
embedded-release: embedded-cluster-linux-amd64 output/tmp/release.tar.gz output/bin/embedded-cluster-release-builder
136136
./output/bin/embedded-cluster-release-builder output/bin/embedded-cluster output/tmp/release.tar.gz output/bin/embedded-cluster
137137

138+
.PHONY: go.mod
138139
go.mod: Makefile
139140
go get github.com/k0sproject/k0s@$(K0S_GO_VERSION)
140141
go mod tidy
@@ -146,7 +147,7 @@ static: pkg/goods/bins/k0s \
146147
pkg/goods/bins/kubectl-support_bundle \
147148
pkg/goods/bins/local-artifact-mirror \
148149
pkg/goods/internal/bins/kubectl-kots
149-
150+
150151
.PHONY: embedded-cluster-linux-amd64
151152
embedded-cluster-linux-amd64: static go.mod
152153
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "$(LD_FLAGS)" -o ./output/bin/$(APP_NAME) ./cmd/embedded-cluster

cmd/embedded-cluster/install.go

Lines changed: 108 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,17 @@ func RunHostPreflights(c *cli.Context) error {
8888
if err != nil {
8989
return fmt.Errorf("unable to read host preflights: %w", err)
9090
}
91+
92+
chpfs, err := preflights.GetClusterHostPreflights(c.Context)
93+
if err != nil {
94+
return fmt.Errorf("unable to get cluster host preflights: %w", err)
95+
}
96+
97+
for _, h := range chpfs {
98+
hpf.Collectors = append(hpf.Collectors, h.Spec.Collectors...)
99+
hpf.Analyzers = append(hpf.Analyzers, h.Spec.Analyzers...)
100+
}
101+
91102
return runHostPreflights(c, hpf)
92103
}
93104

@@ -96,25 +107,61 @@ func runHostPreflights(c *cli.Context, hpf *v1beta2.HostPreflightSpec) error {
96107
return nil
97108
}
98109
pb := spinner.Start()
99-
pb.Infof("Running host preflights on node")
110+
if c.Bool("skip-host-preflights") {
111+
pb.Infof("Skipping host preflights")
112+
pb.Close()
113+
return nil
114+
}
115+
pb.Infof("Running host preflights")
100116
output, err := preflights.Run(c.Context, hpf)
101117
if err != nil {
102118
pb.CloseWithError()
103119
return fmt.Errorf("host preflights failed: %w", err)
104120
}
121+
122+
err = output.SaveToDisk()
123+
if err != nil {
124+
pb.CloseWithError()
125+
return fmt.Errorf("failed to save preflights output: %w", err)
126+
}
127+
105128
if output.HasFail() {
129+
s := "failures"
130+
if len(output.Fail) == 1 {
131+
s = "failure"
132+
}
133+
msg := fmt.Sprintf("Host preflights have %d %s", len(output.Fail), s)
134+
if output.HasWarn() {
135+
s = "warnings"
136+
if len(output.Warn) == 1 {
137+
s = "warning"
138+
}
139+
msg += fmt.Sprintf(" and %d %s", len(output.Warn), s)
140+
}
141+
142+
pb.Errorf(msg)
106143
pb.CloseWithError()
107-
output.PrintTable()
144+
output.PrintTableWithoutInfo()
108145
return fmt.Errorf("preflights haven't passed on the host")
109146
}
110-
if !output.HasWarn() || c.Bool("no-prompt") {
147+
if !output.HasWarn() {
148+
pb.Close()
149+
return nil
150+
}
151+
if c.Bool("no-prompt") {
152+
// We have warnings but we are not in interactive mode
153+
// so we just print the warnings and continue
111154
pb.Close()
112-
output.PrintTable()
155+
output.PrintTableWithoutInfo()
113156
return nil
114157
}
158+
s := "warnings"
159+
if len(output.Warn) == 1 {
160+
s = "warning"
161+
}
162+
pb.Warnf("Host preflights have %d %s", len(output.Warn), s)
115163
pb.CloseWithError()
116-
output.PrintTable()
117-
logrus.Infof("Host preflights have warnings")
164+
output.PrintTableWithoutInfo()
118165
if !prompts.New().Confirm("Do you want to continue ?", false) {
119166
return fmt.Errorf("user aborted")
120167
}
@@ -136,7 +183,7 @@ func isAlreadyInstalled() (bool, error) {
136183
}
137184
}
138185

139-
func checkLicenseMatches(c *cli.Context) error {
186+
func checkLicenseMatches(licenseFile string) error {
140187
rel, err := release.GetChannelRelease()
141188
if err != nil {
142189
return fmt.Errorf("failed to get release from binary: %w", err) // this should only be if the release is malformed
@@ -146,20 +193,20 @@ func checkLicenseMatches(c *cli.Context) error {
146193
// 1. no release and no license, which is OK
147194
// 2. no license and a release, which is not OK
148195
// 3. a license and no release, which is not OK
149-
if rel == nil && c.String("license") == "" {
196+
if rel == nil && licenseFile == "" {
150197
// no license and no release, this is OK
151198
return nil
152-
} else if rel == nil && c.String("license") != "" {
199+
} else if rel == nil && licenseFile != "" {
153200
// license is present but no release, this means we would install without vendor charts and k0s overrides
154201
return fmt.Errorf("a license was provided but no release was found in binary, please rerun without the license flag")
155-
} else if rel != nil && c.String("license") == "" {
202+
} else if rel != nil && licenseFile == "" {
156203
// release is present but no license, this is not OK
157204
return fmt.Errorf("no license was provided for %s and one is required, please rerun with '--license <path to license file>'", rel.AppSlug)
158205
}
159206

160-
license, err := helpers.ParseLicense(c.String("license"))
207+
license, err := helpers.ParseLicense(licenseFile)
161208
if err != nil {
162-
return fmt.Errorf("unable to parse the license file at %q, please ensure it is not corrupt: %w", c.String("license"), err)
209+
return fmt.Errorf("unable to parse the license file at %q, please ensure it is not corrupt: %w", licenseFile, err)
163210
}
164211

165212
// Check if the license matches the application version data
@@ -173,6 +220,21 @@ func checkLicenseMatches(c *cli.Context) error {
173220
return fmt.Errorf("license channel %s (%s) does not match binary channel %s, please provide the correct license", license.Spec.ChannelID, license.Spec.ChannelName, rel.ChannelID)
174221
}
175222

223+
if license.Spec.Entitlements["expires_at"].Value.StrVal != "" {
224+
// read the expiration date, and check it against the current date
225+
expiration, err := time.Parse(time.RFC3339, license.Spec.Entitlements["expires_at"].Value.StrVal)
226+
if err != nil {
227+
return fmt.Errorf("unable to parse expiration date: %w", err)
228+
}
229+
if time.Now().After(expiration) {
230+
return fmt.Errorf("license expired on %s, please provide a valid license", expiration)
231+
}
232+
}
233+
234+
if !license.Spec.IsEmbeddedClusterDownloadEnabled {
235+
return fmt.Errorf("license does not have embedded cluster enabled, please provide a valid license")
236+
}
237+
176238
return nil
177239
}
178240

@@ -375,7 +437,7 @@ func waitForK0s() error {
375437
}
376438

377439
// runOutro calls Outro() in all enabled addons by means of Applier.
378-
func runOutro(c *cli.Context) error {
440+
func runOutro(c *cli.Context, adminConsolePwd string) error {
379441
os.Setenv("KUBECONFIG", defaults.PathToKubeConfig())
380442
opts := []addons.Option{}
381443

@@ -398,12 +460,33 @@ func runOutro(c *cli.Context) error {
398460
if ab := c.String("airgap-bundle"); ab != "" {
399461
opts = append(opts, addons.WithAirgapBundle(ab))
400462
}
463+
opts = append(opts, addons.WithAdminConsolePassword(adminConsolePwd))
401464
if c.String("http-proxy") != "" || c.String("https-proxy") != "" || c.String("no-proxy") != "" {
402465
opts = append(opts, addons.WithProxyFromArgs(c.String("http-proxy"), c.String("https-proxy"), c.String("no-proxy")))
403466
}
404467
return addons.NewApplier(opts...).Outro(c.Context)
405468
}
406469

470+
func askAdminConsolePassword(c *cli.Context) (string, error) {
471+
defaultPass := "password"
472+
if c.Bool("no-prompt") {
473+
logrus.Infof("Admin Console password set to: %s", defaultPass)
474+
return defaultPass, nil
475+
}
476+
maxTries := 3
477+
for i := 0; i < maxTries; i++ {
478+
promptA := prompts.New().Password("Enter an Admin Console password:")
479+
promptB := prompts.New().Password("Confirm password:")
480+
481+
if promptA == promptB {
482+
// TODO: Should we add extra password validation here? e.g length, complexity etc
483+
return promptA, nil
484+
}
485+
logrus.Info("Passwords don't match, please try again.")
486+
}
487+
return "", fmt.Errorf("unable to set Admin Console password after %d tries", maxTries)
488+
}
489+
407490
// installCommands executes the "install" command. This will ensure that a k0s.yaml file exists
408491
// and then run `k0s install` to apply the cluster. Once this is finished then a "kubeconfig"
409492
// file is created. Resulting kubeconfig is stored in the configuration dir.
@@ -461,6 +544,11 @@ var installCommand = &cli.Command{
461544
Usage: "Use the system proxy settings for the install operation. These variables are currently only passed through to Velero and the Admin Console.",
462545
Hidden: true,
463546
},
547+
&cli.BoolFlag{
548+
Name: "skip-host-preflights",
549+
Usage: "Skip host preflight checks. This is not recommended unless you are sure your system is compatible.",
550+
Value: false,
551+
},
464552
},
465553
Action: func(c *cli.Context) error {
466554
logrus.Debugf("checking if %s is already installed", binName)
@@ -479,7 +567,7 @@ var installCommand = &cli.Command{
479567
return fmt.Errorf("unable to configure network manager: %w", err)
480568
}
481569
logrus.Debugf("checking license matches")
482-
if err := checkLicenseMatches(c); err != nil {
570+
if err := checkLicenseMatches(c.String("license")); err != nil {
483571
metricErr := fmt.Errorf("unable to check license: %w", err)
484572
metrics.ReportApplyFinished(c, metricErr)
485573
return err // do not return the metricErr, as we want the user to see the error message without a prefix
@@ -495,6 +583,11 @@ var installCommand = &cli.Command{
495583
metrics.ReportApplyFinished(c, err)
496584
return err
497585
}
586+
adminConsolePwd, err := askAdminConsolePassword(c)
587+
if err != nil {
588+
metrics.ReportApplyFinished(c, err)
589+
return err
590+
}
498591
logrus.Debugf("running host preflights")
499592
if err := RunHostPreflights(c); err != nil {
500593
err := fmt.Errorf("unable to finish preflight checks: %w", err)
@@ -534,7 +627,7 @@ var installCommand = &cli.Command{
534627
return err
535628
}
536629
logrus.Debugf("running outro")
537-
if err := runOutro(c); err != nil {
630+
if err := runOutro(c, adminConsolePwd); err != nil {
538631
metrics.ReportApplyFinished(c, err)
539632
return err
540633
}

0 commit comments

Comments
 (0)