1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25
26 #include "remotelinuxcheckforfreediskspaceservice.h"
27
28 #include <ssh/sshremoteprocessrunner.h>
29 #include <utils/fileutils.h>
30
31 namespace RemoteLinux {
32 namespace Internal {
33 class RemoteLinuxCheckForFreeDiskSpaceServicePrivate
34 {
35 public:
36 QString pathToCheck;
37 quint64 requiredSpaceInBytes;
38 QSsh::SshRemoteProcessRunner *processRunner;
39 };
40 } // namespace Internal
41
RemoteLinuxCheckForFreeDiskSpaceService(QObject * parent)42 RemoteLinuxCheckForFreeDiskSpaceService::RemoteLinuxCheckForFreeDiskSpaceService(QObject *parent)
43 : AbstractRemoteLinuxDeployService(parent),
44 d(new Internal::RemoteLinuxCheckForFreeDiskSpaceServicePrivate)
45 {
46 d->processRunner = nullptr;
47 d->requiredSpaceInBytes = 0;
48 }
49
~RemoteLinuxCheckForFreeDiskSpaceService()50 RemoteLinuxCheckForFreeDiskSpaceService::~RemoteLinuxCheckForFreeDiskSpaceService()
51 {
52 cleanup();
53 delete d;
54 }
55
setPathToCheck(const QString & path)56 void RemoteLinuxCheckForFreeDiskSpaceService::setPathToCheck(const QString &path)
57 {
58 d->pathToCheck = path;
59 }
60
setRequiredSpaceInBytes(quint64 sizeInBytes)61 void RemoteLinuxCheckForFreeDiskSpaceService::setRequiredSpaceInBytes(quint64 sizeInBytes)
62 {
63 d->requiredSpaceInBytes = sizeInBytes;
64 }
65
handleStdErr()66 void RemoteLinuxCheckForFreeDiskSpaceService::handleStdErr()
67 {
68 emit stdErrData(QString::fromUtf8(d->processRunner->readAllStandardError()));
69 }
70
handleProcessFinished()71 void RemoteLinuxCheckForFreeDiskSpaceService::handleProcessFinished()
72 {
73 if (!d->processRunner->processErrorString().isEmpty()) {
74 emit errorMessage(tr("Remote process failed: %1")
75 .arg(d->processRunner->processErrorString()));
76 stopDeployment();
77 return;
78
79 }
80
81 bool isNumber;
82 QByteArray processOutput = d->processRunner->readAllStandardOutput();
83 processOutput.chop(1); // newline
84 quint64 freeSpace = processOutput.toULongLong(&isNumber);
85 quint64 requiredSpaceInMegaBytes = d->requiredSpaceInBytes / (1024 * 1024);
86 if (!isNumber) {
87 emit errorMessage(tr("Unexpected output from remote process: \"%1\"")
88 .arg(QString::fromUtf8(processOutput)));
89 stopDeployment();
90 return;
91 }
92
93 freeSpace /= 1024; // convert kilobyte to megabyte
94 if (freeSpace < requiredSpaceInMegaBytes) {
95 emit errorMessage(tr("The remote file system has only %n megabytes of free space, "
96 "but %1 megabytes are required.", nullptr, freeSpace).arg(requiredSpaceInMegaBytes));
97 stopDeployment();
98 return;
99 }
100
101 emit progressMessage(tr("The remote file system has %n megabytes of free space, going ahead.",
102 nullptr, freeSpace));
103 stopDeployment();
104 }
105
isDeploymentPossible() const106 CheckResult RemoteLinuxCheckForFreeDiskSpaceService::isDeploymentPossible() const
107 {
108 if (!d->pathToCheck.startsWith(QLatin1Char('/'))) {
109 return CheckResult::failure(
110 tr("Cannot check for free disk space: \"%1\" is not an absolute path.")
111 .arg(d->pathToCheck));
112 }
113
114 return AbstractRemoteLinuxDeployService::isDeploymentPossible();
115 }
116
doDeploy()117 void RemoteLinuxCheckForFreeDiskSpaceService::doDeploy()
118 {
119 d->processRunner = new QSsh::SshRemoteProcessRunner;
120 connect(d->processRunner, &QSsh::SshRemoteProcessRunner::processClosed,
121 this, &RemoteLinuxCheckForFreeDiskSpaceService::handleProcessFinished);
122 connect(d->processRunner, &QSsh::SshRemoteProcessRunner::readyReadStandardError,
123 this, &RemoteLinuxCheckForFreeDiskSpaceService::handleStdErr);
124 const QString command = QString::fromLatin1("df -k %1 |tail -n 1 |sed 's/ */ /g' "
125 "|cut -d ' ' -f 4").arg(d->pathToCheck);
126 d->processRunner->run(command, deviceConfiguration()->sshParameters());
127 }
128
stopDeployment()129 void RemoteLinuxCheckForFreeDiskSpaceService::stopDeployment()
130 {
131 cleanup();
132 handleDeploymentDone();
133 }
134
cleanup()135 void RemoteLinuxCheckForFreeDiskSpaceService::cleanup()
136 {
137 if (d->processRunner) {
138 disconnect(d->processRunner, nullptr, this, nullptr);
139 d->processRunner->cancel();
140 delete d->processRunner;
141 d->processRunner = nullptr;
142 }
143 }
144
145 } // namespace RemoteLinux
146