From 6ec090ea0dd5037e25de3af39d5e45df9d57511a Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Mon, 2 Jan 2023 17:32:27 +0300 Subject: [PATCH] added a "Cancel" button to interrupt the server configuration process when it is found that it is busy installing other software --- client/core/defs.h | 1 + client/core/errorstrings.cpp | 1 + client/core/servercontroller.cpp | 20 ++++++- client/core/servercontroller.h | 2 + .../ServerConfiguringProgressLogic.cpp | 55 ++++++++++++++----- .../ServerConfiguringProgressLogic.h | 12 +++- .../ui/pages_logic/protocols/CloakLogic.cpp | 13 ++++- client/ui/pages_logic/protocols/CloakLogic.h | 4 ++ .../ui/pages_logic/protocols/OpenVpnLogic.cpp | 15 ++++- .../ui/pages_logic/protocols/OpenVpnLogic.h | 5 +- .../protocols/ShadowSocksLogic.cpp | 13 ++++- .../pages_logic/protocols/ShadowSocksLogic.h | 4 ++ .../Pages/PageServerConfiguringProgress.qml | 20 +++++-- .../ui/qml/Pages/Protocols/PageProtoCloak.qml | 10 +++- .../qml/Pages/Protocols/PageProtoOpenVPN.qml | 49 +++++++++++------ .../Pages/Protocols/PageProtoShadowSocks.qml | 10 ++++ client/ui/uilogic.cpp | 7 ++- 17 files changed, 193 insertions(+), 48 deletions(-) diff --git a/client/core/defs.h b/client/core/defs.h index 5845fd3c..3f861401 100644 --- a/client/core/defs.h +++ b/client/core/defs.h @@ -31,6 +31,7 @@ enum ErrorCode ServerPortAlreadyAllocatedError, ServerContainerMissingError, ServerDockerFailedError, + ServerCancelInstallation, // Ssh connection errors SshSocketError, SshTimeoutError, SshProtocolError, diff --git a/client/core/errorstrings.cpp b/client/core/errorstrings.cpp index 722dd4b4..1e7eb395 100644 --- a/client/core/errorstrings.cpp +++ b/client/core/errorstrings.cpp @@ -15,6 +15,7 @@ QString errorString(ErrorCode code){ case(ServerPortAlreadyAllocatedError): return QObject::tr("Server port already used. Check for another software"); 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"); // Ssh connection errors case(SshSocketError): return QObject::tr("Ssh connection error"); diff --git a/client/core/servercontroller.cpp b/client/core/servercontroller.cpp index ef1511b2..c9d4f0de 100644 --- a/client/core/servercontroller.cpp +++ b/client/core/servercontroller.cpp @@ -530,10 +530,13 @@ ErrorCode ServerController::installDockerWorker(const ServerCredentials &credent stdOut += data + "\n"; }; - QFutureWatcher watcher; + QFutureWatcher watcher; - QFuture future = QtConcurrent::run([this, &stdOut, &cbReadStdOut, &cbReadStdErr, &credentials]() { + QFuture future = QtConcurrent::run([this, &stdOut, &cbReadStdOut, &cbReadStdErr, &credentials]() { do { + if (m_cancelInstallation) { + return ErrorCode::ServerCancelInstallation; + } stdOut.clear(); runScript(credentials, replaceVars(amnezia::scriptData(SharedScriptType::check_server_is_busy), @@ -543,16 +546,22 @@ ErrorCode ServerController::installDockerWorker(const ServerCredentials &credent QThread::msleep(1000); } } while (!stdOut.isEmpty()); + return ErrorCode::NoError; }); watcher.setFuture(future); QEventLoop wait; - QObject::connect(&watcher, &QFutureWatcher::finished, &wait, &QEventLoop::quit); + QObject::connect(&watcher, &QFutureWatcher::finished, &wait, &QEventLoop::quit); wait.exec(); + m_cancelInstallation = false; emit serverIsBusy(false); + if (future.result() != ErrorCode::NoError) { + return future.result(); + } + ErrorCode error = runScript(credentials, replaceVars(amnezia::scriptData(SharedScriptType::install_docker), genVarsForScript(credentials)), cbReadStdOut, cbReadStdErr); @@ -820,6 +829,11 @@ SshConnection *ServerController::connectToHost(const SshConnectionParameters &ss return client; } +void ServerController::setCancelInstallation(const bool cancel) +{ + m_cancelInstallation = cancel; +} + void ServerController::disconnectFromHost(const ServerCredentials &credentials) { SshConnection *client = acquireConnection(sshParams(credentials)); diff --git a/client/core/servercontroller.h b/client/core/servercontroller.h index b151dc54..c64401da 100644 --- a/client/core/servercontroller.h +++ b/client/core/servercontroller.h @@ -73,6 +73,7 @@ public: QString checkSshConnection(const ServerCredentials &credentials, ErrorCode *errorCode = nullptr); QSsh::SshConnection *connectToHost(const QSsh::SshConnectionParameters &sshParams); + void setCancelInstallation(const bool cancel); private: ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container); @@ -85,6 +86,7 @@ private: std::shared_ptr m_settings; std::shared_ptr m_configurator; + bool m_cancelInstallation = false; signals: void serverIsBusy(const bool isBusy); }; diff --git a/client/ui/pages_logic/ServerConfiguringProgressLogic.cpp b/client/ui/pages_logic/ServerConfiguringProgressLogic.cpp index 23697181..c6e7085b 100644 --- a/client/ui/pages_logic/ServerConfiguringProgressLogic.cpp +++ b/client/ui/pages_logic/ServerConfiguringProgressLogic.cpp @@ -59,22 +59,28 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function void { + set_pushButtonCancelVisible(visible); + }; + + return doInstallAction(action, page, progress, noButton, noWaitInfo, busyInfo, cancelButton); } ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function &action, const PageFunc &page, const ProgressFunc &progress, - const ButtonFunc &button, + const ButtonFunc &saveButton, const LabelFunc &waitInfo, - const LabelFunc &serverBusyInfo) + const LabelFunc &serverBusyInfo, + const ButtonFunc &cancelButton) { progress.setVisibleFunc(true); if (page.setEnabledFunc) { page.setEnabledFunc(false); } - if (button.setVisibleFunc) { - button.setVisibleFunc(false); + if (saveButton.setVisibleFunc) { + saveButton.setVisibleFunc(false); } if (waitInfo.setVisibleFunc) { waitInfo.setVisibleFunc(true); @@ -91,33 +97,47 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function &action, const PageFunc &page, const ProgressFunc &progress, - const ButtonFunc &button, + const ButtonFunc &saveButton, const LabelFunc &waitInfo, - const LabelFunc &serverBusyInfo); + const LabelFunc &serverBusyInfo, + const ButtonFunc &cancelButton); + +signals: + void cancelDoInstallAction(const bool cancel); }; #endif // SERVER_CONFIGURING_PROGRESS_LOGIC_H diff --git a/client/ui/pages_logic/protocols/CloakLogic.cpp b/client/ui/pages_logic/protocols/CloakLogic.cpp index 1456e457..6e179013 100644 --- a/client/ui/pages_logic/protocols/CloakLogic.cpp +++ b/client/ui/pages_logic/protocols/CloakLogic.cpp @@ -105,6 +105,11 @@ void CloakLogic::onPushButtonSaveClicked() set_labelServerBusyVisible(visible); }; + ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc; + cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void { + set_pushButtonCancelVisible(visible); + }; + progressBarFunc.setTextVisibleFunc(true); progressBarFunc.setTextFunc(QString("Configuring...")); ErrorCode e = uiLogic()->pageLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ @@ -114,7 +119,8 @@ void CloakLogic::onPushButtonSaveClicked() newContainerConfig); }, pageFunc, progressBarFunc, - saveButtonFunc, waitInfoFunc, busyInfoFuncy); + saveButtonFunc, waitInfoFunc, + busyInfoFuncy, cancelButtonFunc); if (!e) { m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig); @@ -123,3 +129,8 @@ void CloakLogic::onPushButtonSaveClicked() qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer; } + +void CloakLogic::onPushButtonCancelClicked() +{ + emit uiLogic()->pageLogic()->cancelDoInstallAction(true); +} diff --git a/client/ui/pages_logic/protocols/CloakLogic.h b/client/ui/pages_logic/protocols/CloakLogic.h index 57afb5b0..5c39e8ac 100644 --- a/client/ui/pages_logic/protocols/CloakLogic.h +++ b/client/ui/pages_logic/protocols/CloakLogic.h @@ -25,8 +25,12 @@ class CloakLogic : public PageProtocolLogicBase AUTO_PROPERTY(bool, labelServerBusyVisible) AUTO_PROPERTY(QString, labelServerBusyText) + + AUTO_PROPERTY(bool, pushButtonCancelVisible) + public: Q_INVOKABLE void onPushButtonSaveClicked(); + Q_INVOKABLE void onPushButtonCancelClicked(); public: explicit CloakLogic(UiLogic *uiLogic, QObject *parent = nullptr); diff --git a/client/ui/pages_logic/protocols/OpenVpnLogic.cpp b/client/ui/pages_logic/protocols/OpenVpnLogic.cpp index a25fd134..a37b365b 100644 --- a/client/ui/pages_logic/protocols/OpenVpnLogic.cpp +++ b/client/ui/pages_logic/protocols/OpenVpnLogic.cpp @@ -92,7 +92,7 @@ void OpenVpnLogic::updateProtocolPage(const QJsonObject &openvpnConfig, DockerCo set_lineEditPortEnabled(container == DockerContainer::OpenVpn); } -void OpenVpnLogic::onPushButtonProtoOpenVpnSaveClicked() +void OpenVpnLogic::onPushButtonSaveClicked() { QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::OpenVpn); protocolConfig = getProtocolConfigFromPage(protocolConfig); @@ -144,6 +144,11 @@ void OpenVpnLogic::onPushButtonProtoOpenVpnSaveClicked() set_labelServerBusyVisible(visible); }; + ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc; + cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void { + set_pushButtonCancelVisible(visible); + }; + progressBarFunc.setTextVisibleFunc(true); progressBarFunc.setTextFunc(QString("Configuring...")); ErrorCode e = uiLogic()->pageLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ @@ -153,7 +158,8 @@ void OpenVpnLogic::onPushButtonProtoOpenVpnSaveClicked() newContainerConfig); }, pageFunc, progressBarFunc, - saveButtonFunc, waitInfoFunc, busyInfoFuncy); + saveButtonFunc, waitInfoFunc, + busyInfoFuncy, cancelButtonFunc); if (!e) { m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig); @@ -178,3 +184,8 @@ QJsonObject OpenVpnLogic::getProtocolConfigFromPage(QJsonObject oldConfig) oldConfig.insert(config_key::additional_server_config, textAreaAdditionalServerConfig()); return oldConfig; } + +void OpenVpnLogic::onPushButtonCancelClicked() +{ + emit uiLogic()->pageLogic()->cancelDoInstallAction(true); +} diff --git a/client/ui/pages_logic/protocols/OpenVpnLogic.h b/client/ui/pages_logic/protocols/OpenVpnLogic.h index 1dafe5ee..dd861238 100644 --- a/client/ui/pages_logic/protocols/OpenVpnLogic.h +++ b/client/ui/pages_logic/protocols/OpenVpnLogic.h @@ -40,8 +40,11 @@ class OpenVpnLogic : public PageProtocolLogicBase AUTO_PROPERTY(bool, labelServerBusyVisible) AUTO_PROPERTY(QString, labelServerBusyText) + AUTO_PROPERTY(bool, pushButtonCancelVisible) + public: - Q_INVOKABLE void onPushButtonProtoOpenVpnSaveClicked(); + Q_INVOKABLE void onPushButtonSaveClicked(); + Q_INVOKABLE void onPushButtonCancelClicked(); public: explicit OpenVpnLogic(UiLogic *uiLogic, QObject *parent = nullptr); diff --git a/client/ui/pages_logic/protocols/ShadowSocksLogic.cpp b/client/ui/pages_logic/protocols/ShadowSocksLogic.cpp index c2575a4d..94a8ee04 100644 --- a/client/ui/pages_logic/protocols/ShadowSocksLogic.cpp +++ b/client/ui/pages_logic/protocols/ShadowSocksLogic.cpp @@ -97,6 +97,11 @@ void ShadowSocksLogic::onPushButtonSaveClicked() set_labelServerBusyVisible(visible); }; + ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc; + cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void { + set_pushButtonCancelVisible(visible); + }; + progressBarFunc.setTextVisibleFunc(true); progressBarFunc.setTextFunc(QString("Configuring...")); ErrorCode e = uiLogic()->pageLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ @@ -106,7 +111,8 @@ void ShadowSocksLogic::onPushButtonSaveClicked() newContainerConfig); }, pageFunc, progressBarFunc, - saveButtonFunc, waitInfoFunc, busyInfoFuncy); + saveButtonFunc, waitInfoFunc, + busyInfoFuncy, cancelButtonFunc); if (!e) { m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig); @@ -114,3 +120,8 @@ void ShadowSocksLogic::onPushButtonSaveClicked() } qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer; } + +void ShadowSocksLogic::onPushButtonCancelClicked() +{ + emit uiLogic()->pageLogic()->cancelDoInstallAction(true); +} diff --git a/client/ui/pages_logic/protocols/ShadowSocksLogic.h b/client/ui/pages_logic/protocols/ShadowSocksLogic.h index 1300511f..da859959 100644 --- a/client/ui/pages_logic/protocols/ShadowSocksLogic.h +++ b/client/ui/pages_logic/protocols/ShadowSocksLogic.h @@ -23,8 +23,12 @@ class ShadowSocksLogic : public PageProtocolLogicBase AUTO_PROPERTY(bool, labelServerBusyVisible) AUTO_PROPERTY(QString, labelServerBusyText) + + AUTO_PROPERTY(bool, pushButtonCancelVisible) + public: Q_INVOKABLE void onPushButtonSaveClicked(); + Q_INVOKABLE void onPushButtonCancelClicked(); public: explicit ShadowSocksLogic(UiLogic *uiLogic, QObject *parent = nullptr); diff --git a/client/ui/qml/Pages/PageServerConfiguringProgress.qml b/client/ui/qml/Pages/PageServerConfiguringProgress.qml index e481dbfe..87c602c3 100644 --- a/client/ui/qml/Pages/PageServerConfiguringProgress.qml +++ b/client/ui/qml/Pages/PageServerConfiguringProgress.qml @@ -10,7 +10,6 @@ PageBase { page: PageEnum.ServerConfiguringProgress logic: ServerConfiguringProgressLogic - enabled: ServerConfiguringProgressLogic.pageEnabled Caption { id: caption text: qsTr("Configuring...") @@ -56,14 +55,27 @@ PageBase { visible: ServerConfiguringProgressLogic.labelWaitInfoVisible } - ProgressBar { - id: pr + + BlueButtonType { + id: pb_cancel + z: 1 anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: logo.bottom anchors.bottomMargin: 40 - width: parent.width - 40 + width: root.width - 60 height: 40 + text: qsTr("Cancel") + visible: ServerConfiguringProgressLogic.pushButtonCancelVisible + enabled: ServerConfiguringProgressLogic.pushButtonCancelVisible + onClicked: { + ServerConfiguringProgressLogic.onPushButtonCancelClicked() + } + } + ProgressBar { + id: pr + enabled: ServerConfiguringProgressLogic.pageEnabled + anchors.fill: pb_cancel from: 0 to: ServerConfiguringProgressLogic.progressBarMaximium value: ServerConfiguringProgressLogic.progressBarValue diff --git a/client/ui/qml/Pages/Protocols/PageProtoCloak.qml b/client/ui/qml/Pages/Protocols/PageProtoCloak.qml index 17dc829a..86a2584a 100644 --- a/client/ui/qml/Pages/Protocols/PageProtoCloak.qml +++ b/client/ui/qml/Pages/Protocols/PageProtoCloak.qml @@ -129,7 +129,6 @@ PageProtocolBase { text: logic.labelInfoText } - ProgressBar { id: progressBar_proto_cloak_reset anchors.horizontalCenter: parent.horizontalCenter @@ -184,4 +183,13 @@ PageProtocolBase { } } + BlueButtonType { + anchors.fill: pb_save + text: qsTr("Cancel") + visible: logic.pushButtonCancelVisible + enabled: logic.pushButtonCancelVisible + onClicked: { + logic.onPushButtonCancelClicked() + } + } } diff --git a/client/ui/qml/Pages/Protocols/PageProtoOpenVPN.qml b/client/ui/qml/Pages/Protocols/PageProtoOpenVPN.qml index a644bf59..19dad8e6 100644 --- a/client/ui/qml/Pages/Protocols/PageProtoOpenVPN.qml +++ b/client/ui/qml/Pages/Protocols/PageProtoOpenVPN.qml @@ -37,7 +37,6 @@ PageProtocolBase { ColumnLayout { id: content - enabled: logic.pageEnabled anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right @@ -45,12 +44,13 @@ PageProtocolBase { LabelType { id: lb_subnet + enabled: logic.pageEnabled height: 21 text: qsTr("VPN Addresses Subnet") } TextFieldType { id: tf_subnet - + enabled: logic.pageEnabled implicitWidth: parent.width height: 31 text: logic.lineEditSubnetText @@ -59,15 +59,16 @@ PageProtocolBase { } } - // LabelType { id: lb_proto + enabled: logic.pageEnabled Layout.topMargin: 20 height: 21 text: qsTr("Network protocol") } Rectangle { id: rect_proto + enabled: logic.pageEnabled implicitWidth: root.width - 60 height: 71 border.width: 1 @@ -99,8 +100,8 @@ PageProtocolBase { } } - // RowLayout { + enabled: logic.pageEnabled Layout.topMargin: 10 Layout.fillWidth: true LabelType { @@ -122,12 +123,9 @@ PageProtocolBase { } } - - - // CheckBoxType { id: check_auto_enc - + enabled: logic.pageEnabled implicitWidth: parent.width height: 21 text: qsTr("Auto-negotiate encryption") @@ -140,15 +138,16 @@ PageProtocolBase { } } - // LabelType { id: lb_cipher + enabled: logic.pageEnabled height: 21 text: qsTr("Cipher") } ComboBoxType { id: cb_cipher + enabled: logic.pageEnabled && !check_auto_enc.checked implicitWidth: parent.width height: 31 @@ -175,18 +174,18 @@ PageProtocolBase { onCurrentTextChanged: { logic.comboBoxVpnCipherText = currentText } - enabled: !check_auto_enc.checked } - // LabelType { id: lb_hash + enabled: logic.pageEnabled height: 21 Layout.topMargin: 20 text: qsTr("Hash") } ComboBoxType { id: cb_hash + enabled: logic.pageEnabled && !check_auto_enc.checked height: 31 implicitWidth: parent.width model: [ @@ -212,11 +211,11 @@ PageProtocolBase { onCurrentTextChanged: { logic.comboBoxVpnHashText = currentText } - enabled: !check_auto_enc.checked } CheckBoxType { id: check_tls + enabled: logic.pageEnabled implicitWidth: parent.width Layout.topMargin: 20 height: 21 @@ -230,6 +229,7 @@ PageProtocolBase { CheckBoxType { id: check_block_dns + enabled: logic.pageEnabled implicitWidth: parent.width height: 21 text: qsTr("Block DNS requests outside of VPN") @@ -242,7 +242,7 @@ PageProtocolBase { BasicButtonType { id: pb_client_config - + enabled: logic.pageEnabled implicitWidth: parent.width height: 21 text: qsTr("Additional client config commands →") @@ -267,6 +267,7 @@ PageProtocolBase { Rectangle { id: rect_client_conf + enabled: logic.pageEnabled implicitWidth: root.width - 60 height: 101 border.width: 1 @@ -288,14 +289,12 @@ PageProtocolBase { } } } - - } BasicButtonType { id: pb_server_config - + enabled: logic.pageEnabled implicitWidth: parent.width height: 21 text: qsTr("Additional server config commands →") @@ -320,6 +319,7 @@ PageProtocolBase { Rectangle { id: rect_server_conf + enabled: logic.pageEnabled implicitWidth: root.width - 60 height: 101 border.width: 1 @@ -347,6 +347,7 @@ PageProtocolBase { LabelType { id: label_server_busy + enabled: logic.pageEnabled horizontalAlignment: Text.AlignHCenter Layout.maximumWidth: parent.width Layout.fillWidth: true @@ -356,6 +357,7 @@ PageProtocolBase { LabelType { id: label_proto_openvpn_info + enabled: logic.pageEnabled horizontalAlignment: Text.AlignHCenter Layout.maximumWidth: parent.width Layout.fillWidth: true @@ -371,18 +373,31 @@ PageProtocolBase { BlueButtonType { id: pb_save + enabled: logic.pageEnabled z: 1 height: 40 text: qsTr("Save and restart VPN") width: parent.width visible: logic.pushButtonSaveVisible onClicked: { - logic.onPushButtonProtoOpenVpnSaveClicked() + logic.onPushButtonSaveClicked() + } + } + + BlueButtonType { + z: 1 + anchors.fill: pb_save + text: qsTr("Cancel") + visible: logic.pushButtonCancelVisible + enabled: logic.pushButtonCancelVisible + onClicked: { + logic.onPushButtonCancelClicked() } } ProgressBar { id: progress_save + enabled: logic.pageEnabled anchors.fill: pb_save from: 0 to: logic.progressBarResetMaximium diff --git a/client/ui/qml/Pages/Protocols/PageProtoShadowSocks.qml b/client/ui/qml/Pages/Protocols/PageProtoShadowSocks.qml index 3fe0df26..4d627fe2 100644 --- a/client/ui/qml/Pages/Protocols/PageProtoShadowSocks.qml +++ b/client/ui/qml/Pages/Protocols/PageProtoShadowSocks.qml @@ -162,4 +162,14 @@ PageProtocolBase { logic.onPushButtonSaveClicked() } } + + BlueButtonType { + anchors.fill: pb_save + text: qsTr("Cancel") + visible: logic.pushButtonCancelVisible + enabled: logic.pushButtonCancelVisible + onClicked: { + logic.onPushButtonCancelClicked() + } + } } diff --git a/client/ui/uilogic.cpp b/client/ui/uilogic.cpp index 9d43f414..ef50c464 100644 --- a/client/ui/uilogic.cpp +++ b/client/ui/uilogic.cpp @@ -346,6 +346,11 @@ void UiLogic::installServer(QMap &containers) pageLogic()->set_labelServerBusyVisible(visible); }; + ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc; + cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void { + pageLogic()->set_pushButtonCancelVisible(visible); + }; + int count = 0; ErrorCode error; for (QMap::iterator i = containers.begin(); i != containers.end(); i++, count++) { @@ -353,7 +358,7 @@ void UiLogic::installServer(QMap &containers) error = pageLogic()->doInstallAction([&] () { return m_serverController->setupContainer(installCredentials, i.key(), i.value()); - }, pageFunc, progressBarFunc, noButton, waitInfoFunc, busyInfoFunc); + }, pageFunc, progressBarFunc, noButton, waitInfoFunc, busyInfoFunc, cancelButtonFunc); m_serverController->disconnectFromHost(installCredentials); }