From 65fe27ae14bc145e0f05729d399c290cc514cfb7 Mon Sep 17 00:00:00 2001 From: lw035596 Date: Wed, 15 Jan 2025 13:44:41 +0800 Subject: [PATCH] Allow to update the packageinstall with a difference packageName Signed-off-by: luwang --- .../cmd/package/installed/create_or_update.go | 15 ++++-- cli/test/e2e/package_install_test.go | 51 ++++++++++++++++--- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/cli/pkg/kctrl/cmd/package/installed/create_or_update.go b/cli/pkg/kctrl/cmd/package/installed/create_or_update.go index bfcbdea13..9f76515ef 100644 --- a/cli/pkg/kctrl/cmd/package/installed/create_or_update.go +++ b/cli/pkg/kctrl/cmd/package/installed/create_or_update.go @@ -767,13 +767,20 @@ func (o *CreateOrUpdateOptions) preparePackageInstallForUpdate(pkgInstall *kcpkg return nil, fmt.Errorf("Failed to update package '%s' as no existing package reference/version was found in the package install", o.Name) } - // If o.PackageName is provided by the user (via --package flag), verify that the package name in PackageInstall matches it. - // This will prevent the users from accidentally overwriting an installed package with another package content due to choosing a pre-existing name for the package isntall. + // If o.PackageName is provided by the user (via --package flag) is not the same as the the package name in PackageInstall + // Ask users for confirmation // Otherwise if o.PackageName is not provided, fill it from the installed package spec if o.packageName != "" && updatedPkgInstall.Spec.PackageRef.RefName != o.packageName { - return nil, fmt.Errorf("Installed package '%s' is already associated with package '%s'", o.Name, updatedPkgInstall.Spec.PackageRef.RefName) + o.ui.PrintLinef("Update package install '%s' from packageName '%s' to packageName '%s'", o.Name, updatedPkgInstall.Spec.PackageRef.RefName, o.packageName) + + err := o.ui.AskForConfirmation() + if err != nil { + return nil, err + } + updatedPkgInstall.Spec.PackageRef.RefName = o.packageName + } else { + o.packageName = updatedPkgInstall.Spec.PackageRef.RefName } - o.packageName = updatedPkgInstall.Spec.PackageRef.RefName // If o.Version is provided by the user (via --version flag), set the version in PackageInstall to this version // Otherwise if o.Version is not provided, fill it from the installed package spec diff --git a/cli/test/e2e/package_install_test.go b/cli/test/e2e/package_install_test.go index 71272b025..40acfdfaf 100644 --- a/cli/test/e2e/package_install_test.go +++ b/cli/test/e2e/package_install_test.go @@ -23,20 +23,23 @@ func TestPackageInstalled(t *testing.T) { appName := "test-package-name" pkgiName := "testpkgi" packageMetadataName := "test-pkg.carvel.dev" + packageMetadataNameNew := "test-pkg.carvel-new.dev" - packageMetadata := fmt.Sprintf(`--- + packageMetadataCR := `--- apiVersion: data.packaging.carvel.dev/v1alpha1 kind: PackageMetadata metadata: name: %s spec: displayName: "Carvel Test Package" - shortDescription: "Carvel package for testing installation"`, packageMetadataName) + shortDescription: "Carvel package for testing installation"` + + packageMetadata := fmt.Sprintf(packageMetadataCR, packageMetadataName) + packageMetadataNew := fmt.Sprintf(packageMetadataCR, packageMetadataNameNew) - packageName1 := "test-pkg.carvel.dev.1.0.0" - packageName2 := "test-pkg.carvel.dev.2.0.0" packageVersion1 := "1.0.0" packageVersion2 := "2.0.0" + packageVersion3 := "3.0.0" packageCR := `--- apiVersion: data.packaging.carvel.dev/v1alpha1 @@ -44,7 +47,7 @@ kind: Package metadata: name: %s spec: - refName: test-pkg.carvel.dev + refName: %s version: %s template: spec: @@ -69,12 +72,16 @@ key1: value1 valuesFile2 := ` key2: value2 ` + valuesFile3 := ` +key3: value3 +` + packageCR1 := fmt.Sprintf(packageCR, packageMetadataName+"."+packageVersion1, packageMetadataName, packageVersion1) - packageCR1 := fmt.Sprintf(packageCR, packageName1, packageVersion1) + packageCR2 := fmt.Sprintf(packageCR, packageMetadataName+"."+packageVersion2, packageMetadataName, packageVersion2) - packageCR2 := fmt.Sprintf(packageCR, packageName2, packageVersion2) + packageCR3 := fmt.Sprintf(packageCR, packageMetadataNameNew+"."+packageVersion3, packageMetadataNameNew, packageVersion3) - yaml := packageMetadata + "\n" + packageCR1 + "\n" + packageCR2 + yaml := packageMetadata + "\n" + packageCR1 + "\n" + packageCR2 + packageMetadataNew + "\n" + packageCR3 cleanUp := func() { // TODO: Check for error while uninstalling in cleanup? @@ -218,6 +225,34 @@ key2: value2 require.Exactly(t, expectedOutputRows, output.Tables[0].Rows) }) + logger.Section("package installed update with changing packageName", func() { + _, err := kappCtrl.RunWithOpts([]string{ + "package", "installed", "update", + "--package-install", pkgiName, + "-p", packageMetadataNameNew, + "--version", packageVersion3, + "--values-file", "-", + "-y", + }, RunOpts{StdinReader: strings.NewReader(valuesFile3)}) + require.NoError(t, err) + + out, err := kappCtrl.RunWithOpts([]string{"package", "installed", "get", "--package-install", pkgiName, "--json"}, RunOpts{}) + require.NoError(t, err) + + output := uitest.JSONUIFromBytes(t, []byte(out)) + + expectedOutputRows := []map[string]string{{ + "conditions": "- type: ReconcileSucceeded\n status: \"True\"\n reason: \"\"\n message: \"\"", + "namespace": env.Namespace, + "name": "testpkgi", + "package_name": packageMetadataNameNew, + "package_version": packageVersion3, + "status": "Reconcile succeeded", + }} + + require.Exactly(t, expectedOutputRows, output.Tables[0].Rows) + }) + logger.Section("package installed pause", func() { _, err := kappCtrl.RunWithOpts([]string{