Compare commits

...
Author SHA1 Message Date
yp d3753a7e78 merge dev 2026-09-30 09:25:08 +03:00
dranik 0d1cfbaf19 Fix for creating child elements for a parent element 2026-06-12 11:25:06 +03:00
6 changed files with 94 additions and 7 deletions

No files matched your search

+2
View File
@@ -22,6 +22,7 @@ set(HEADERS ${HEADERS}
${CLIENT_ROOT_DIR}/core/controllers/coreSignalHandlers.h
${CLIENT_ROOT_DIR}/core/controllers/gatewayController.h
${CLIENT_ROOT_DIR}/core/utils/selfhosted/sshSession.h
${CLIENT_ROOT_DIR}/core/utils/selfhosted/sshExecutor.h
${CLIENT_ROOT_DIR}/core/controllers/serversController.h
${CLIENT_ROOT_DIR}/core/controllers/selfhosted/usersController.h
${CLIENT_ROOT_DIR}/core/controllers/selfhosted/installController.h
@@ -107,6 +108,7 @@ set(SOURCES ${SOURCES}
${CLIENT_ROOT_DIR}/core/controllers/coreSignalHandlers.cpp
${CLIENT_ROOT_DIR}/core/controllers/gatewayController.cpp
${CLIENT_ROOT_DIR}/core/utils/selfhosted/sshSession.cpp
${CLIENT_ROOT_DIR}/core/utils/selfhosted/sshExecutor.cpp
${CLIENT_ROOT_DIR}/core/controllers/serversController.cpp
${CLIENT_ROOT_DIR}/core/controllers/selfhosted/usersController.cpp
${CLIENT_ROOT_DIR}/core/controllers/selfhosted/installController.cpp
@@ -1,9 +1,9 @@
#include "coreSignalHandlers.h"
#include <QTimer>
#include <QtConcurrent>
#include "core/utils/selfhosted/sshSession.h"
#include "core/utils/selfhosted/sshExecutor.h"
#include "core/utils/errorCodes.h"
#include "core/utils/routeModes.h"
#include "core/controllers/coreController.h"
@@ -145,7 +145,7 @@ void CoreSignalHandlers::initExportControllerHandler()
});
connect(m_coreController->m_exportController, &ExportController::revokeClientRequested, this,
[this](const QString &serverId, int row, DockerContainer container) {
QtConcurrent::run([this, serverId, row, container]() {
SshExecutor::instance().run(serverId, [this, serverId, row, container]() {
m_coreController->m_usersController->revokeClient(serverId, row, container);
});
});
@@ -205,8 +205,10 @@ void CoreSignalHandlers::initAdminConfigRevokedHandler()
{
connect(m_coreController->m_installController, &InstallController::clientRevocationRequested, this,
[this](const QString &serverId, const ContainerConfig &containerConfig, DockerContainer container) {
m_coreController->m_usersController->revokeClient(serverId, containerConfig, container);
}, Qt::DirectConnection);
SshExecutor::instance().run(serverId, [this, serverId, containerConfig, container]() {
m_coreController->m_usersController->revokeClient(serverId, containerConfig, container);
});
});
connect(m_coreController->m_installController, &InstallController::clientAppendRequested, this,
[this](const QString &serverId, const QString &clientId, const QString &clientName, DockerContainer container) {
@@ -16,6 +16,7 @@
#include "core/utils/containers/containerUtils.h"
#include "core/utils/protocolEnum.h"
#include "core/utils/selfhosted/sshSession.h"
#include "core/utils/selfhosted/sshExecutor.h"
#include "core/installers/awgInstaller.h"
#include "core/installers/installerBase.h"
#include "core/installers/openvpnInstaller.h"
@@ -104,6 +105,7 @@ InstallController::~InstallController()
ErrorCode InstallController::setupContainer(const ServerCredentials &credentials, DockerContainer container, ContainerConfig &config,
bool isUpdate)
{
qDebug().noquote() << "InstallController::setupContainer" << ContainerUtils::containerToString(container);
SshSession sshSession;
ErrorCode e = ErrorCode::NoError;
@@ -371,7 +373,7 @@ ErrorCode InstallController::validateAndPrepareConfig(const QString &serverId)
void InstallController::validateConfig(const QString &serverId)
{
QFuture<ErrorCode> future = QtConcurrent::run([this, serverId]() {
QFuture<ErrorCode> future = SshExecutor::instance().run(serverId, [this, serverId]() {
return validateAndPrepareConfig(serverId);
});
@@ -0,0 +1,33 @@
#include "sshExecutor.h"
SshExecutor &SshExecutor::instance()
{
static SshExecutor executor;
return executor;
}
SshExecutor::~SshExecutor()
{
QMutexLocker lock(&m_mutex);
for (QThreadPool *pool : std::as_const(m_pools)) {
pool->waitForDone();
delete pool;
}
m_pools.clear();
}
QThreadPool *SshExecutor::poolFor(const QString &serverId)
{
QMutexLocker lock(&m_mutex);
auto it = m_pools.find(serverId);
if (it != m_pools.end()) {
return it.value();
}
auto *pool = new QThreadPool();
pool->setMaxThreadCount(1); // serialize all SSH ops for this server
pool->setExpiryTimeout(-1); // keep the single worker thread alive between ops
m_pools.insert(serverId, pool);
return pool;
}
@@ -0,0 +1,47 @@
#ifndef SSHEXECUTOR_H
#define SSHEXECUTOR_H
#include <QHash>
#include <QMutex>
#include <QString>
#include <QThreadPool>
#include <QtConcurrent>
#include <utility>
// Per-server serial executor for long-running self-hosted SSH operations.
//
// All SSH work for a given serverId is queued onto a dedicated single-thread
// pool, so operations to the same server run strictly one at a time (no
// concurrent SSH sessions to one host => no races, and a natural guard against
// double-run). Operations to different servers still run in parallel.
//
// NOTE: do NOT route nested workers that are awaited from within an already
// queued operation (e.g. InstallController::isServerDpkgBusy) through the same
// per-server pool — the single worker thread would block waiting on itself.
// Such nested helpers must keep using the global QThreadPool.
class SshExecutor
{
public:
static SshExecutor &instance();
SshExecutor(const SshExecutor &) = delete;
SshExecutor &operator=(const SshExecutor &) = delete;
template <typename Functor>
auto run(const QString &serverId, Functor &&functor)
{
return QtConcurrent::run(poolFor(serverId), std::forward<Functor>(functor));
}
private:
SshExecutor() = default;
~SshExecutor();
QThreadPool *poolFor(const QString &serverId);
QHash<QString, QThreadPool *> m_pools;
QMutex m_mutex;
};
#endif // SSHEXECUTOR_H
@@ -12,6 +12,7 @@
#include <utility>
#include "core/utils/api/apiUtils.h"
#include "core/utils/selfhosted/sshExecutor.h"
#include "core/controllers/selfhosted/installController.h"
#include "core/controllers/connectionController.h"
#include "core/utils/networkUtilities.h"
@@ -347,7 +348,7 @@ void InstallUiController::updateServerConfig(const QString &serverId, int contai
ContainerConfig oldConfigCopy = oldContainerConfig;
InstallController *installController = m_installController;
QFuture<ErrorCode> future =
QtConcurrent::run([installController, serverId, container, oldConfigCopy,
SshExecutor::instance().run(serverId, [installController, serverId, container, oldConfigCopy,
newConfigCopy]() mutable -> ErrorCode {
return installController->updateServerConfig(serverId, container, oldConfigCopy, newConfigCopy);
});
@@ -540,7 +541,7 @@ void InstallUiController::removeContainer(const QString &serverId, int container
});
InstallController *installController = m_installController;
QFuture<ErrorCode> future = QtConcurrent::run(
QFuture<ErrorCode> future = SshExecutor::instance().run(serverId,
[installController, serverId, container]() -> ErrorCode {
return installController->removeContainer(serverId, container);
});