From e9b92b216a68444a9342e06fd25d57ee2eeeef91 Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Tue, 14 Feb 2023 18:02:51 +0300 Subject: [PATCH 1/2] added a check for port availability when installing up a container - added wireguard service copying to debug build folder --- client/CMakeLists.txt | 24 +++++++++++----- client/containers/containers_defs.cpp | 17 +++++++++++ client/containers/containers_defs.h | 20 +++++++------ client/core/servercontroller.cpp | 41 +++++++++++++++++++++++++-- client/core/servercontroller.h | 6 ++-- 5 files changed, 88 insertions(+), 20 deletions(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 004385b7..03ddd369 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -546,11 +546,21 @@ elseif(APPLE AND NOT IOS) endif() if(NOT IOS) -add_custom_command( - TARGET ${PROJECT} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E $,copy_directory,true> - ${CMAKE_SOURCE_DIR}/deploy/data/${DEPLOY_ARTIFACT_PATH} - $ - COMMAND_EXPAND_LISTS -) + add_custom_command( + TARGET ${PROJECT} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E $,copy_directory,true> + ${CMAKE_SOURCE_DIR}/deploy/data/${DEPLOY_ARTIFACT_PATH} + $ + COMMAND_EXPAND_LISTS + ) +endif() + +if(WIN32) + add_custom_command( + TARGET ${PROJECT} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E $,copy,true> + $/../service/wireguard-service/wireguard-service.exe + $/wireguard/wireguard-service.exe + COMMAND_EXPAND_LISTS + ) endif() diff --git a/client/containers/containers_defs.cpp b/client/containers/containers_defs.cpp index c9ee2959..cca77e7d 100644 --- a/client/containers/containers_defs.cpp +++ b/client/containers/containers_defs.cpp @@ -27,6 +27,16 @@ QString ContainerProps::containerToString(amnezia::DockerContainer c){ return "amnezia-" + containerKey.toLower(); } +QString ContainerProps::containerTypeToString(amnezia::DockerContainer c){ + if (c == DockerContainer::None) return "none"; + if (c == DockerContainer::Ipsec) return "ikev2"; + + QMetaEnum metaEnum = QMetaEnum::fromType(); + QString containerKey = metaEnum.valueToKey(static_cast(c)); + + return containerKey.toLower(); +} + QVector ContainerProps::protocolsForContainer(amnezia::DockerContainer container) { switch (container) { @@ -171,3 +181,10 @@ return false; #endif } +QStringList ContainerProps::fixedPortsForContainer(DockerContainer c) +{ + switch (c) { + case DockerContainer::Ipsec : return QStringList{"500", "4500"}; + default: return {}; + } +} diff --git a/client/containers/containers_defs.h b/client/containers/containers_defs.h index f1891864..33e9a4ae 100644 --- a/client/containers/containers_defs.h +++ b/client/containers/containers_defs.h @@ -37,24 +37,26 @@ class ContainerProps : public QObject Q_OBJECT public: - Q_INVOKABLE static DockerContainer containerFromString(const QString &container); - Q_INVOKABLE static QString containerToString(DockerContainer container); + Q_INVOKABLE static amnezia::DockerContainer containerFromString(const QString &container); + Q_INVOKABLE static QString containerToString(amnezia::DockerContainer container); + Q_INVOKABLE static QString containerTypeToString(amnezia::DockerContainer c); - Q_INVOKABLE static QList allContainers(); + Q_INVOKABLE static QList allContainers(); - Q_INVOKABLE static QMap containerHumanNames(); - Q_INVOKABLE static QMap containerDescriptions(); + Q_INVOKABLE static QMap containerHumanNames(); + Q_INVOKABLE static QMap containerDescriptions(); // these protocols will be displayed in container settings - Q_INVOKABLE static QVector protocolsForContainer(DockerContainer container); + Q_INVOKABLE static QVector protocolsForContainer(amnezia::DockerContainer container); - Q_INVOKABLE static ServiceType containerService(DockerContainer c); + Q_INVOKABLE static amnezia::ServiceType containerService(amnezia::DockerContainer c); // binding between Docker container and main protocol of given container // it may be changed fot future containers :) - Q_INVOKABLE static Proto defaultProtocol(DockerContainer c); + Q_INVOKABLE static amnezia::Proto defaultProtocol(amnezia::DockerContainer c); - Q_INVOKABLE static bool isSupportedByCurrentPlatform(DockerContainer c); + Q_INVOKABLE static bool isSupportedByCurrentPlatform(amnezia::DockerContainer c); + Q_INVOKABLE static QStringList fixedPortsForContainer(amnezia::DockerContainer c); }; diff --git a/client/core/servercontroller.cpp b/client/core/servercontroller.cpp index 375215b7..5e6685dd 100644 --- a/client/core/servercontroller.cpp +++ b/client/core/servercontroller.cpp @@ -409,12 +409,18 @@ ErrorCode ServerController::removeContainer(const ServerCredentials &credentials genVarsForScript(credentials, container))); } -ErrorCode ServerController::setupContainer(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config) +ErrorCode ServerController::setupContainer(const ServerCredentials &credentials, DockerContainer container, + QJsonObject &config, bool isUpdate) { qDebug().noquote() << "ServerController::setupContainer" << ContainerProps::containerToString(container); //qDebug().noquote() << QJsonDocument(config).toJson(); ErrorCode e = ErrorCode::NoError; + if (!isUpdate) { + e = isServerPortBusy(credentials, container, config); + if (e) return e; + } + e = installDockerWorker(credentials, container); if (e) return e; qDebug().noquote() << "ServerController::setupContainer installDockerWorker finished"; @@ -451,7 +457,7 @@ ErrorCode ServerController::updateContainer(const ServerCredentials &credentials qDebug() << "ServerController::updateContainer for container" << container << "reinstall required is" << reinstallRequred; if (reinstallRequred) { - return setupContainer(credentials, container, newConfig); + return setupContainer(credentials, container, newConfig, true); } else { ErrorCode e = configureContainerWorker(credentials, container, newConfig); @@ -856,3 +862,34 @@ QString ServerController::replaceVars(const QString &script, const Vars &vars) //qDebug().noquote() << script; return s; } + +ErrorCode ServerController::isServerPortBusy(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config) +{ + QString stdOut; + auto cbReadStdOut = [&](const QString &data, QSharedPointer proc) { + stdOut += data + "\n"; + }; + auto cbReadStdErr = [&](const QString &data, QSharedPointer ) { + stdOut += data + "\n"; + }; + + const QJsonObject containerConfig = config.value(ContainerProps::containerTypeToString(container)).toObject(); + + QStringList fixedPorts = ContainerProps::fixedPortsForContainer(container); + + QString port = containerConfig.value(config_key::port).toString(); + QString transportProto = containerConfig.value(config_key::transport_proto).toString(); + + QString script = QString("sudo lsof -i -P -n | grep -E ':%1").arg(port); + for (auto &port : fixedPorts) { + script = script.append("|:%1").arg(port); + } + script = script.append("' | grep -i %1").arg(transportProto); + runScript(credentials, + replaceVars(script, genVarsForScript(credentials, container)), cbReadStdOut, cbReadStdErr); + + if (!stdOut.isEmpty()) { + return ErrorCode::ServerPortAlreadyAllocatedError; + } + return ErrorCode::NoError; +} diff --git a/client/core/servercontroller.h b/client/core/servercontroller.h index 04ae1a15..c82c043b 100644 --- a/client/core/servercontroller.h +++ b/client/core/servercontroller.h @@ -35,9 +35,10 @@ public: ErrorCode removeAllContainers(const ServerCredentials &credentials); ErrorCode removeContainer(const ServerCredentials &credentials, DockerContainer container); - ErrorCode setupContainer(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config); + ErrorCode setupContainer(const ServerCredentials &credentials, DockerContainer container, + QJsonObject &config, bool isUpdate = false); ErrorCode updateContainer(const ServerCredentials &credentials, DockerContainer container, - const QJsonObject &oldConfig, QJsonObject &newConfig); + const QJsonObject &oldConfig, QJsonObject &newConfig); // create initial config - generate passwords, etc QJsonObject createContainerInitialConfig(DockerContainer container, int port, TransportProto tp); @@ -82,6 +83,7 @@ private: ErrorCode runContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config); ErrorCode configureContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config); ErrorCode startupContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject()); + ErrorCode isServerPortBusy(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config); std::shared_ptr m_settings; std::shared_ptr m_configurator; From 69d4f0ce10141020cd65f25a5f86da1ff6cd2674 Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Sat, 25 Feb 2023 18:17:25 +0300 Subject: [PATCH 2/2] removed ContainerProps::containerTypeToString --- client/core/servercontroller.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/core/servercontroller.cpp b/client/core/servercontroller.cpp index 5e6685dd..0f867237 100644 --- a/client/core/servercontroller.cpp +++ b/client/core/servercontroller.cpp @@ -873,7 +873,8 @@ ErrorCode ServerController::isServerPortBusy(const ServerCredentials &credential stdOut += data + "\n"; }; - const QJsonObject containerConfig = config.value(ContainerProps::containerTypeToString(container)).toObject(); + const QString containerString = ProtocolProps::protoToString(ContainerProps::defaultProtocol(container)); + const QJsonObject containerConfig = config.value(containerString).toObject(); QStringList fixedPorts = ContainerProps::fixedPortsForContainer(container);