diff --git a/changes/22571-fix-pkg-uninstall b/changes/22571-fix-pkg-uninstall new file mode 100644 index 000000000000..4118221f5f0b --- /dev/null +++ b/changes/22571-fix-pkg-uninstall @@ -0,0 +1 @@ +* Fixed software uninstaller script for `pkg`s to only remove '.app' directories installed by the package. diff --git a/ee/server/service/software_installers.go b/ee/server/service/software_installers.go index ac4461a592b2..8660e9dbb6f5 100644 --- a/ee/server/service/software_installers.go +++ b/ee/server/service/software_installers.go @@ -105,17 +105,13 @@ func preProcessUninstallScript(payload *fleet.UploadSoftwareInstallerPayload) { var packageID string switch payload.Extension { case "pkg": - var sb strings.Builder - _, _ = sb.WriteString("(\n") - for _, pkgID := range payload.PackageIDs { - _, _ = sb.WriteString(fmt.Sprintf(" \"%s\"\n", pkgID)) - } - _, _ = sb.WriteString(")") // no ending newline - packageID = sb.String() + // For pkgs we've decided to use the app's name instead of relying on pkgutil. + // See https://github.com/fleetdm/fleet/issues/22571. + // In future iterations we may start using the stored package_ids. + packageID = fmt.Sprintf("\"%s\"", payload.Title) default: packageID = fmt.Sprintf("\"%s\"", payload.PackageIDs[0]) } - payload.UninstallScript = packageIDRegex.ReplaceAllString(payload.UninstallScript, fmt.Sprintf("%s${suffix}", packageID)) } diff --git a/ee/server/service/software_installers_test.go b/ee/server/service/software_installers_test.go index 6abd95085eb5..54c7712d83e0 100644 --- a/ee/server/service/software_installers_test.go +++ b/ee/server/service/software_installers_test.go @@ -15,7 +15,7 @@ import ( func TestPreProcessUninstallScript(t *testing.T) { t.Parallel() - var input = ` + input := ` blah$PACKAGE_IDS pkgids=$PACKAGE_ID they are $PACKAGE_ID, right $MY_SECRET? @@ -42,6 +42,7 @@ quotes and braces for "com.foo" assert.Equal(t, expected, payload.UninstallScript) payload = fleet.UploadSoftwareInstallerPayload{ + Title: "Foo bar", Extension: "pkg", UninstallScript: input, PackageIDs: []string{"com.foo", "com.bar"}, @@ -49,32 +50,13 @@ quotes and braces for "com.foo" preProcessUninstallScript(&payload) expected = ` blah$PACKAGE_IDS -pkgids=( - "com.foo" - "com.bar" -) -they are ( - "com.foo" - "com.bar" -), right $MY_SECRET? -quotes for ( - "com.foo" - "com.bar" -) -blah( - "com.foo" - "com.bar" -)withConcat -quotes and braces for ( - "com.foo" - "com.bar" -) -( - "com.foo" - "com.bar" -)` +pkgids="Foo bar" +they are "Foo bar", right $MY_SECRET? +quotes for "Foo bar" +blah"Foo bar"withConcat +quotes and braces for "Foo bar" +"Foo bar"` assert.Equal(t, expected, payload.UninstallScript) - } func TestInstallUninstallAuth(t *testing.T) { @@ -93,7 +75,8 @@ func TestInstallUninstallAuth(t *testing.T) { }, nil } ds.GetSoftwareInstallerMetadataByTeamAndTitleIDFunc = func(ctx context.Context, teamID *uint, titleID uint, - withScriptContents bool) (*fleet.SoftwareInstaller, error) { + withScriptContents bool, + ) (*fleet.SoftwareInstaller, error) { return &fleet.SoftwareInstaller{ Name: "installer.pkg", Platform: "darwin", @@ -104,14 +87,16 @@ func TestInstallUninstallAuth(t *testing.T) { return nil, nil } ds.InsertSoftwareInstallRequestFunc = func(ctx context.Context, hostID uint, softwareInstallerID uint, selfService bool) (string, - error) { + error, + ) { return "request_id", nil } ds.GetAnyScriptContentsFunc = func(ctx context.Context, id uint) ([]byte, error) { return []byte("script"), nil } ds.NewHostScriptExecutionRequestFunc = func(ctx context.Context, request *fleet.HostScriptRequestPayload) (*fleet.HostScriptResult, - error) { + error, + ) { return &fleet.HostScriptResult{ ExecutionID: "execution_id", }, nil @@ -197,7 +182,6 @@ func TestUninstallSoftwareTitle(t *testing.T) { // Host scripts disabled host.ScriptsEnabled = ptr.Bool(false) require.ErrorContains(t, svc.UninstallSoftwareTitle(context.Background(), 1, 10), fleet.RunScriptsOrbitDisabledErrMsg) - } func checkAuthErr(t *testing.T, shouldFail bool, err error) { diff --git a/pkg/file/scripts/uninstall_pkg.sh b/pkg/file/scripts/uninstall_pkg.sh index 473cff971b49..3bddaaf57fd7 100644 --- a/pkg/file/scripts/uninstall_pkg.sh +++ b/pkg/file/scripts/uninstall_pkg.sh @@ -1,21 +1,18 @@ #!/bin/sh -# Fleet extracts and saves package IDs. -pkg_ids=$PACKAGE_ID +package_app_name="$PACKAGE_ID" -# Get all files associated with package and remove them -for pkg_id in "${pkg_ids[@]}" -do - # Get volume and location of package - volume=$(pkgutil --pkg-info "$pkg_id" | grep -i "volume" | awk '{for (i=2; i