forked from qt-creator/qt-creator
Docker: Handle docker daemon
Avoid calling the docker daemon again and again if it is currently not running. Change-Id: I17afa2eca098589bd362149d18e090252ef83f6e Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -49,6 +49,7 @@
|
|||||||
#include <utils/basetreeview.h>
|
#include <utils/basetreeview.h>
|
||||||
#include <utils/environment.h>
|
#include <utils/environment.h>
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
|
#include <utils/utilsicons.h>
|
||||||
#include <utils/layoutbuilder.h>
|
#include <utils/layoutbuilder.h>
|
||||||
#include <utils/overridecursor.h>
|
#include <utils/overridecursor.h>
|
||||||
#include <utils/port.h>
|
#include <utils/port.h>
|
||||||
@@ -69,6 +70,7 @@
|
|||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QTextBrowser>
|
#include <QTextBrowser>
|
||||||
|
#include <QToolButton>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
#ifdef Q_OS_UNIX
|
#ifdef Q_OS_UNIX
|
||||||
@@ -312,6 +314,14 @@ public:
|
|||||||
QFileSystemWatcher m_mergedDirWatcher;
|
QFileSystemWatcher m_mergedDirWatcher;
|
||||||
|
|
||||||
Environment m_cachedEnviroment;
|
Environment m_cachedEnviroment;
|
||||||
|
|
||||||
|
enum LocalAccessState
|
||||||
|
{
|
||||||
|
NotEvaluated,
|
||||||
|
NoDaemon,
|
||||||
|
Accessible,
|
||||||
|
NotAccessible
|
||||||
|
} m_accessible = NotEvaluated;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DockerDeviceWidget final : public IDeviceWidget
|
class DockerDeviceWidget final : public IDeviceWidget
|
||||||
@@ -337,6 +347,17 @@ public:
|
|||||||
m_repoLineEdit->setText(data.repo);
|
m_repoLineEdit->setText(data.repo);
|
||||||
m_repoLineEdit->setEnabled(false);
|
m_repoLineEdit->setEnabled(false);
|
||||||
|
|
||||||
|
auto daemonStateLabel = new QLabel(tr("Daemon state:"));
|
||||||
|
m_daemonReset = new QToolButton;
|
||||||
|
m_daemonReset->setIcon(Icons::INFO.icon());
|
||||||
|
m_daemonReset->setToolTip(tr("Daemon state not evaluated."));
|
||||||
|
|
||||||
|
connect(m_daemonReset, &QToolButton::clicked, this, [this, dockerDevice] {
|
||||||
|
dockerDevice->resetDaemonState();
|
||||||
|
m_daemonReset->setIcon(Icons::INFO.icon());
|
||||||
|
m_daemonReset->setToolTip(tr("Daemon state not evaluated."));
|
||||||
|
});
|
||||||
|
|
||||||
m_runAsOutsideUser = new QCheckBox(tr("Run as outside user"));
|
m_runAsOutsideUser = new QCheckBox(tr("Run as outside user"));
|
||||||
m_runAsOutsideUser->setToolTip(tr("Use user ID and group ID of the user running Qt Creator "
|
m_runAsOutsideUser->setToolTip(tr("Use user ID and group ID of the user running Qt Creator "
|
||||||
"in the Docker container."));
|
"in the Docker container."));
|
||||||
@@ -369,6 +390,16 @@ public:
|
|||||||
logView->clear();
|
logView->clear();
|
||||||
dockerDevice->tryCreateLocalFileAccess();
|
dockerDevice->tryCreateLocalFileAccess();
|
||||||
m_kitItemDetector.autoDetect(id);
|
m_kitItemDetector.autoDetect(id);
|
||||||
|
|
||||||
|
if (!dockerDevice->isDaemonRunning()) {
|
||||||
|
logView->append(tr("Docker daemon appears to be not running."));
|
||||||
|
m_daemonReset->setToolTip(tr("Daemon not running. Push to reset the state."));
|
||||||
|
m_daemonReset->setIcon(Icons::CRITICAL.icon());
|
||||||
|
} else {
|
||||||
|
m_daemonReset->setToolTip(tr("Docker daemon running."));
|
||||||
|
m_daemonReset->setIcon(Icons::OK.icon());
|
||||||
|
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(undoAutoDetectButton, &QPushButton::clicked, this, [this, logView, id = data.id()] {
|
connect(undoAutoDetectButton, &QPushButton::clicked, this, [this, logView, id = data.id()] {
|
||||||
@@ -381,6 +412,7 @@ public:
|
|||||||
Form {
|
Form {
|
||||||
idLabel, m_idLineEdit, Break(),
|
idLabel, m_idLineEdit, Break(),
|
||||||
repoLabel, m_repoLineEdit, Break(),
|
repoLabel, m_repoLineEdit, Break(),
|
||||||
|
daemonStateLabel, m_daemonReset, Break(),
|
||||||
m_runAsOutsideUser, Break(),
|
m_runAsOutsideUser, Break(),
|
||||||
tr("Paths to mount:"), m_pathsLineEdit, Break(),
|
tr("Paths to mount:"), m_pathsLineEdit, Break(),
|
||||||
Column {
|
Column {
|
||||||
@@ -397,6 +429,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
QLineEdit *m_idLineEdit;
|
QLineEdit *m_idLineEdit;
|
||||||
QLineEdit *m_repoLineEdit;
|
QLineEdit *m_repoLineEdit;
|
||||||
|
QToolButton *m_daemonReset;
|
||||||
QCheckBox *m_runAsOutsideUser;
|
QCheckBox *m_runAsOutsideUser;
|
||||||
QLineEdit *m_pathsLineEdit;
|
QLineEdit *m_pathsLineEdit;
|
||||||
|
|
||||||
@@ -648,7 +681,7 @@ void DockerDevice::tryCreateLocalFileAccess() const
|
|||||||
|
|
||||||
void DockerDevicePrivate::stopCurrentContainer()
|
void DockerDevicePrivate::stopCurrentContainer()
|
||||||
{
|
{
|
||||||
if (m_container.isEmpty())
|
if (m_container.isEmpty() || m_accessible == NoDaemon)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QtcProcess proc;
|
QtcProcess proc;
|
||||||
@@ -662,7 +695,7 @@ void DockerDevicePrivate::stopCurrentContainer()
|
|||||||
|
|
||||||
void DockerDevicePrivate::tryCreateLocalFileAccess()
|
void DockerDevicePrivate::tryCreateLocalFileAccess()
|
||||||
{
|
{
|
||||||
if (!m_container.isEmpty())
|
if (!m_container.isEmpty() || m_accessible == NoDaemon)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QString tempFileName;
|
QString tempFileName;
|
||||||
@@ -701,6 +734,14 @@ void DockerDevicePrivate::tryCreateLocalFileAccess()
|
|||||||
LOG("RES: " << m_shell->result()
|
LOG("RES: " << m_shell->result()
|
||||||
<< " STDOUT: " << m_shell->readAllStandardOutput()
|
<< " STDOUT: " << m_shell->readAllStandardOutput()
|
||||||
<< " STDERR: " << m_shell->readAllStandardError());
|
<< " STDERR: " << m_shell->readAllStandardError());
|
||||||
|
if (m_shell->exitCode() != 0) {
|
||||||
|
m_accessible = NoDaemon;
|
||||||
|
LOG("DOCKER DAEMON NOT RUNNING?");
|
||||||
|
MessageManager::writeFlashing(tr("Docker Daemon appears to be not running. "
|
||||||
|
"Verify daemon is up and running and reset the "
|
||||||
|
"docker daemon on the docker device settings page "
|
||||||
|
"or restart Qt Creator."));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_container.clear();
|
m_container.clear();
|
||||||
});
|
});
|
||||||
@@ -723,10 +764,11 @@ void DockerDevicePrivate::tryCreateLocalFileAccess()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i == 20) {
|
if (i == 20 || m_accessible == NoDaemon) {
|
||||||
qWarning("Docker cid file empty.");
|
qWarning("Docker cid file empty.");
|
||||||
return; // No
|
return; // No
|
||||||
}
|
}
|
||||||
|
qApp->processEvents(); // FIXME turn this for-loop into QEventLoop
|
||||||
QThread::msleep(100);
|
QThread::msleep(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -753,11 +795,13 @@ void DockerDevicePrivate::tryCreateLocalFileAccess()
|
|||||||
// of using wsl or a named pipe.
|
// of using wsl or a named pipe.
|
||||||
// TODO investigate how to make it possible nevertheless.
|
// TODO investigate how to make it possible nevertheless.
|
||||||
m_mergedDir.clear();
|
m_mergedDir.clear();
|
||||||
|
m_accessible = NotAccessible;
|
||||||
MessageManager::writeSilently(tr("This is expected on Windows."));
|
MessageManager::writeSilently(tr("This is expected on Windows."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_accessible = Accessible;
|
||||||
m_mergedDirWatcher.addPath(m_mergedDir);
|
m_mergedDirWatcher.addPath(m_mergedDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -766,6 +810,24 @@ bool DockerDevice::hasLocalFileAccess() const
|
|||||||
return !d->m_mergedDir.isEmpty();
|
return !d->m_mergedDir.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DockerDevice::isDaemonRunning() const
|
||||||
|
{
|
||||||
|
switch (d->m_accessible) {
|
||||||
|
case DockerDevicePrivate::NoDaemon:
|
||||||
|
return false;
|
||||||
|
case DockerDevicePrivate::NotEvaluated: // FIXME?
|
||||||
|
case DockerDevicePrivate::Accessible:
|
||||||
|
case DockerDevicePrivate::NotAccessible:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockerDevice::resetDaemonState()
|
||||||
|
{
|
||||||
|
d->m_accessible = DockerDevicePrivate::NotEvaluated;
|
||||||
|
}
|
||||||
|
|
||||||
void DockerDevice::setMounts(const QStringList &mounts) const
|
void DockerDevice::setMounts(const QStringList &mounts) const
|
||||||
{
|
{
|
||||||
d->m_data.mounts = mounts;
|
d->m_data.mounts = mounts;
|
||||||
@@ -1183,7 +1245,7 @@ bool DockerDevice::writeFileContents(const Utils::FilePath &filePath, const QByt
|
|||||||
void DockerDevice::runProcess(QtcProcess &process) const
|
void DockerDevice::runProcess(QtcProcess &process) const
|
||||||
{
|
{
|
||||||
tryCreateLocalFileAccess();
|
tryCreateLocalFileAccess();
|
||||||
if (d->m_container.isEmpty()) {
|
if (d->m_container.isEmpty() || d->m_accessible == DockerDevicePrivate::NoDaemon) {
|
||||||
LOG("No container set to run " << process.commandLine().toUserOutput());
|
LOG("No container set to run " << process.commandLine().toUserOutput());
|
||||||
QTC_CHECK(false);
|
QTC_CHECK(false);
|
||||||
process.setResult(QtcProcess::StartFailed);
|
process.setResult(QtcProcess::StartFailed);
|
||||||
@@ -1237,6 +1299,8 @@ void DockerDevicePrivate::fetchSystemEnviroment()
|
|||||||
|
|
||||||
int DockerDevicePrivate::runSynchronously(const CommandLine &cmd) const
|
int DockerDevicePrivate::runSynchronously(const CommandLine &cmd) const
|
||||||
{
|
{
|
||||||
|
if (m_accessible == NoDaemon)
|
||||||
|
return -1;
|
||||||
CommandLine dcmd{"docker", {"exec", m_container}};
|
CommandLine dcmd{"docker", {"exec", m_container}};
|
||||||
dcmd.addArgs(cmd);
|
dcmd.addArgs(cmd);
|
||||||
|
|
||||||
|
@@ -107,6 +107,8 @@ public:
|
|||||||
|
|
||||||
void tryCreateLocalFileAccess() const;
|
void tryCreateLocalFileAccess() const;
|
||||||
bool hasLocalFileAccess() const;
|
bool hasLocalFileAccess() const;
|
||||||
|
bool isDaemonRunning() const;
|
||||||
|
void resetDaemonState();
|
||||||
void setMounts(const QStringList &mounts) const;
|
void setMounts(const QStringList &mounts) const;
|
||||||
|
|
||||||
Utils::FilePath mapToLocalAccess(const Utils::FilePath &filePath) const;
|
Utils::FilePath mapToLocalAccess(const Utils::FilePath &filePath) const;
|
||||||
|
Reference in New Issue
Block a user