Skip to content

Commit

Permalink
feat(upgrade): add force-upgrade flag for failed installations
Browse files Browse the repository at this point in the history
- Add --force-upgrade flag to porter upgrade command
- Implement ForceUpgrade option in UpgradeOptions struct
- Allow upgrades on failed installations when force-upgrade is true
- Add integration test for force-upgrade functionality

Signed-off-by: Kim Christensen <[email protected]>
  • Loading branch information
kichristensen committed Dec 1, 2024
1 parent 955f0e5 commit 9089b2b
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 1 deletion.
2 changes: 2 additions & 0 deletions cmd/porter/installations.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,8 @@ The docker driver runs the bundle container using the local Docker host. To use
"Namespace of the specified installation. Defaults to the global namespace.")
f.StringVar(&opts.Version, "version", "",
"Version to which the installation should be upgraded. This represents the version of the bundle, which assumes the convention of setting the bundle tag to its version.")
f.BoolVar(&opts.ForceUpgrade, "force-upgrade", false,
"Force the upgrade to run even if the current installation is marked as failed.")
addBundleActionFlags(f, opts)

// Allow configuring the --driver flag with runtime-driver, to avoid conflicts with other commands
Expand Down
5 changes: 4 additions & 1 deletion pkg/porter/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ type UpgradeOptions struct {

// Version of the bundle to upgrade to
Version string

// ForceUpgrade allows the upgrade to run even if the current installation is marked as failed.
ForceUpgrade bool
}

func NewUpgradeOptions() *UpgradeOptions {
Expand Down Expand Up @@ -64,7 +67,7 @@ func (p *Porter) UpgradeBundle(ctx context.Context, opts *UpgradeOptions) error
return span.Errorf("could not find installation %s/%s: %w", opts.Namespace, opts.Name, err)
}

if !i.IsInstalled() {
if !i.IsInstalled() && !opts.ForceUpgrade {
return span.Errorf("The installation cannot be upgraded, because it is not installed. Verify the installation name and namespace, and if correct, use porter install.")
}

Expand Down
23 changes: 23 additions & 0 deletions tests/integration/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,29 @@ func TestUpgrade_failedInstallation(t *testing.T) {
require.Error(t, err, "Upgrade should fail, because the installation failed")
}

func TestUpgrade_failedInstallation_withForceUpgrade(t *testing.T) {
p := porter.NewTestPorter(t)
defer p.Close()
ctx := p.SetupIntegrationTest()

p.AddTestBundleDir("testdata/bundles/bundle-with-failing-install", false)

installOpts := porter.NewInstallOptions()
err := installOpts.Validate(ctx, []string{}, p.Porter)
require.NoError(t, err)

err = p.InstallBundle(ctx, installOpts)
require.Error(t, err, "Installation should fail")

upgradeOpts := porter.NewUpgradeOptions()
upgradeOpts.ForceUpgrade = true
err = upgradeOpts.Validate(ctx, []string{}, p.Porter)
require.NoError(t, err)

err = p.UpgradeBundle(ctx, upgradeOpts)
require.NoError(t, err, "Upgrade should succeed, because force-upgrade is true")
}

func TestUpgrade_DebugModeAppliesToSingleInvocation(t *testing.T) {
p := porter.NewTestPorter(t)
defer p.Close()
Expand Down

0 comments on commit 9089b2b

Please sign in to comment.