Invoke `paccache` as part of the build service cleanup

This commit is contained in:
Martchus 2023-04-07 19:15:16 +02:00
parent 08af21ddb5
commit 836b7da8a3
4 changed files with 84 additions and 3 deletions

View File

@ -461,16 +461,41 @@ LibPkg::StorageID BuildAction::conclude(BuildActionResult result)
BuildServiceCleanup::BuildServiceCleanup(ServiceSetup &setup, const std::shared_ptr<BuildAction> &buildAction)
: InternalBuildAction(setup, buildAction)
, m_dbCleanupConcluded(false)
, m_cacheCleanupConcluded(false)
{
}
void BuildServiceCleanup::run()
{
// validate parameter
// validate parameter and read parameter/settings
if (auto error = validateParameter(RequiredDatabases::None, RequiredParameters::None); !error.empty()) {
reportError(std::move(error));
return;
}
const auto flags = static_cast<BuildServiceCleanupFlags>(m_buildAction->flags);
m_dryCacheCleanup = flags & BuildServiceCleanupFlags::DryPackageCacheCleanup;
// get variables from setup
auto setupLock = m_setup.lockToRead();
m_paccachePath = findExecutable(m_setup.building.paccachePath);
const auto packageCachePath = m_setup.building.packageCacheDir;
setupLock.unlock();
// find concrete cache dirs (packageCachePath does not contain arch subdir) and start invoking paccache
m_concreteCacheDirs.reserve(8);
for (auto i = boost::filesystem::directory_iterator(packageCachePath, boost::filesystem::directory_options::follow_directory_symlink);
auto entry : i) {
if (entry.path().filename_is_dot() || entry.path().filename_is_dot_dot()) {
continue;
}
auto canonical = boost::filesystem::canonical(entry.path());
if (boost::filesystem::is_directory(canonical)) {
m_concreteCacheDirs.emplace_back(entry.path().filename().string(), std::move(canonical));
}
}
m_concreteCacheDirsIterator = m_concreteCacheDirs.begin();
invokePaccache();
// iterate though build actions and delete those that are unlikely to be relevant anymore
auto count = std::size_t();
@ -491,7 +516,42 @@ void BuildServiceCleanup::run()
return --count <= stopAt;
},
&count);
auto lock = lockToWrite();
m_dbCleanupConcluded = true;
conclude(std::move(lock));
}
void BuildServiceCleanup::invokePaccache()
{
if (m_concreteCacheDirsIterator == m_concreteCacheDirs.end()) {
auto lock = lockToWrite();
m_cacheCleanupConcluded = true;
conclude(std::move(lock));
return;
}
const auto &cacheDirArch = m_concreteCacheDirsIterator->first;
const auto &cacheDirPath = m_concreteCacheDirsIterator->second;
auto processSession = m_buildAction->makeBuildProcess(
"paccache-" + cacheDirArch, "paccache-" % cacheDirArch + ".log", [this](boost::process::child &&child, ProcessResult &&result) {
CPP_UTILITIES_UNUSED(child)
if (result.errorCode) {
const auto errorMessage = result.errorCode.message();
m_errors.emplace_back("unable to invoke paccache: " + errorMessage);
} else if (result.exitCode != 0) {
m_errors.emplace_back(argsToString("paccache returned with exit code ", result.exitCode));
}
invokePaccache();
});
++m_concreteCacheDirsIterator;
processSession->launch(m_paccachePath, m_dryCacheCleanup ? "--dryrun" : "--remove", "--cachedir", cacheDirPath.string());
}
void BuildServiceCleanup::conclude(std::unique_lock<std::shared_mutex> &&lock)
{
if (!m_dbCleanupConcluded || !m_cacheCleanupConcluded) {
return;
}
lock.unlock();
const auto buildActionLock = m_setup.building.lockToWrite();
reportSuccess();
}

View File

@ -378,7 +378,14 @@ BuildActionMetaInfo::BuildActionMetaInfo()
.category = "Misc",
.name = "Clean build-service-internal data",
.type = "build-service-cleanup",
.flags = {},
.flags = {
BuildActionFlagMetaInfo{
.id = static_cast<BuildActionFlagType>(BuildServiceCleanupFlags::DryPackageCacheCleanup),
.name = "Dry package cache cleanup",
.desc = "Use --dryrun (instead of --remove) when invoking paccache",
.param = "dry-package-cache-cleanup",
},
},
.settings = {},
.directory = false,
.sourceDb = false,

View File

@ -94,6 +94,10 @@ enum class CleanRepositoryFlags : BuildActionFlagType {
None,
DryRun = (1 << 0),
};
enum class BuildServiceCleanupFlags : BuildActionFlagType {
None,
DryPackageCacheCleanup = (1 << 0),
};
enum class ReloadLibraryDependenciesSettings : std::size_t { PackageExcludeRegex };
enum class CheckForProblemsSettings : std::size_t { IgnoreDeps, IgnoreLibDeps };
enum class PrepareBuildSettings : std::size_t { PKGBUILDsDirs };
@ -197,6 +201,7 @@ CPP_UTILITIES_MARK_FLAG_ENUM_CLASS(LibRepoMgr, LibRepoMgr::ReloadLibraryDependen
CPP_UTILITIES_MARK_FLAG_ENUM_CLASS(LibRepoMgr, LibRepoMgr::PrepareBuildFlags)
CPP_UTILITIES_MARK_FLAG_ENUM_CLASS(LibRepoMgr, LibRepoMgr::ConductBuildFlags)
CPP_UTILITIES_MARK_FLAG_ENUM_CLASS(LibRepoMgr, LibRepoMgr::CleanRepositoryFlags)
CPP_UTILITIES_MARK_FLAG_ENUM_CLASS(LibRepoMgr, LibRepoMgr::BuildServiceCleanupFlags)
CPP_UTILITIES_MARK_FLAG_ENUM_CLASS(LibRepoMgr, LibRepoMgr::CheckForProblemsFlags)
#endif // LIBREPOMGR_BUILD_ACTION_META_H

View File

@ -675,11 +675,20 @@ private:
bool m_useContainer;
};
struct LIBREPOMGR_EXPORT BuildServiceCleanup : public InternalBuildAction {
struct LIBREPOMGR_EXPORT BuildServiceCleanup : public InternalBuildAction, private LibPkg::Lockable {
BuildServiceCleanup(ServiceSetup &setup, const std::shared_ptr<BuildAction> &buildAction);
void run();
private:
void invokePaccache();
void conclude(std::unique_lock<std::shared_mutex> &&lock);
boost::filesystem::path m_paccachePath;
std::vector<std::pair<std::string, boost::filesystem::path>> m_concreteCacheDirs;
std::vector<std::pair<std::string, boost::filesystem::path>>::iterator m_concreteCacheDirsIterator;
std::vector<std::string> m_errors;
bool m_dryCacheCleanup;
bool m_dbCleanupConcluded, m_cacheCleanupConcluded;
};
#ifdef LIBREPOMGR_DUMMY_BUILD_ACTION_ENABLED