Skip to content

Commit

Permalink
Allow upgrade of failed installations (#3269)
Browse files Browse the repository at this point in the history
feat(upgrade): add force-upgrade flag for failed installations

- 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 <kimworking@gmail.com>
  • Loading branch information
kichristensen authored Dec 5, 2024
1 parent dcd45df commit 6c56f35
Show file tree
Hide file tree
Showing 5 changed files with 31 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
1 change: 1 addition & 0 deletions docs/content/docs/references/cli/installations_upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ porter installations upgrade [INSTALLATION] [flags]
-d, --driver string Specify a driver to use. Allowed values: docker, debug (default "docker")
-f, --file porter.yaml Path to the Porter manifest. Defaults to porter.yaml in the current directory.
--force Force a fresh pull of the bundle
--force-upgrade Force the upgrade to run even if the current installation is marked as failed.
-h, --help help for upgrade
--insecure-registry Don't require TLS for the registry
--mount-host-volume stringArray Mount a host volume into the bundle. Format is <host path>:<container path>[:<option>]. May be specified multiple times. Option can be ro (read-only), rw (read-write), default is ro.
Expand Down
1 change: 1 addition & 0 deletions docs/content/docs/references/cli/upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ porter upgrade [INSTALLATION] [flags]
-d, --driver string Specify a driver to use. Allowed values: docker, debug (default "docker")
-f, --file porter.yaml Path to the Porter manifest. Defaults to porter.yaml in the current directory.
--force Force a fresh pull of the bundle
--force-upgrade Force the upgrade to run even if the current installation is marked as failed.
-h, --help help for upgrade
--insecure-registry Don't require TLS for the registry
--mount-host-volume stringArray Mount a host volume into the bundle. Format is <host path>:<container path>[:<option>]. May be specified multiple times. Option can be ro (read-only), rw (read-write), default is ro.
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 6c56f35

Please sign in to comment.