Package Kit & pkgman: Split cleanup operations into a "cleanup" command.

And only inform that some can be deleted at the end of install/uninstall.

As discussed in https://review.haiku-os.org/c/haiku/+/10711.
This commit is contained in:
Augustin Cavalier
2026-04-27 16:29:33 -04:00
parent 3a9a7e2188
commit 4dd45837e9
6 changed files with 147 additions and 9 deletions
@@ -25,6 +25,7 @@ public:
time_t cleanupBefore, int32 minStatesToKeep); time_t cleanupBefore, int32 minStatesToKeep);
virtual ~CleanUpAdminDirectoryRequest(); virtual ~CleanUpAdminDirectoryRequest();
status_t GetOldStatesCount(size_t& count);
virtual status_t CreateInitialJobs(); virtual status_t CreateInitialJobs();
private: private:
+1
View File
@@ -5,6 +5,7 @@ UsePrivateHeaders shared storage support ;
Application pkgman : Application pkgman :
Command.cpp Command.cpp
command_add_repo.cpp command_add_repo.cpp
command_cleanup.cpp
command_drop_repo.cpp command_drop_repo.cpp
command_full_sync.cpp command_full_sync.cpp
command_info.cpp command_info.cpp
+9 -9
View File
@@ -29,7 +29,6 @@
#include <package/solver/SolverProblemSolution.h> #include <package/solver/SolverProblemSolution.h>
#include "pkgman.h" #include "pkgman.h"
#include "JobStateListener.h"
using namespace BPackageKit::BPrivate; using namespace BPackageKit::BPrivate;
@@ -336,15 +335,16 @@ PackageManager::ProgressApplyingChangesDone(InstalledRepository& repository)
BInstallationLocationInfo info; BInstallationLocationInfo info;
if (BPackageRoster().GetInstallationLocationInfo(repository.Location(), info) == B_OK) { if (BPackageRoster().GetInstallationLocationInfo(repository.Location(), info) == B_OK) {
// Offer to delete older state and transaction directories. time_t before = time(NULL) - kCleanUpKeepDays * 24 * 60 * 60;
BJobStateListener listener; BJobStateListener listener;
BContext context(fDecisionProvider, listener); CleanUpAdminDirectoryRequest request(BContext(fDecisionProvider, listener),
info, before, kCleanUpKeepStates);
const int days = 30; size_t count;
time_t before = time(NULL) - days * 24 * 60 * 60; if (request.GetOldStatesCount(count) == B_OK && count > 0) {
printf("[%s] %" B_PRIuSIZE " old state(s) can be cleaned up. "
CleanUpAdminDirectoryRequest request(context, info, before, 10); "Use \"pkgman cleanup\" to remove them.\n",
request.Process(); repository.Name().String(), count);
}
} }
if (BPackageRoster().IsRebootNeeded()) if (BPackageRoster().IsRebootNeeded())
+110
View File
@@ -0,0 +1,110 @@
/*
* Copyright 2013-2025, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Ingo Weinhold <[email protected]>
* Humdinger <[email protected]>
* Adrien Destugues <[email protected]>
*/
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <package/PackageRoster.h>
#include <package/CleanUpAdminDirectoryRequest.h>
#include <Job.h>
#include "Command.h"
#include "DecisionProvider.h"
#include "pkgman.h"
// TODO: internationalization!
using namespace BPackageKit;
using namespace BPackageKit::BPrivate;
static const char* const kShortUsage =
" %command% [-H]\n"
" Cleans up old states and transactions in the administrative directory.\n";
static const char* const kLongUsage =
"Usage: %program% %command% [-H]\n"
"\n"
"Cleans up old states and transactions in the administrative directory.\n"
"\n"
"Options:\n"
" -H, --home\n"
" Clean up the administrative directoryin the user's home directory.\n"
" Default is to clean up the system directory.\n"
" -y\n"
" Non-interactive mode. Automatically confirm changes, but fail when\n"
" encountering problems.\n"
;
DEFINE_COMMAND(CleanupCommand, "cleanup", kShortUsage, kLongUsage,
COMMAND_CATEGORY_OTHER)
int
CleanupCommand::Execute(int argc, const char* const* argv)
{
BPackageInstallationLocation location
= B_PACKAGE_INSTALLATION_LOCATION_SYSTEM;
bool interactive = true;
while (true) {
static struct option sLongOptions[] = {
{ "debug", required_argument, 0, OPTION_DEBUG },
{ "help", no_argument, 0, 'h' },
{ "home", no_argument, 0, 'H' },
{ 0, 0, 0, 0 }
};
opterr = 0; // don't print errors
int c = getopt_long(argc, (char**)argv, "hHy", sLongOptions, NULL);
if (c == -1)
break;
if (fCommonOptions.HandleOption(c))
continue;
switch (c) {
case 'h':
PrintUsageAndExit(false);
break;
case 'H':
location = B_PACKAGE_INSTALLATION_LOCATION_HOME;
break;
case 'y':
interactive = false;
break;
default:
PrintUsageAndExit(true);
break;
}
}
BInstallationLocationInfo info;
status_t status = BPackageRoster().GetInstallationLocationInfo(location, info);
if (status == B_OK) {
DecisionProvider decisionProvider(interactive);
BSupportKit::BJobStateListener listener;
BContext context(decisionProvider, listener);
time_t before = time(NULL) - kCleanUpKeepDays * 24 * 60 * 60;
CleanUpAdminDirectoryRequest request(context, info, before, kCleanUpKeepStates);
status = request.Process();
}
return status;
}
+4
View File
@@ -43,4 +43,8 @@ void print_usage_and_exit(bool error);
#define COMMAND_CATEGORY_OTHER "other" #define COMMAND_CATEGORY_OTHER "other"
static const size_t kCleanUpKeepDays = 30;
static const size_t kCleanUpKeepStates = 10;
#endif // PKGMAN_H #endif // PKGMAN_H
@@ -39,6 +39,8 @@ protected:
virtual status_t Execute(); virtual status_t Execute();
private: private:
friend class CleanUpAdminDirectoryRequest;
status_t _GetOldStateDirectories(BStringList& directories); status_t _GetOldStateDirectories(BStringList& directories);
private: private:
@@ -191,6 +193,26 @@ CleanUpAdminDirectoryRequest::~CleanUpAdminDirectoryRequest()
} }
status_t
CleanUpAdminDirectoryRequest::GetOldStatesCount(size_t& count)
{
status_t status = InitCheck();
if (status != B_OK)
return B_NO_INIT;
CleanUpAdminDirectoryJob temp(fContext, "",
fLocationInfo, fCleanupBefore, fMinimumStatesToKeep);
BStringList dirs;
status = temp._GetOldStateDirectories(dirs);
if (status != B_OK)
return status;
count = dirs.CountStrings();
return B_OK;
}
status_t status_t
CleanUpAdminDirectoryRequest::CreateInitialJobs() CleanUpAdminDirectoryRequest::CreateInitialJobs()
{ {