Allow specifying locks when executing custom command
This commit is contained in:
parent
b7f27cb0a0
commit
aae5bf81f3
|
@ -306,6 +306,16 @@ BuildActionMetaInfo::BuildActionMetaInfo()
|
||||||
.desc = "The command to execute via Bash",
|
.desc = "The command to execute via Bash",
|
||||||
.param = "cmd",
|
.param = "cmd",
|
||||||
},
|
},
|
||||||
|
BuildActionSettingMetaInfo{
|
||||||
|
.name = "Shared locks",
|
||||||
|
.desc = "A comma-separated list of shared lock names to acquire",
|
||||||
|
.param = "shared-locks",
|
||||||
|
},
|
||||||
|
BuildActionSettingMetaInfo{
|
||||||
|
.name = "Unique locks",
|
||||||
|
.desc = "A comma-separated list of exclusive lock names to acquire",
|
||||||
|
.param = "exclusive-locks",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
.directory = true,
|
.directory = true,
|
||||||
.sourceDb = false,
|
.sourceDb = false,
|
||||||
|
|
|
@ -81,7 +81,7 @@ enum class CleanRepositoryFlags : BuildActionFlagType {
|
||||||
enum class CheckForProblemsSettings : std::size_t { IgnoreDeps, IgnoreLibDeps };
|
enum class CheckForProblemsSettings : std::size_t { IgnoreDeps, IgnoreLibDeps };
|
||||||
enum class PrepareBuildSettings : std::size_t { PKGBUILDsDirs };
|
enum class PrepareBuildSettings : std::size_t { PKGBUILDsDirs };
|
||||||
enum class ConductBuildSettings : std::size_t { ChrootDir, ChrootDefaultUser, CCacheDir, PackageCacheDir, TestFilesDir };
|
enum class ConductBuildSettings : std::size_t { ChrootDir, ChrootDefaultUser, CCacheDir, PackageCacheDir, TestFilesDir };
|
||||||
enum class CustomCommandSettings : std::size_t { Command };
|
enum class CustomCommandSettings : std::size_t { Command, SharedLocks, ExclusiveLocks };
|
||||||
|
|
||||||
struct LIBREPOMGR_EXPORT BuildActionFlagMetaInfo : public ReflectiveRapidJSON::JsonSerializable<BuildActionFlagMetaInfo> {
|
struct LIBREPOMGR_EXPORT BuildActionFlagMetaInfo : public ReflectiveRapidJSON::JsonSerializable<BuildActionFlagMetaInfo> {
|
||||||
const BuildActionFlagType id = 0;
|
const BuildActionFlagType id = 0;
|
||||||
|
|
|
@ -34,6 +34,8 @@ void CustomCommand::run()
|
||||||
auto metaInfoLock = metaInfo.lockToRead();
|
auto metaInfoLock = metaInfo.lockToRead();
|
||||||
const auto &typeInfo = metaInfo.typeInfoForId(BuildActionType::CustomCommand);
|
const auto &typeInfo = metaInfo.typeInfoForId(BuildActionType::CustomCommand);
|
||||||
const auto commandSetting = typeInfo.settings[static_cast<std::size_t>(CustomCommandSettings::Command)].param;
|
const auto commandSetting = typeInfo.settings[static_cast<std::size_t>(CustomCommandSettings::Command)].param;
|
||||||
|
const auto sharedLocksSetting = typeInfo.settings[static_cast<std::size_t>(CustomCommandSettings::SharedLocks)].param;
|
||||||
|
const auto exclusiveLocksSetting = typeInfo.settings[static_cast<std::size_t>(CustomCommandSettings::ExclusiveLocks)].param;
|
||||||
metaInfoLock.unlock();
|
metaInfoLock.unlock();
|
||||||
const auto &command = findSetting(commandSetting);
|
const auto &command = findSetting(commandSetting);
|
||||||
if (command.empty()) {
|
if (command.empty()) {
|
||||||
|
@ -54,7 +56,7 @@ void CustomCommand::run()
|
||||||
|
|
||||||
m_buildAction->appendOutput(Phrases::InfoMessage, "Running custom command: ", command, '\n');
|
m_buildAction->appendOutput(Phrases::InfoMessage, "Running custom command: ", command, '\n');
|
||||||
|
|
||||||
// launch process, pass finish handler
|
// prepare process and finish handler
|
||||||
auto process
|
auto process
|
||||||
= m_buildAction->makeBuildProcess("command", m_workingDirectory + "/the.log", [this](boost::process::child &&, ProcessResult &&result) {
|
= m_buildAction->makeBuildProcess("command", m_workingDirectory + "/the.log", [this](boost::process::child &&, ProcessResult &&result) {
|
||||||
if (result.errorCode) {
|
if (result.errorCode) {
|
||||||
|
@ -71,6 +73,25 @@ void CustomCommand::run()
|
||||||
const auto buildLock = m_setup.building.lockToWrite();
|
const auto buildLock = m_setup.building.lockToWrite();
|
||||||
reportSuccess();
|
reportSuccess();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// acquire locks
|
||||||
|
// note: Using an std::set here (instead of a std::vector) to ensure we don't attempt to acquire the same lock twice and to ensure
|
||||||
|
// locks are always acquired in the same order (to prevent deadlocks).
|
||||||
|
const auto sharedLockNames = splitStringSimple<std::set<std::string>>(findSetting(sharedLocksSetting), ",");
|
||||||
|
const auto exclusiveLockNames = splitStringSimple<std::set<std::string>>(findSetting(exclusiveLocksSetting), ",");
|
||||||
|
auto &locks = process->locks();
|
||||||
|
locks.reserve(sharedLockNames.size() + exclusiveLockNames.size());
|
||||||
|
for (const auto &lockName : sharedLockNames) {
|
||||||
|
if (!lockName.empty()) {
|
||||||
|
locks.emplace_back(m_setup.locks.acquireToRead(lockName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto &lockName : exclusiveLockNames) {
|
||||||
|
if (!lockName.empty()) {
|
||||||
|
locks.emplace_back(m_setup.locks.acquireToWrite(lockName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
process->launch(boost::process::start_dir(m_workingDirectory), boost::process::search_path("bash"), "-ec", command);
|
process->launch(boost::process::start_dir(m_workingDirectory), boost::process::search_path("bash"), "-ec", command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue