2021-01-25 00:24:31 +01:00
|
|
|
#include "./buildactionprivate.h"
|
|
|
|
|
|
|
|
#include "../helper.h"
|
|
|
|
#include "../logging.h"
|
|
|
|
#include "../serversetup.h"
|
|
|
|
|
|
|
|
#include "../webclient/database.h"
|
|
|
|
|
|
|
|
#include "../webapi/params.h"
|
|
|
|
|
|
|
|
#include <c++utilities/conversion/stringbuilder.h>
|
|
|
|
#include <c++utilities/io/ansiescapecodes.h>
|
|
|
|
|
|
|
|
#include <boost/asio/post.hpp>
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
using namespace CppUtilities;
|
|
|
|
using namespace CppUtilities::EscapeCodes;
|
|
|
|
|
|
|
|
namespace LibRepoMgr {
|
|
|
|
|
|
|
|
ReloadDatabase::ReloadDatabase(ServiceSetup &setup, const std::shared_ptr<BuildAction> &buildAction)
|
|
|
|
: InternalBuildAction(setup, buildAction)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void ReloadDatabase::run()
|
|
|
|
{
|
2022-01-25 00:13:10 +01:00
|
|
|
const auto flags = static_cast<ReloadDatabaseFlags>(m_buildAction->flags);
|
|
|
|
const auto force = flags & ReloadDatabaseFlags::ForceReload;
|
2021-01-25 00:24:31 +01:00
|
|
|
const auto withFiles = m_setup.building.loadFilesDbs;
|
|
|
|
vector<LibPkg::Database *> dbsToLoadFromMirror;
|
|
|
|
|
|
|
|
auto configReadLock
|
|
|
|
= init(BuildActionAccess::ReadConfig, RequiredDatabases::MaybeDestination | RequiredDatabases::AllowToAur, RequiredParameters::None);
|
|
|
|
if (holds_alternative<monostate>(configReadLock)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto session
|
|
|
|
= WebClient::DatabaseQuerySession::create(m_setup.building.ioContext, [this](WebClient::DatabaseQuerySession::ContainerType &&failedDbs) {
|
2022-02-20 20:17:42 +01:00
|
|
|
// save state for "lastUpdate" timestamps
|
|
|
|
auto configReadLock2 = m_setup.config.lockToRead();
|
|
|
|
m_setup.saveState();
|
|
|
|
configReadLock2.unlock();
|
|
|
|
|
|
|
|
// conclude build action
|
2021-01-25 00:24:31 +01:00
|
|
|
if (!m_preparationFailures.empty()) {
|
|
|
|
mergeSecondVectorIntoFirstVector(failedDbs, m_preparationFailures);
|
|
|
|
}
|
|
|
|
if (!failedDbs.empty()) {
|
|
|
|
m_hasError = true;
|
|
|
|
reportError("Failed to reload the following databases, see logs for details: " + joinStrings(failedDbs, ", "));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (m_hasError) {
|
|
|
|
reportError("Errors occurred, see output log for details.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
auto buildActionWriteLock = m_setup.building.lockToWrite();
|
|
|
|
reportSuccess();
|
|
|
|
});
|
|
|
|
|
|
|
|
for (const auto &db : m_destinationDbs) {
|
|
|
|
// add database for syncing with mirror
|
|
|
|
if (db->syncFromMirror) {
|
|
|
|
dbsToLoadFromMirror.emplace_back(db);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// post job to reload database
|
|
|
|
auto dbPath = withFiles ? db->filesPath : db->path;
|
|
|
|
if (dbPath.empty()) {
|
|
|
|
m_hasError = true;
|
|
|
|
m_buildAction->appendOutput(
|
|
|
|
Phrases::ErrorMessage, "Unable to reload database database ", db->name, '@', db->arch, ": no path configured\n");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
boost::asio::post(
|
2022-01-25 00:13:10 +01:00
|
|
|
m_setup.building.ioContext.get_executor(), [this, force, session, dbName = db->name, dbArch = db->arch, dbPath = move(dbPath)]() mutable {
|
2021-01-25 00:24:31 +01:00
|
|
|
try {
|
2022-04-20 22:47:10 +02:00
|
|
|
auto configLock = m_setup.config.lockToRead();
|
2021-02-25 16:59:36 +01:00
|
|
|
auto dbFileLock = m_setup.locks.acquireToRead(m_buildAction->log(), ServiceSetup::Locks::forDatabase(dbName, dbArch));
|
2021-01-25 00:24:31 +01:00
|
|
|
const auto lastModified = LibPkg::lastModified(dbPath);
|
2022-01-25 00:13:10 +01:00
|
|
|
if (!force) {
|
|
|
|
auto configReadLock2 = m_setup.config.lockToRead();
|
|
|
|
auto *const destinationDb = m_setup.config.findDatabase(dbName, dbArch);
|
2022-03-05 18:55:52 +01:00
|
|
|
if (const auto lastUpdate = destinationDb->lastUpdate.load(); lastModified <= lastUpdate) {
|
2022-01-25 00:13:10 +01:00
|
|
|
configReadLock2.unlock();
|
|
|
|
m_buildAction->appendOutput(Phrases::InfoMessage, "Skip loading database \"", dbName, '@', dbArch,
|
|
|
|
"\" from local file \"", dbPath, "\"; last modification time <= last update (", lastModified.toString(), '<', '=',
|
|
|
|
lastUpdate.toString(), ')', '\n');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2022-04-18 20:39:02 +02:00
|
|
|
|
2022-01-25 00:13:10 +01:00
|
|
|
m_buildAction->appendOutput(
|
|
|
|
Phrases::InfoMessage, "Loading database \"", dbName, '@', dbArch, "\" from local file \"", dbPath, "\"\n");
|
2022-04-18 20:39:02 +02:00
|
|
|
|
2021-03-22 15:08:41 +01:00
|
|
|
auto *const destinationDb = m_setup.config.findDatabase(dbName, dbArch);
|
|
|
|
if (!destinationDb) {
|
2022-04-18 20:39:02 +02:00
|
|
|
configLock.unlock();
|
2021-01-25 00:24:31 +01:00
|
|
|
m_buildAction->appendOutput(
|
|
|
|
Phrases::ErrorMessage, "Loaded database file for \"", dbName, '@', dbArch, "\" but it no longer exists; discarding\n");
|
|
|
|
session->addResponse(std::move(dbName));
|
|
|
|
return;
|
|
|
|
}
|
2022-04-18 20:39:02 +02:00
|
|
|
|
|
|
|
auto updater = LibPkg::PackageUpdater(*destinationDb, true);
|
2022-04-20 22:47:10 +02:00
|
|
|
updater.insertFromDatabaseFile(dbPath);
|
|
|
|
dbFileLock.lock().unlock();
|
2022-04-18 20:39:02 +02:00
|
|
|
updater.commit();
|
|
|
|
destinationDb->lastUpdate = lastModified;
|
2021-01-25 00:24:31 +01:00
|
|
|
} catch (const std::runtime_error &e) {
|
|
|
|
m_buildAction->appendOutput(Phrases::ErrorMessage, "An error occurred when reloading database \"", dbName, '@', dbArch,
|
|
|
|
"\" from local file \"", dbPath, "\": ", e.what(), '\n');
|
|
|
|
session->addResponse(std::move(dbName));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// query databases
|
|
|
|
auto query = WebClient::prepareDatabaseQuery(m_buildAction->log(), dbsToLoadFromMirror, withFiles);
|
|
|
|
std::get<std::shared_lock<std::shared_mutex>>(configReadLock).unlock();
|
2022-01-25 00:13:10 +01:00
|
|
|
WebClient::queryDatabases(m_buildAction->log(), m_setup, std::move(query.queryParamsForDbs), session, force);
|
2021-01-25 00:24:31 +01:00
|
|
|
m_preparationFailures = std::move(query.failedDbs);
|
|
|
|
|
|
|
|
// clear AUR cache
|
|
|
|
if (m_toAur) {
|
2022-03-05 18:55:52 +01:00
|
|
|
auto lock = m_setup.config.lockToRead();
|
2021-01-25 00:24:31 +01:00
|
|
|
m_setup.config.aur.clearPackages();
|
|
|
|
lock.unlock();
|
|
|
|
m_buildAction->log()(Phrases::InfoMessage, "Cleared AUR cache\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace LibRepoMgr
|