Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
36fcdf0
Add rancherupgrade package: Longhorn pre/post/chart-upgrade validation
floatingman Oct 8, 2026
f563865
Add validation/Jenkinsfile.rancher-upgrade.e2e six-stage upgrade orch…
floatingman Oct 8, 2026
3e14ff9
Add awsNodeTemplate to upgrade cattle-config for SG authorization
floatingman Oct 8, 2026
90381bd
Make repo/executor params sticky against declarative parameter sync
floatingman Oct 8, 2026
263293c
Wait up to ten minutes for the checksum PVC to bind
floatingman Oct 8, 2026
bd78700
Collect failure diagnostics before destroy and image cleanup
floatingman Oct 8, 2026
c1237a5
Smoke-check the rotated token and the dispatched config post-upgrade
floatingman Oct 8, 2026
a5420c2
Accept the insecure LB cert in the rotated-token smoke check
floatingman Oct 8, 2026
ae95642
Export the token before yq injection (empty-adminToken 401 root cause)
floatingman Oct 8, 2026
739d5ac
Address PR review: phase progress logs, build-pinned image tags
floatingman Oct 8, 2026
b14003d
fix: decide teardown in post.always, defer artifact removal to cleanup
floatingman Oct 19, 2026
84bac3d
Address PR review: pit.weekly build tag, skip suite outside the upgra…
floatingman Oct 20, 2026
0848729
Address PR review: fail on pipeline misconfig via rancherUpgradePipel…
floatingman Oct 20, 2026
da60028
Address PR 986 review findings: checksum validation, stale catalog gu…
floatingman Oct 21, 2026
a19485d
Address hamistao review findings: dedupe deployment helper, clarify v…
floatingman Oct 21, 2026
8164583
Add SUSE Observability suite to rancherupgrade (rancher/tests#971)
floatingman Oct 22, 2026
c670078
Retry ClusterRepo creation across fresh-cluster settling
floatingman Oct 25, 2026
ee7b5df
Poll for the fresh ClusterRepo's chart version before resolving
floatingman Oct 25, 2026
1196215
Retry the large StackState chart action POSTs
floatingman Oct 26, 2026
7ef8dcc
Pre-warm the chart template before StackState chart actions
floatingman Oct 26, 2026
56a3ae1
Capture Rancher server logs when the chart action fails
floatingman Oct 26, 2026
2ab0f66
Let the chart action create the StackState namespaces
floatingman Oct 26, 2026
0a77374
Fix retry spacing: the delay polls returned instantly
floatingman Oct 26, 2026
a868983
Capture install diagnostics from every replica plus the operation CR
floatingman Oct 26, 2026
1bf61c3
Pass the cluster-prefixed System project ID to the chart actions
floatingman Oct 26, 2026
711abd4
Align the server values with chart 2.12.0 and capture helm operation …
floatingman Oct 26, 2026
d9b6b0e
Carry a thirty-minute helm timeout on the StackState chart actions
floatingman Oct 26, 2026
9adfd9a
Outlive the helm deadline in the app watches
floatingman Oct 26, 2026
d170321
Make the observability pre-upgrade re-entrant and fail fast
floatingman Oct 26, 2026
79aab1d
Install suse-observability with the 10-nonha sizing profile
floatingman Oct 26, 2026
fa9ba63
Dump namespace workload state in install diagnostics
floatingman Oct 26, 2026
89f3215
Raise the stackstate helm action timeout to forty-five minutes
floatingman Oct 26, 2026
aeacda8
Provide a default storage class for the suse-observability install
floatingman Oct 26, 2026
09e89f3
Capture crash evidence in the workload diagnostics
floatingman Oct 26, 2026
bae9751
Slim the evidence harness to the proxied k8s client
floatingman Oct 27, 2026
5ecf85d
Give the split server components memory limits their JVM flags fit
floatingman Oct 27, 2026
0830f9c
Surface error lines from crashed containers' previous logs
floatingman Oct 27, 2026
dad3d04
Install the suse-observability server in global configuration mode
floatingman Oct 27, 2026
41023fc
Install the agent from the suse-observability prime repo
floatingman Oct 27, 2026
ae241ae
Capture diagnostics on agent install failure too
floatingman Oct 27, 2026
cdcd3f5
Slim the evidence harness to the proxied k8s client
floatingman Oct 27, 2026
2d3f7f0
Dump reassembled catalog index chunks in the evidence harness
floatingman Oct 27, 2026
dacd44f
Point the agent install action at the suse-observability repo
floatingman Oct 27, 2026
b5aef2b
Seed the pre-upgrade install with the previous stable chart version
floatingman Oct 27, 2026
d1d171a
Retry app watches on transient stream drops, drop pending-upgrade wat…
floatingman Oct 27, 2026
012ebce
Gate upgrade watches on pending-upgrade before the new deployed state
floatingman Oct 27, 2026
7f83e53
Remove the throwaway evidence harness
floatingman Oct 27, 2026
df398b1
Make the pre-upgrade readiness poll and seed resolution read as two s…
floatingman Oct 27, 2026
3d3eb53
Capture diagnostics on the observability chart-upgrade failure path
floatingman Oct 27, 2026
48a3472
Capture namespace events in the workload diagnostics
floatingman Oct 27, 2026
3a8f3c2
fix: address observability review feedback
floatingman Oct 27, 2026
4a6e42c
fix: use the renamed agent chart name in retry labels
floatingman Oct 27, 2026
70d35ad
Rename observability_test.go to observability_upgrade_test.go
floatingman Oct 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions actions/charts/longhorn.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"fmt"

catalogv1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1"
"github.com/rancher/shepherd/clients/rancher"
"github.com/rancher/shepherd/clients/rancher/catalog"
shepherdCharts "github.com/rancher/shepherd/extensions/charts"
Expand Down Expand Up @@ -100,6 +101,123 @@ func InstallLonghornChart(client *rancher.Client, payload PayloadOpts, values ma
return err
}

// UpgradeLonghornChart upgrades the longhorn and longhorn-crd charts to
// installOptions.Version on installOptions.Cluster and waits for Deployed state.
// No session cleanup is registered: the uninstall cleanup belongs to the install
// call of the same session, and upgrade-test sessions must not delete the chart.
func UpgradeLonghornChart(client *rancher.Client, installOptions *InstallOptions) error {
serverSetting, err := client.Management.Setting.ByID(serverURLSettingID)
if err != nil {
return err
}

registrySetting, err := client.Management.Setting.ByID(defaultRegistrySettingID)
if err != nil {
return err
}

longhornChartUpgradeActionPayload := &PayloadOpts{
InstallOptions: *installOptions,
Name: LonghornChartName,
Namespace: LonghornNamespace,
Host: serverSetting.Value,
DefaultRegistry: registrySetting.Value,
}

chartUpgradeAction := newLonghornChartUpgradeAction(longhornChartUpgradeActionPayload)

catalogClient, err := client.GetClusterCatalogClient(installOptions.Cluster.ID)
if err != nil {
return err
}

bodyBytes, err := json.Marshal(chartUpgradeAction)
if err != nil {
return err
}
err = ChartActionWithRetry(context.TODO(), client, verbUpgrade, longhornChartUpgradeActionPayload, catalog.RancherChartRepo, []string{LonghornChartName, LonghornChartName + "-crd"}, buildRepoActionRequest(catalogClient, catalog.RancherChartRepo, verbUpgrade, bodyBytes))
if err != nil {
return err
}

adminClient, err := rancher.NewClient(client.RancherConfig.AdminToken, client.Session)
if err != nil {
return err
}

adminCatalogClient, err := adminClient.GetClusterCatalogClient(installOptions.Cluster.ID)
if err != nil {
return err
}

watchAppInterface, err := adminCatalogClient.Apps(LonghornNamespace).Watch(context.TODO(), metav1.ListOptions{
FieldSelector: "metadata.name=" + LonghornChartName,
TimeoutSeconds: &defaults.WatchTimeoutSeconds,
})
if err != nil {
return err
}

err = wait.WatchWait(watchAppInterface, func(event watch.Event) (ready bool, err error) {
app := event.Object.(*catalogv1.App)

state := app.Status.Summary.State
if state == string(catalogv1.StatusPendingUpgrade) {
return true, nil
}

return false, nil
})
if err != nil {
return err
}

watchAppInterface, err = adminCatalogClient.Apps(LonghornNamespace).Watch(context.TODO(), metav1.ListOptions{
FieldSelector: "metadata.name=" + LonghornChartName,
TimeoutSeconds: &defaults.WatchTimeoutSeconds,
})
if err != nil {
return err
}

err = wait.WatchWait(watchAppInterface, func(event watch.Event) (ready bool, err error) {
app := event.Object.(*catalogv1.App)

state := app.Status.Summary.State
if state == string(catalogv1.StatusDeployed) {
return true, nil
}

return false, nil
})
if err != nil {
return err
}

err = shepherdCharts.WatchAndWaitDeployments(client, installOptions.Cluster.ID, LonghornNamespace, metav1.ListOptions{})
if err != nil {
return err
}

return shepherdCharts.WatchAndWaitDaemonSets(client, installOptions.Cluster.ID, LonghornNamespace, metav1.ListOptions{})
}

// newLonghornChartUpgradeAction is a private helper function that returns the chart upgrade action for Longhorn.
func newLonghornChartUpgradeAction(p *PayloadOpts) *types.ChartUpgradeAction {
// Pass the deletingConfirmationFlag value on the main chart so the upgrade does
// not reset it; the CRD chart takes no Longhorn settings (same split as install).
chartUpgrade := NewChartUpgrade(p.Name, p.Name, p.Version, p.Cluster.ID, p.Cluster.Name, p.Host, p.DefaultRegistry, enableDeletionSetting)
chartUpgradeCRD := NewChartUpgrade(p.Name+"-crd", p.Name+"-crd", p.Version, p.Cluster.ID, p.Cluster.Name, p.Host, p.DefaultRegistry, nil)
chartUpgrades := []types.ChartUpgrade{*chartUpgradeCRD, *chartUpgrade}

chartUpgradeAction := NewChartUpgradeAction(p.Namespace, chartUpgrades)
// Disable OpenAPI validation to avoid schema-conflict failures on the large
// Longhorn CRDs, which frequently change shape between versions.
chartUpgradeAction.DisableOpenAPIValidation = true

return chartUpgradeAction
}

// UninstallLonghornChart removes Longhorn from the cluster related to the received catalog client object.
func UninstallLonghornChart(client *rancher.Client, namespace string, clusterID string, rancherHostname string) error {
catalogClient, err := client.GetClusterCatalogClient(clusterID)
Expand Down
40 changes: 40 additions & 0 deletions actions/clusters/local.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package clusters

import (
"context"
"errors"
"fmt"
"regexp"
"strings"
"time"

"github.com/Masterminds/semver/v3"
"github.com/rancher/shepherd/clients/rancher"
"github.com/rancher/shepherd/extensions/defaults"
"github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/util/wait"
)

const (
Expand Down Expand Up @@ -37,6 +42,41 @@ func IsRancherVersionAbove(client *rancher.Client, minVersion string) (bool, err
return serverVersion.GreaterThan(minimumVersion), nil
}

// WaitRancherVersion polls the management server-version setting until it equals
// targetVersion (semver-compared) or timeout elapses. Gates post-upgrade assertions
// on Rancher server convergence; transient read errors during the upgrade rollout
// are retried, not returned.
func WaitRancherVersion(client *rancher.Client, targetVersion string, timeout time.Duration) error {
target, err := parseRancherVersion(targetVersion)
if err != nil {
return err
}

return wait.PollUntilContextTimeout(context.Background(), defaults.TenSecondTimeout, timeout, true, func(ctx context.Context) (done bool, err error) {
serverVersionRawValue, err := client.Management.Setting.ByID(serverVersionSetting)
if err != nil {
// The server may be mid-restart during the upgrade rollout; retry the read.
// Logged so a terminal cause (e.g. a revoked token or unreachable API)
// is visible in the log instead of surfacing only as the final timeout.
logrus.Debugf("server-version read failed, retrying: %v", err)
return false, nil
}

serverVersion, err := parseRancherVersion(serverVersionRawValue.Value)
if err != nil {
logrus.Debugf("server-version value %q not parseable yet, retrying: %v", serverVersionRawValue.Value, err)
return false, nil
}

if serverVersion.Equal(target) {
return true, nil
}

logrus.Debugf("Rancher server version is %q, waiting for %q", serverVersionRawValue.Value, targetVersion)
return false, nil
})
}

func parseRancherVersion(versionInput string) (*semver.Version, error) {
trimmedVersion := strings.TrimSpace(strings.TrimPrefix(versionInput, "v"))
if trimmedVersion == "" {
Expand Down
Loading
Loading