Merge pull request #168 from amnezia-vpn/feature/port-availability-on-container-setup
feature/port-availability-on-container-setup
This commit is contained in:
commit
c756ab70ae
5 changed files with 89 additions and 20 deletions
|
@ -592,13 +592,23 @@ elseif(APPLE AND NOT IOS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT IOS)
|
if(NOT IOS)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET ${PROJECT} POST_BUILD
|
TARGET ${PROJECT} POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E $<IF:$<CONFIG:Debug>,copy_directory,true>
|
COMMAND ${CMAKE_COMMAND} -E $<IF:$<CONFIG:Debug>,copy_directory,true>
|
||||||
${CMAKE_SOURCE_DIR}/deploy/data/${DEPLOY_ARTIFACT_PATH}
|
${CMAKE_SOURCE_DIR}/deploy/data/${DEPLOY_ARTIFACT_PATH}
|
||||||
$<TARGET_FILE_DIR:${PROJECT}>
|
$<TARGET_FILE_DIR:${PROJECT}>
|
||||||
COMMAND_EXPAND_LISTS
|
COMMAND_EXPAND_LISTS
|
||||||
)
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
add_custom_command(
|
||||||
|
TARGET ${PROJECT} POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E $<IF:$<CONFIG:Debug>,copy,true>
|
||||||
|
$<TARGET_FILE_DIR:${PROJECT}>/../service/wireguard-service/wireguard-service.exe
|
||||||
|
$<TARGET_FILE_DIR:${PROJECT}>/wireguard/wireguard-service.exe
|
||||||
|
COMMAND_EXPAND_LISTS
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
if(IOS)
|
if(IOS)
|
||||||
#include(cmake/ios-arch-fixup.cmake)
|
#include(cmake/ios-arch-fixup.cmake)
|
||||||
|
|
|
@ -27,6 +27,16 @@ QString ContainerProps::containerToString(amnezia::DockerContainer c){
|
||||||
return "amnezia-" + containerKey.toLower();
|
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<DockerContainer>();
|
||||||
|
QString containerKey = metaEnum.valueToKey(static_cast<int>(c));
|
||||||
|
|
||||||
|
return containerKey.toLower();
|
||||||
|
}
|
||||||
|
|
||||||
QVector<amnezia::Proto> ContainerProps::protocolsForContainer(amnezia::DockerContainer container)
|
QVector<amnezia::Proto> ContainerProps::protocolsForContainer(amnezia::DockerContainer container)
|
||||||
{
|
{
|
||||||
switch (container) {
|
switch (container) {
|
||||||
|
@ -171,3 +181,10 @@ return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringList ContainerProps::fixedPortsForContainer(DockerContainer c)
|
||||||
|
{
|
||||||
|
switch (c) {
|
||||||
|
case DockerContainer::Ipsec : return QStringList{"500", "4500"};
|
||||||
|
default: return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -37,24 +37,26 @@ class ContainerProps : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Q_INVOKABLE static DockerContainer containerFromString(const QString &container);
|
Q_INVOKABLE static amnezia::DockerContainer containerFromString(const QString &container);
|
||||||
Q_INVOKABLE static QString containerToString(DockerContainer container);
|
Q_INVOKABLE static QString containerToString(amnezia::DockerContainer container);
|
||||||
|
Q_INVOKABLE static QString containerTypeToString(amnezia::DockerContainer c);
|
||||||
|
|
||||||
Q_INVOKABLE static QList<DockerContainer> allContainers();
|
Q_INVOKABLE static QList<amnezia::DockerContainer> allContainers();
|
||||||
|
|
||||||
Q_INVOKABLE static QMap<DockerContainer, QString> containerHumanNames();
|
Q_INVOKABLE static QMap<amnezia::DockerContainer, QString> containerHumanNames();
|
||||||
Q_INVOKABLE static QMap<DockerContainer, QString> containerDescriptions();
|
Q_INVOKABLE static QMap<amnezia::DockerContainer, QString> containerDescriptions();
|
||||||
|
|
||||||
// these protocols will be displayed in container settings
|
// these protocols will be displayed in container settings
|
||||||
Q_INVOKABLE static QVector<Proto> protocolsForContainer(DockerContainer container);
|
Q_INVOKABLE static QVector<amnezia::Proto> 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
|
// binding between Docker container and main protocol of given container
|
||||||
// it may be changed fot future containers :)
|
// 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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -409,12 +409,18 @@ ErrorCode ServerController::removeContainer(const ServerCredentials &credentials
|
||||||
genVarsForScript(credentials, container)));
|
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() << "ServerController::setupContainer" << ContainerProps::containerToString(container);
|
||||||
//qDebug().noquote() << QJsonDocument(config).toJson();
|
//qDebug().noquote() << QJsonDocument(config).toJson();
|
||||||
ErrorCode e = ErrorCode::NoError;
|
ErrorCode e = ErrorCode::NoError;
|
||||||
|
|
||||||
|
if (!isUpdate) {
|
||||||
|
e = isServerPortBusy(credentials, container, config);
|
||||||
|
if (e) return e;
|
||||||
|
}
|
||||||
|
|
||||||
e = installDockerWorker(credentials, container);
|
e = installDockerWorker(credentials, container);
|
||||||
if (e) return e;
|
if (e) return e;
|
||||||
qDebug().noquote() << "ServerController::setupContainer installDockerWorker finished";
|
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;
|
qDebug() << "ServerController::updateContainer for container" << container << "reinstall required is" << reinstallRequred;
|
||||||
|
|
||||||
if (reinstallRequred) {
|
if (reinstallRequred) {
|
||||||
return setupContainer(credentials, container, newConfig);
|
return setupContainer(credentials, container, newConfig, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ErrorCode e = configureContainerWorker(credentials, container, newConfig);
|
ErrorCode e = configureContainerWorker(credentials, container, newConfig);
|
||||||
|
@ -856,3 +862,35 @@ QString ServerController::replaceVars(const QString &script, const Vars &vars)
|
||||||
//qDebug().noquote() << script;
|
//qDebug().noquote() << script;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorCode ServerController::isServerPortBusy(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
|
||||||
|
{
|
||||||
|
QString stdOut;
|
||||||
|
auto cbReadStdOut = [&](const QString &data, QSharedPointer<QSsh::SshRemoteProcess> proc) {
|
||||||
|
stdOut += data + "\n";
|
||||||
|
};
|
||||||
|
auto cbReadStdErr = [&](const QString &data, QSharedPointer<QSsh::SshRemoteProcess> ) {
|
||||||
|
stdOut += data + "\n";
|
||||||
|
};
|
||||||
|
|
||||||
|
const QString containerString = ProtocolProps::protoToString(ContainerProps::defaultProtocol(container));
|
||||||
|
const QJsonObject containerConfig = config.value(containerString).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;
|
||||||
|
}
|
||||||
|
|
|
@ -35,9 +35,10 @@ public:
|
||||||
|
|
||||||
ErrorCode removeAllContainers(const ServerCredentials &credentials);
|
ErrorCode removeAllContainers(const ServerCredentials &credentials);
|
||||||
ErrorCode removeContainer(const ServerCredentials &credentials, DockerContainer container);
|
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,
|
ErrorCode updateContainer(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &oldConfig, QJsonObject &newConfig);
|
const QJsonObject &oldConfig, QJsonObject &newConfig);
|
||||||
|
|
||||||
// create initial config - generate passwords, etc
|
// create initial config - generate passwords, etc
|
||||||
QJsonObject createContainerInitialConfig(DockerContainer container, int port, TransportProto tp);
|
QJsonObject createContainerInitialConfig(DockerContainer container, int port, TransportProto tp);
|
||||||
|
@ -82,6 +83,7 @@ private:
|
||||||
ErrorCode runContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config);
|
ErrorCode runContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config);
|
||||||
ErrorCode configureContainerWorker(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 startupContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
|
||||||
|
ErrorCode isServerPortBusy(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config);
|
||||||
|
|
||||||
std::shared_ptr<Settings> m_settings;
|
std::shared_ptr<Settings> m_settings;
|
||||||
std::shared_ptr<VpnConfigurator> m_configurator;
|
std::shared_ptr<VpnConfigurator> m_configurator;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue