From 2580475f6716351f5bbfdad0d306824eb1be2d2a Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Sat, 25 Feb 2023 17:59:22 +0300 Subject: [PATCH] added a button to scan the server for already installed containers - refactoring of old code, redundant sections of code removed --- client/core/defs.h | 1 - client/core/errorstrings.cpp | 1 - client/core/servercontroller.cpp | 6 +- .../AdvancedServerSettingsLogic.cpp | 29 +++- .../pages_logic/AdvancedServerSettingsLogic.h | 3 +- .../pages_logic/NewServerProtocolsLogic.cpp | 5 +- .../ui/pages_logic/ServerContainersLogic.cpp | 6 +- client/ui/pages_logic/WizardLogic.cpp | 22 +-- client/ui/pages_logic/WizardLogic.h | 2 +- .../qml/Pages/PageAdvancedServerSettings.qml | 14 +- client/ui/uilogic.cpp | 136 +++++++++--------- client/ui/uilogic.h | 9 +- 12 files changed, 136 insertions(+), 98 deletions(-) diff --git a/client/core/defs.h b/client/core/defs.h index 884cb60f..3f861401 100644 --- a/client/core/defs.h +++ b/client/core/defs.h @@ -32,7 +32,6 @@ enum ErrorCode ServerContainerMissingError, ServerDockerFailedError, ServerCancelInstallation, - ServerContainerAlreadyInstalledError, // Ssh connection errors SshSocketError, SshTimeoutError, SshProtocolError, diff --git a/client/core/errorstrings.cpp b/client/core/errorstrings.cpp index 9460365f..1e7eb395 100644 --- a/client/core/errorstrings.cpp +++ b/client/core/errorstrings.cpp @@ -16,7 +16,6 @@ QString errorString(ErrorCode code){ case(ServerContainerMissingError): return QObject::tr("Server error: Docker container missing"); case(ServerDockerFailedError): return QObject::tr("Server error: Docker failed"); case(ServerCancelInstallation): return QObject::tr("Installation canceled by user"); - case(ServerContainerAlreadyInstalledError): return QObject::tr("Container already installed"); // Ssh connection errors case(SshSocketError): return QObject::tr("Ssh connection error"); diff --git a/client/core/servercontroller.cpp b/client/core/servercontroller.cpp index 9b52071c..f1cf0046 100644 --- a/client/core/servercontroller.cpp +++ b/client/core/servercontroller.cpp @@ -879,7 +879,7 @@ ErrorCode ServerController::getAlreadyInstalledContainers(const ServerCredential if (containerInfo.isEmpty()) { continue; } - const static QRegularExpression containerAndPortRegExp("(amnezia-[a-z]*).*?>([0-9]*)/(udp|tcp).*"); + const static QRegularExpression containerAndPortRegExp("(amnezia[-a-z]*).*?>([0-9]*)/(udp|tcp).*"); QRegularExpressionMatch containerAndPortMatch = containerAndPortRegExp.match(containerInfo); if (containerAndPortMatch.hasMatch()) { QString name = containerAndPortMatch.captured(1); @@ -890,8 +890,8 @@ ErrorCode ServerController::getAlreadyInstalledContainers(const ServerCredential QJsonObject config { { config_key::container, name }, { ProtocolProps::protoToString(mainProto), QJsonObject { - { config_key::port, port }, - { config_key::transport_proto, transportProto }} + { config_key::port, port }, + { config_key::transport_proto, transportProto }} } }; installedContainers.insert(container, config); diff --git a/client/ui/pages_logic/AdvancedServerSettingsLogic.cpp b/client/ui/pages_logic/AdvancedServerSettingsLogic.cpp index 832fc6fd..0b02241c 100644 --- a/client/ui/pages_logic/AdvancedServerSettingsLogic.cpp +++ b/client/ui/pages_logic/AdvancedServerSettingsLogic.cpp @@ -35,7 +35,7 @@ void AdvancedServerSettingsLogic::onUpdatePage() set_labelCurrentVpnProtocolText(tr("Service: ") + selectedContainerName); } -void AdvancedServerSettingsLogic::onPushButtonClearServer() +void AdvancedServerSettingsLogic::onPushButtonClearServerClicked() { set_pageEnabled(false); set_pushButtonClearText(tr("Uninstalling Amnezia software...")); @@ -47,7 +47,7 @@ void AdvancedServerSettingsLogic::onPushButtonClearServer() ErrorCode e = m_serverController->removeAllContainers(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex)); m_serverController->disconnectFromHost(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex)); if (e) { - emit uiLogic()->showWarningMessage(tr("Error occurred while configuring server.") + "\n" + + emit uiLogic()->showWarningMessage(tr("Error occurred while cleaning the server.") + "\n" + tr("Error message: ") + errorString(e) + "\n" + tr("See logs for details.")); } else { @@ -61,3 +61,28 @@ void AdvancedServerSettingsLogic::onPushButtonClearServer() set_pageEnabled(true); set_pushButtonClearText(tr("Clear server from Amnezia software")); } + +void AdvancedServerSettingsLogic::onPushButtonScanServerClicked() +{ + set_labelWaitInfoVisible(false); + set_pageEnabled(false); + + bool isServerCreated; + auto containersCount = m_settings->containers(uiLogic()->m_selectedServerIndex).size(); + ErrorCode errorCode = uiLogic()->addAlreadyInstalledContainersGui(false, isServerCreated); + if (errorCode != ErrorCode::NoError) { + emit uiLogic()->showWarningMessage(tr("Error occurred while scanning the server.") + "\n" + + tr("Error message: ") + errorString(errorCode) + "\n" + + tr("See logs for details.")); + } + auto newContainersCount = m_settings->containers(uiLogic()->m_selectedServerIndex).size(); + if (containersCount != newContainersCount) { + emit uiLogic()->showWarningMessage(tr("All containers installed on the server are added to the GUI")); + } else { + emit uiLogic()->showWarningMessage(tr("No installed containers found on the server")); + } + + + onUpdatePage(); + set_pageEnabled(true); +} diff --git a/client/ui/pages_logic/AdvancedServerSettingsLogic.h b/client/ui/pages_logic/AdvancedServerSettingsLogic.h index 396b375a..692968f1 100644 --- a/client/ui/pages_logic/AdvancedServerSettingsLogic.h +++ b/client/ui/pages_logic/AdvancedServerSettingsLogic.h @@ -24,7 +24,8 @@ public: Q_INVOKABLE void onUpdatePage() override; - Q_INVOKABLE void onPushButtonClearServer(); + Q_INVOKABLE void onPushButtonClearServerClicked(); + Q_INVOKABLE void onPushButtonScanServerClicked(); }; #endif // ADVANCEDSERVERSETTINGSLOGIC_H diff --git a/client/ui/pages_logic/NewServerProtocolsLogic.cpp b/client/ui/pages_logic/NewServerProtocolsLogic.cpp index cabe1bc0..a1db7565 100644 --- a/client/ui/pages_logic/NewServerProtocolsLogic.cpp +++ b/client/ui/pages_logic/NewServerProtocolsLogic.cpp @@ -17,7 +17,6 @@ void NewServerProtocolsLogic::onUpdatePage() void NewServerProtocolsLogic::onPushButtonConfigureClicked(DockerContainer c, int port, TransportProto tp) { - QMap containers; Proto mainProto = ContainerProps::defaultProtocol(c); QJsonObject config { @@ -28,8 +27,8 @@ void NewServerProtocolsLogic::onPushButtonConfigureClicked(DockerContainer c, in } }; - containers.insert(c, config); + QPair container(c, config); - uiLogic()->installServer(containers); + uiLogic()->installServer(container); } diff --git a/client/ui/pages_logic/ServerContainersLogic.cpp b/client/ui/pages_logic/ServerContainersLogic.cpp index 91efc2c6..aeec8161 100644 --- a/client/ui/pages_logic/ServerContainersLogic.cpp +++ b/client/ui/pages_logic/ServerContainersLogic.cpp @@ -88,11 +88,11 @@ void ServerContainersLogic::onPushButtonContinueClicked(DockerContainer c, int p emit uiLogic()->goToPage(Page::ServerConfiguringProgress); qApp->processEvents(); - ServerCredentials credentials = m_settings->serverCredentials(uiLogic()->m_selectedServerIndex); - ErrorCode errorCode = uiLogic()->addAlreadyInstalledContainersGui(false, credentials); + bool isServerCreated = false; + ErrorCode errorCode = uiLogic()->addAlreadyInstalledContainersGui(false, isServerCreated); if (errorCode == ErrorCode::NoError) { - if (!uiLogic()->isContainerAlreadyAddedToGui(c, credentials)) { + if (!uiLogic()->isContainerAlreadyAddedToGui(c)) { auto installAction = [this, c, &config]() { return m_serverController->setupContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex), c, config); }; diff --git a/client/ui/pages_logic/WizardLogic.cpp b/client/ui/pages_logic/WizardLogic.cpp index 5fe820f1..23a20aed 100644 --- a/client/ui/pages_logic/WizardLogic.cpp +++ b/client/ui/pages_logic/WizardLogic.cpp @@ -18,7 +18,7 @@ void WizardLogic::onUpdatePage() set_radioButtonMediumChecked(true); } -QMap WizardLogic::getInstallConfigsFromWizardPage() const +QPair WizardLogic::getInstallConfigsFromWizardPage() const { QJsonObject cloakConfig { { config_key::container, ContainerProps::containerToString(DockerContainer::Cloak) }, @@ -33,27 +33,29 @@ QMap WizardLogic::getInstallConfigsFromWizardPage( { config_key::container, ContainerProps::containerToString(DockerContainer::OpenVpn) } }; - QMap containers; + QPair container; + + DockerContainer dockerContainer; if (radioButtonHighChecked()) { - containers.insert(DockerContainer::Cloak, cloakConfig); + container = {DockerContainer::Cloak, cloakConfig}; } if (radioButtonMediumChecked()) { - containers.insert(DockerContainer::ShadowSocks, ssConfig); + container = {DockerContainer::ShadowSocks, ssConfig}; } if (radioButtonLowChecked()) { - containers.insert(DockerContainer::OpenVpn, openVpnConfig); + container = {DockerContainer::OpenVpn, openVpnConfig}; } - return containers; + return container; } void WizardLogic::onPushButtonVpnModeFinishClicked() { - auto containers = getInstallConfigsFromWizardPage(); - uiLogic()->installServer(containers); + auto container = getInstallConfigsFromWizardPage(); + uiLogic()->installServer(container); if (checkBoxVpnModeChecked()) { m_settings->setRouteMode(Settings::VpnOnlyForwardSites); } else { @@ -63,6 +65,6 @@ void WizardLogic::onPushButtonVpnModeFinishClicked() void WizardLogic::onPushButtonLowFinishClicked() { - auto containers = getInstallConfigsFromWizardPage(); - uiLogic()->installServer(containers); + auto container = getInstallConfigsFromWizardPage(); + uiLogic()->installServer(container); } diff --git a/client/ui/pages_logic/WizardLogic.h b/client/ui/pages_logic/WizardLogic.h index 3827c86e..a2e45af7 100644 --- a/client/ui/pages_logic/WizardLogic.h +++ b/client/ui/pages_logic/WizardLogic.h @@ -25,7 +25,7 @@ public: explicit WizardLogic(UiLogic *uiLogic, QObject *parent = nullptr); ~WizardLogic() = default; - QMap getInstallConfigsFromWizardPage() const; + QPair getInstallConfigsFromWizardPage() const; }; #endif // WIZARD_LOGIC_H diff --git a/client/ui/qml/Pages/PageAdvancedServerSettings.qml b/client/ui/qml/Pages/PageAdvancedServerSettings.qml index 4e9d1106..e00f7326 100644 --- a/client/ui/qml/Pages/PageAdvancedServerSettings.qml +++ b/client/ui/qml/Pages/PageAdvancedServerSettings.qml @@ -16,12 +16,21 @@ PageBase { BackButton { id: back } + Caption { id: caption text: qsTr("Advanced server settings") anchors.horizontalCenter: parent.horizontalCenter } + BusyIndicator { + z: 99 + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + visible: !AdvancedServerSettingsLogic.pageEnabled + running: !AdvancedServerSettingsLogic.pageEnabled + } + FlickableType { id: fl anchors.top: caption.bottom @@ -54,6 +63,7 @@ PageBase { LabelType { Layout.fillWidth: true + horizontalAlignment: Text.AlignHCenter text: AdvancedServerSettingsLogic.labelWaitInfoText visible: AdvancedServerSettingsLogic.labelWaitInfoVisible } @@ -64,7 +74,7 @@ PageBase { text: "Scan the server for installed containers" visible: AdvancedServerSettingsLogic.pushButtonClearVisible onClicked: { - UiLogic.getInstalledContainers(false) + AdvancedServerSettingsLogic.onPushButtonScanServerClicked() } } @@ -82,8 +92,8 @@ PageBase { id: popupClearServer questionText: "Attention! All containers will be deleted on the server. This means that configuration files, keys and certificates will be deleted. Continue?" yesFunc: function() { - AdvancedServerSettingsLogic.onPushButtonClearServer() close() + AdvancedServerSettingsLogic.onPushButtonClearServerClicked() } noFunc: function() { close() diff --git a/client/ui/uilogic.cpp b/client/ui/uilogic.cpp index ed44efad..895a526c 100644 --- a/client/ui/uilogic.cpp +++ b/client/ui/uilogic.cpp @@ -267,10 +267,8 @@ void UiLogic::onGotoCurrentProtocolsPage() emit goToPage(Page::ServerContainers); } -void UiLogic::installServer(QMap &containers) +void UiLogic::installServer(QPair &container) { - if (containers.isEmpty()) return; - emit goToPage(Page::ServerConfiguringProgress); QEventLoop loop; QTimer::singleShot(500, &loop, SLOT(quit())); @@ -325,57 +323,48 @@ void UiLogic::installServer(QMap &containers) pageLogic()->set_pushButtonCancelVisible(visible); }; - ErrorCode errorCode = addAlreadyInstalledContainersGui(true, m_installCredentials); + bool isServerCreated = false; + ErrorCode errorCode = addAlreadyInstalledContainersGui(true, isServerCreated); if (errorCode == ErrorCode::NoError) { - int count = 0; - bool isSomethingInstalled = false; - for (QMap::iterator i = containers.begin(); i != containers.end(); i++, count++) { - if (isContainerAlreadyAddedToGui(i.key(), m_installCredentials)) { - continue; - } - - isSomethingInstalled = true; - - progressBarFunc.setTextFunc(QString("Installing %1 %2 %3").arg(count + 1).arg(tr("of")).arg(containers.size())); + if (!isContainerAlreadyAddedToGui(container.first)) { + progressBarFunc.setTextFunc(QString("Installing %1").arg(ContainerProps::containerToString(container.first))); auto installAction = [&] () { - return m_serverController->setupContainer(m_installCredentials, i.key(), i.value()); + return m_serverController->setupContainer(m_installCredentials, container.first, container.second); }; errorCode = pageLogic()->doInstallAction(installAction, pageFunc, progressBarFunc, - noButton, waitInfoFunc, - busyInfoFunc, cancelButtonFunc); - + noButton, waitInfoFunc, + busyInfoFunc, cancelButtonFunc); m_serverController->disconnectFromHost(m_installCredentials); - } - if (errorCode == ErrorCode::NoError) { - if (!isSomethingInstalled) { + if (errorCode == ErrorCode::NoError) { + if (!isServerCreated) { + QJsonObject server; + server.insert(config_key::hostName, m_installCredentials.hostName); + server.insert(config_key::userName, m_installCredentials.userName); + server.insert(config_key::password, m_installCredentials.password); + server.insert(config_key::port, m_installCredentials.port); + server.insert(config_key::description, m_settings->nextAvailableServerName()); + + server.insert(config_key::containers, QJsonArray{container.second}); + server.insert(config_key::defaultContainer, ContainerProps::containerToString(container.first)); + + m_settings->addServer(server); + m_settings->setDefaultServer(m_settings->serversCount() - 1); + } else { + m_settings->setContainerConfig(m_settings->serversCount() - 1, container.first, container.second); + m_settings->setDefaultContainer(m_settings->serversCount() - 1, container.first); + } onUpdateAllPages(); - emit showWarningMessage("Attention! The container you are trying to install is already installed on the server. " - "All installed containers have been added to the application "); + emit setStartPage(Page::Vpn); + qApp->processEvents(); return; } - - QJsonObject server; - server.insert(config_key::hostName, m_installCredentials.hostName); - server.insert(config_key::userName, m_installCredentials.userName); - server.insert(config_key::password, m_installCredentials.password); - server.insert(config_key::port, m_installCredentials.port); - server.insert(config_key::description, m_settings->nextAvailableServerName()); - - QJsonArray containerConfigs; - for (const QJsonObject &cfg : containers) { - containerConfigs.append(cfg); - } - server.insert(config_key::containers, containerConfigs); - server.insert(config_key::defaultContainer, ContainerProps::containerToString(containers.firstKey())); - - m_settings->addServer(server); - m_settings->setDefaultServer(m_settings->serversCount() - 1); + } else { onUpdateAllPages(); - + emit showWarningMessage("Attention! The container you are trying to install is already installed on the server. " + "All installed containers have been added to the application "); emit setStartPage(Page::Vpn); - qApp->processEvents(); return; } } @@ -521,8 +510,16 @@ void UiLogic::registerPagesLogic() registerPageLogic(); } -ErrorCode UiLogic::addAlreadyInstalledContainersGui(bool createNewServer, const ServerCredentials& credentials) +ErrorCode UiLogic::addAlreadyInstalledContainersGui(bool createNewServer, bool &isServerCreated) { + isServerCreated = false; + ServerCredentials credentials; + if (createNewServer) { + credentials = m_installCredentials; + } else { + credentials = m_settings->serverCredentials(m_selectedServerIndex); + } + QMap installedContainers; ErrorCode errorCode = m_serverController->getAlreadyInstalledContainers(credentials, installedContainers); m_serverController->disconnectFromHost(credentials); @@ -530,44 +527,47 @@ ErrorCode UiLogic::addAlreadyInstalledContainersGui(bool createNewServer, const return errorCode; } - QJsonObject server; - QJsonArray containerConfigs; - if (createNewServer) { - server.insert(config_key::hostName, credentials.hostName); - server.insert(config_key::userName, credentials.userName); - server.insert(config_key::password, credentials.password); - server.insert(config_key::port, credentials.port); - server.insert(config_key::description, m_settings->nextAvailableServerName()); - } + if (!installedContainers.empty()) { + QJsonObject server; + QJsonArray containerConfigs; + if (createNewServer) { + server.insert(config_key::hostName, credentials.hostName); + server.insert(config_key::userName, credentials.userName); + server.insert(config_key::password, credentials.password); + server.insert(config_key::port, credentials.port); + server.insert(config_key::description, m_settings->nextAvailableServerName()); + } - for (auto container = installedContainers.begin(); container != installedContainers.end(); container++) { - if (isContainerAlreadyAddedToGui(container.key(), credentials)) { - continue; + for (auto container = installedContainers.begin(); container != installedContainers.end(); container++) { + if (isContainerAlreadyAddedToGui(container.key())) { + continue; + } + + if (createNewServer) { + containerConfigs.append(container.value()); + server.insert(config_key::containers, containerConfigs); + } else { + m_settings->setContainerConfig(m_selectedServerIndex, container.key(), container.value()); + m_settings->setDefaultContainer(m_selectedServerIndex, installedContainers.firstKey()); + } } if (createNewServer) { - containerConfigs.append(container.value()); - server.insert(config_key::containers, containerConfigs); - } else { - m_settings->setContainerConfig(m_selectedServerIndex, container.key(), container.value()); - m_settings->setDefaultContainer(m_selectedServerIndex, installedContainers.firstKey()); + server.insert(config_key::defaultContainer, ContainerProps::containerToString(installedContainers.firstKey())); + m_settings->addServer(server); + m_settings->setDefaultServer(m_settings->serversCount() - 1); + isServerCreated = true; } } - if (createNewServer) { - server.insert(config_key::defaultContainer, ContainerProps::containerToString(installedContainers.firstKey())); - m_settings->addServer(server); - m_settings->setDefaultServer(m_settings->serversCount() - 1); - } - return ErrorCode::NoError; } -bool UiLogic::isContainerAlreadyAddedToGui(DockerContainer container, const ServerCredentials &selectedServerCredentials) +bool UiLogic::isContainerAlreadyAddedToGui(DockerContainer container) { for (int i = 0; i < m_settings->serversCount(); i++) { const ServerCredentials credentials = m_settings->serverCredentials(i); - if (selectedServerCredentials.hostName == credentials.hostName && selectedServerCredentials.port == credentials.port) { + if (m_installCredentials.hostName == credentials.hostName && m_installCredentials.port == credentials.port) { const QJsonObject containerConfig = m_settings->containerConfig(i, container); if (!containerConfig.isEmpty()) { return true; diff --git a/client/ui/uilogic.h b/client/ui/uilogic.h index 339f119c..92035fe5 100644 --- a/client/ui/uilogic.h +++ b/client/ui/uilogic.h @@ -53,6 +53,7 @@ class OtherProtocolsLogic; class VpnConnection; +class CreateServerTest; class UiLogic : public QObject { @@ -97,6 +98,8 @@ public: friend class OtherProtocolsLogic; + friend class CreateServerTest; + Q_INVOKABLE virtual void onUpdatePage() {} // UiLogic is set as logic class for some qml pages Q_INVOKABLE void onUpdateAllPages(); @@ -114,7 +117,7 @@ public: Q_INVOKABLE void saveBinaryFile(const QString& desc, QString ext, const QString& data); Q_INVOKABLE void copyToClipboard(const QString& text); - Q_INVOKABLE amnezia::ErrorCode addAlreadyInstalledContainersGui(bool createNewServer, const ServerCredentials& credentials); + Q_INVOKABLE amnezia::ErrorCode addAlreadyInstalledContainersGui(bool createNewServer, bool &isServerCreated); void shareTempFile(const QString &suggestedName, QString ext, const QString& data); @@ -135,11 +138,11 @@ signals: private slots: // containers - INOUT arg - void installServer(QMap &containers); + void installServer(QPair &container); private: PageEnumNS::Page currentPage(); - bool isContainerAlreadyAddedToGui(DockerContainer container, const ServerCredentials &selectedServerCredentials); + bool isContainerAlreadyAddedToGui(DockerContainer container); public: Q_INVOKABLE PageProtocolLogicBase *protocolLogic(Proto p);