forked from qt-creator/qt-creator
docker: Add dockercli setting
Change-Id: I46fada555d697007042d823ef1cad0658be98e22 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -1027,6 +1027,7 @@ QtcProcess::QtcProcess(QObject *parent)
|
|||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
d(new QtcProcessPrivate(this))
|
d(new QtcProcessPrivate(this))
|
||||||
{
|
{
|
||||||
|
qRegisterMetaType<ProcessResultData>("ProcessResultData");
|
||||||
static int qProcessExitStatusMeta = qRegisterMetaType<QProcess::ExitStatus>();
|
static int qProcessExitStatusMeta = qRegisterMetaType<QProcess::ExitStatus>();
|
||||||
static int qProcessProcessErrorMeta = qRegisterMetaType<QProcess::ProcessError>();
|
static int qProcessProcessErrorMeta = qRegisterMetaType<QProcess::ProcessError>();
|
||||||
Q_UNUSED(qProcessExitStatusMeta)
|
Q_UNUSED(qProcessExitStatusMeta)
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ using namespace Utils;
|
|||||||
|
|
||||||
DockerApi *s_instance{nullptr};
|
DockerApi *s_instance{nullptr};
|
||||||
|
|
||||||
DockerApi::DockerApi()
|
DockerApi::DockerApi(QSharedPointer<DockerSettings> settings)
|
||||||
|
: m_settings(settings)
|
||||||
{
|
{
|
||||||
s_instance = this;
|
s_instance = this;
|
||||||
}
|
}
|
||||||
@@ -56,7 +57,7 @@ DockerApi *DockerApi::instance()
|
|||||||
bool DockerApi::canConnect()
|
bool DockerApi::canConnect()
|
||||||
{
|
{
|
||||||
QtcProcess process;
|
QtcProcess process;
|
||||||
FilePath dockerExe = findDockerClient();
|
FilePath dockerExe = dockerClient();
|
||||||
if (dockerExe.isEmpty() || !dockerExe.isExecutableFile())
|
if (dockerExe.isEmpty() || !dockerExe.isExecutableFile())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -83,11 +84,11 @@ void DockerApi::checkCanConnect(bool async)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
m_dockerDaemonAvailable = nullopt;
|
m_dockerDaemonAvailable = nullopt;
|
||||||
dockerDaemonAvailableChanged();
|
emit dockerDaemonAvailableChanged();
|
||||||
|
|
||||||
auto future = Utils::runAsync([lk = std::move(lk), this] {
|
auto future = Utils::runAsync([lk = std::move(lk), this] {
|
||||||
m_dockerDaemonAvailable = canConnect();
|
m_dockerDaemonAvailable = canConnect();
|
||||||
dockerDaemonAvailableChanged();
|
emit dockerDaemonAvailableChanged();
|
||||||
});
|
});
|
||||||
|
|
||||||
Core::ProgressManager::addTask(future, tr("Checking docker daemon"), "DockerPlugin");
|
Core::ProgressManager::addTask(future, tr("Checking docker daemon"), "DockerPlugin");
|
||||||
@@ -98,7 +99,7 @@ void DockerApi::checkCanConnect(bool async)
|
|||||||
bool isAvailable = canConnect();
|
bool isAvailable = canConnect();
|
||||||
if (!m_dockerDaemonAvailable.has_value() || isAvailable != m_dockerDaemonAvailable) {
|
if (!m_dockerDaemonAvailable.has_value() || isAvailable != m_dockerDaemonAvailable) {
|
||||||
m_dockerDaemonAvailable = isAvailable;
|
m_dockerDaemonAvailable = isAvailable;
|
||||||
dockerDaemonAvailableChanged();
|
emit dockerDaemonAvailableChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,11 +122,9 @@ Utils::optional<bool> DockerApi::isDockerDaemonAvailable(bool async)
|
|||||||
return s_instance->dockerDaemonAvailable(async);
|
return s_instance->dockerDaemonAvailable(async);
|
||||||
}
|
}
|
||||||
|
|
||||||
FilePath DockerApi::findDockerClient()
|
FilePath DockerApi::dockerClient()
|
||||||
{
|
{
|
||||||
if (m_dockerExecutable.isEmpty() || m_dockerExecutable.isExecutableFile())
|
return FilePath::fromString(m_settings->dockerBinaryPath.value());
|
||||||
m_dockerExecutable = FilePath::fromString("docker").searchInPath();
|
|
||||||
return m_dockerExecutable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "dockersettings.h"
|
||||||
|
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
@@ -40,7 +42,7 @@ class DockerApi : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DockerApi();
|
DockerApi(QSharedPointer<DockerSettings> settings);
|
||||||
|
|
||||||
static DockerApi *instance();
|
static DockerApi *instance();
|
||||||
|
|
||||||
@@ -56,12 +58,12 @@ public:
|
|||||||
static Utils::optional<bool> isDockerDaemonAvailable(bool async = true);
|
static Utils::optional<bool> isDockerDaemonAvailable(bool async = true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Utils::FilePath findDockerClient();
|
Utils::FilePath dockerClient();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Utils::FilePath m_dockerExecutable;
|
|
||||||
Utils::optional<bool> m_dockerDaemonAvailable;
|
Utils::optional<bool> m_dockerDaemonAvailable;
|
||||||
QMutex m_daemonCheckGuard;
|
QMutex m_daemonCheckGuard;
|
||||||
|
QSharedPointer<DockerSettings> m_settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
namespace Docker {
|
namespace Docker {
|
||||||
namespace Constants {
|
namespace Constants {
|
||||||
|
|
||||||
|
const char DOCKER[] = "docker";
|
||||||
|
|
||||||
const char DOCKER_SETTINGS_ID[] = "Docker.Settings";
|
const char DOCKER_SETTINGS_ID[] = "Docker.Settings";
|
||||||
const char DOCKER_DEVICE_TYPE[] = "DockerDeviceType";
|
const char DOCKER_DEVICE_TYPE[] = "DockerDeviceType";
|
||||||
|
|
||||||
|
|||||||
@@ -106,18 +106,20 @@ static Q_LOGGING_CATEGORY(dockerDeviceLog, "qtc.docker.device", QtWarningMsg);
|
|||||||
class ContainerShell : public Utils::DeviceShell
|
class ContainerShell : public Utils::DeviceShell
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ContainerShell(const QString &containerId)
|
ContainerShell(QSharedPointer<DockerSettings> settings, const QString &containerId)
|
||||||
: m_containerId(containerId)
|
: m_settings(settings)
|
||||||
|
, m_containerId(containerId)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupShellProcess(QtcProcess *shellProcess) final
|
void setupShellProcess(QtcProcess *shellProcess) final
|
||||||
{
|
{
|
||||||
shellProcess->setCommand({"docker", {"container", "start", "-i", "-a", m_containerId}});
|
shellProcess->setCommand({m_settings->dockerBinaryPath.filePath(), {"container", "start", "-i", "-a", m_containerId}});
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QSharedPointer<DockerSettings> m_settings;
|
||||||
QString m_containerId;
|
QString m_containerId;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -126,8 +128,9 @@ class DockerDevicePrivate : public QObject
|
|||||||
Q_DECLARE_TR_FUNCTIONS(Docker::Internal::DockerDevice)
|
Q_DECLARE_TR_FUNCTIONS(Docker::Internal::DockerDevice)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DockerDevicePrivate(DockerDevice *parent)
|
DockerDevicePrivate(DockerDevice *parent, QSharedPointer<DockerSettings> settings)
|
||||||
: q(parent)
|
: q(parent)
|
||||||
|
, m_settings(settings)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
~DockerDevicePrivate() { stopCurrentContainer(); }
|
~DockerDevicePrivate() { stopCurrentContainer(); }
|
||||||
@@ -144,6 +147,7 @@ public:
|
|||||||
|
|
||||||
DockerDevice *q;
|
DockerDevice *q;
|
||||||
DockerDeviceData m_data;
|
DockerDeviceData m_data;
|
||||||
|
QSharedPointer<DockerSettings> m_settings;
|
||||||
|
|
||||||
// For local file access
|
// For local file access
|
||||||
|
|
||||||
@@ -316,8 +320,8 @@ QString DockerDeviceData::repoAndTag() const
|
|||||||
|
|
||||||
// DockerDevice
|
// DockerDevice
|
||||||
|
|
||||||
DockerDevice::DockerDevice(const DockerDeviceData &data)
|
DockerDevice::DockerDevice(QSharedPointer<DockerSettings> settings, const DockerDeviceData &data)
|
||||||
: d(new DockerDevicePrivate(this))
|
: d(new DockerDevicePrivate(this, settings))
|
||||||
{
|
{
|
||||||
d->m_data = data;
|
d->m_data = data;
|
||||||
|
|
||||||
@@ -327,7 +331,7 @@ DockerDevice::DockerDevice(const DockerDeviceData &data)
|
|||||||
setDisplayName(tr("Docker Image \"%1\" (%2)").arg(data.repoAndTag()).arg(data.imageId));
|
setDisplayName(tr("Docker Image \"%1\" (%2)").arg(data.repoAndTag()).arg(data.imageId));
|
||||||
setAllowEmptyCommand(true);
|
setAllowEmptyCommand(true);
|
||||||
|
|
||||||
setOpenTerminal([this](const Environment &env, const FilePath &workingDir) {
|
setOpenTerminal([this, settings](const Environment &env, const FilePath &workingDir) {
|
||||||
Q_UNUSED(env); // TODO: That's the runnable's environment in general. Use it via -e below.
|
Q_UNUSED(env); // TODO: That's the runnable's environment in general. Use it via -e below.
|
||||||
updateContainerAccess();
|
updateContainerAccess();
|
||||||
if (d->m_container.isEmpty()) {
|
if (d->m_container.isEmpty()) {
|
||||||
@@ -345,7 +349,7 @@ DockerDevice::DockerDevice(const DockerDeviceData &data)
|
|||||||
});
|
});
|
||||||
|
|
||||||
const QString wd = workingDir.isEmpty() ? "/" : workingDir.path();
|
const QString wd = workingDir.isEmpty() ? "/" : workingDir.path();
|
||||||
proc->setCommand({"docker", {"exec", "-it", "-w", wd, d->m_container, "/bin/sh"}});
|
proc->setCommand({settings->dockerBinaryPath.filePath(), {"exec", "-it", "-w", wd, d->m_container, "/bin/sh"}});
|
||||||
proc->setEnvironment(Environment::systemEnvironment()); // The host system env. Intentional.
|
proc->setEnvironment(Environment::systemEnvironment()); // The host system env. Intentional.
|
||||||
proc->start();
|
proc->start();
|
||||||
});
|
});
|
||||||
@@ -385,7 +389,7 @@ void DockerDevicePrivate::stopCurrentContainer()
|
|||||||
m_shell.reset();
|
m_shell.reset();
|
||||||
|
|
||||||
QtcProcess proc;
|
QtcProcess proc;
|
||||||
proc.setCommand({"docker", {"container", "stop", m_container}});
|
proc.setCommand({m_settings->dockerBinaryPath.filePath(), {"container", "stop", m_container}});
|
||||||
|
|
||||||
m_container.clear();
|
m_container.clear();
|
||||||
|
|
||||||
@@ -410,7 +414,7 @@ void DockerDevicePrivate::startContainer()
|
|||||||
{
|
{
|
||||||
const QString display = HostOsInfo::isLinuxHost() ? QString(":0")
|
const QString display = HostOsInfo::isLinuxHost() ? QString(":0")
|
||||||
: QString(getLocalIPv4Address() + ":0.0");
|
: QString(getLocalIPv4Address() + ":0.0");
|
||||||
CommandLine dockerCreate{"docker", {"create",
|
CommandLine dockerCreate{m_settings->dockerBinaryPath.filePath(), {"create",
|
||||||
"-i",
|
"-i",
|
||||||
"--rm",
|
"--rm",
|
||||||
"-e", QString("DISPLAY=%1").arg(display),
|
"-e", QString("DISPLAY=%1").arg(display),
|
||||||
@@ -448,7 +452,7 @@ void DockerDevicePrivate::startContainer()
|
|||||||
return;
|
return;
|
||||||
LOG("Container via process: " << m_container);
|
LOG("Container via process: " << m_container);
|
||||||
|
|
||||||
m_shell = std::make_unique<ContainerShell>(m_container);
|
m_shell = std::make_unique<ContainerShell>(m_settings, m_container);
|
||||||
connect(m_shell.get(), &DeviceShell::done, this, [this] (const ProcessResultData &resultData) {
|
connect(m_shell.get(), &DeviceShell::done, this, [this] (const ProcessResultData &resultData) {
|
||||||
if (resultData.m_error != QProcess::UnknownError)
|
if (resultData.m_error != QProcess::UnknownError)
|
||||||
return;
|
return;
|
||||||
@@ -497,7 +501,7 @@ CommandLine DockerDevice::withDockerExecCmd(const Utils::CommandLine &cmd, bool
|
|||||||
args << "-i";
|
args << "-i";
|
||||||
args << d->m_container;
|
args << d->m_container;
|
||||||
|
|
||||||
CommandLine dcmd{"docker", args};
|
CommandLine dcmd{d->m_settings->dockerBinaryPath.filePath(), args};
|
||||||
dcmd.addCommandLineAsArgs(cmd);
|
dcmd.addCommandLineAsArgs(cmd);
|
||||||
return dcmd;
|
return dcmd;
|
||||||
}
|
}
|
||||||
@@ -1001,7 +1005,7 @@ bool DockerDevicePrivate::runInContainer(const CommandLine &cmd) const
|
|||||||
{
|
{
|
||||||
if (!DockerApi::isDockerDaemonAvailable(false).value_or(false))
|
if (!DockerApi::isDockerDaemonAvailable(false).value_or(false))
|
||||||
return false;
|
return false;
|
||||||
CommandLine dcmd{"docker", {"exec", m_container}};
|
CommandLine dcmd{m_settings->dockerBinaryPath.filePath(), {"exec", m_container}};
|
||||||
dcmd.addCommandLineAsArgs(cmd);
|
dcmd.addCommandLineAsArgs(cmd);
|
||||||
|
|
||||||
QtcProcess proc;
|
QtcProcess proc;
|
||||||
@@ -1062,8 +1066,9 @@ public:
|
|||||||
class DockerDeviceSetupWizard final : public QDialog
|
class DockerDeviceSetupWizard final : public QDialog
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DockerDeviceSetupWizard()
|
DockerDeviceSetupWizard(QSharedPointer<DockerSettings> settings)
|
||||||
: QDialog(ICore::dialogParent())
|
: QDialog(ICore::dialogParent())
|
||||||
|
, m_settings(settings)
|
||||||
{
|
{
|
||||||
setWindowTitle(DockerDevice::tr("Docker Image Selection"));
|
setWindowTitle(DockerDevice::tr("Docker Image Selection"));
|
||||||
resize(800, 600);
|
resize(800, 600);
|
||||||
@@ -1100,7 +1105,7 @@ public:
|
|||||||
connect(m_buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
connect(m_buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||||
m_buttons->button(QDialogButtonBox::Ok)->setEnabled(false);
|
m_buttons->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||||
|
|
||||||
CommandLine cmd{"docker", {"images", "--format", "{{.ID}}\\t{{.Repository}}\\t{{.Tag}}\\t{{.Size}}"}};
|
CommandLine cmd{m_settings->dockerBinaryPath.filePath(), {"images", "--format", "{{.ID}}\\t{{.Repository}}\\t{{.Tag}}\\t{{.Size}}"}};
|
||||||
m_log->append(DockerDevice::tr("Running \"%1\"\n").arg(cmd.toUserOutput()));
|
m_log->append(DockerDevice::tr("Running \"%1\"\n").arg(cmd.toUserOutput()));
|
||||||
|
|
||||||
m_process = new QtcProcess(this);
|
m_process = new QtcProcess(this);
|
||||||
@@ -1150,7 +1155,7 @@ public:
|
|||||||
DockerImageItem *item = m_model.itemForIndex(selectedRows.front());
|
DockerImageItem *item = m_model.itemForIndex(selectedRows.front());
|
||||||
QTC_ASSERT(item, return {});
|
QTC_ASSERT(item, return {});
|
||||||
|
|
||||||
auto device = DockerDevice::create(*item);
|
auto device = DockerDevice::create(m_settings, *item);
|
||||||
device->setupId(IDevice::ManuallyAdded);
|
device->setupId(IDevice::ManuallyAdded);
|
||||||
device->setType(Constants::DOCKER_DEVICE_TYPE);
|
device->setType(Constants::DOCKER_DEVICE_TYPE);
|
||||||
device->setMachineType(IDevice::Hardware);
|
device->setMachineType(IDevice::Hardware);
|
||||||
@@ -1163,6 +1168,7 @@ public:
|
|||||||
TreeView *m_view = nullptr;
|
TreeView *m_view = nullptr;
|
||||||
QTextBrowser *m_log = nullptr;
|
QTextBrowser *m_log = nullptr;
|
||||||
QDialogButtonBox *m_buttons;
|
QDialogButtonBox *m_buttons;
|
||||||
|
QSharedPointer<DockerSettings> m_settings;
|
||||||
|
|
||||||
QtcProcess *m_process = nullptr;
|
QtcProcess *m_process = nullptr;
|
||||||
QString m_selectedId;
|
QString m_selectedId;
|
||||||
@@ -1170,18 +1176,18 @@ public:
|
|||||||
|
|
||||||
// Factory
|
// Factory
|
||||||
|
|
||||||
DockerDeviceFactory::DockerDeviceFactory()
|
DockerDeviceFactory::DockerDeviceFactory(QSharedPointer<DockerSettings> settings)
|
||||||
: IDeviceFactory(Constants::DOCKER_DEVICE_TYPE)
|
: IDeviceFactory(Constants::DOCKER_DEVICE_TYPE)
|
||||||
{
|
{
|
||||||
setDisplayName(DockerDevice::tr("Docker Device"));
|
setDisplayName(DockerDevice::tr("Docker Device"));
|
||||||
setIcon(QIcon());
|
setIcon(QIcon());
|
||||||
setCreator([] {
|
setCreator([settings] {
|
||||||
DockerDeviceSetupWizard wizard;
|
DockerDeviceSetupWizard wizard(settings);
|
||||||
if (wizard.exec() != QDialog::Accepted)
|
if (wizard.exec() != QDialog::Accepted)
|
||||||
return IDevice::Ptr();
|
return IDevice::Ptr();
|
||||||
return wizard.device();
|
return wizard.device();
|
||||||
});
|
});
|
||||||
setConstructionFunction([] { return DockerDevice::create({}); });
|
setConstructionFunction([settings] { return DockerDevice::create(settings, {}); });
|
||||||
}
|
}
|
||||||
|
|
||||||
} // Internal
|
} // Internal
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "dockersettings.h"
|
||||||
|
|
||||||
#include <projectexplorer/devicesupport/idevice.h>
|
#include <projectexplorer/devicesupport/idevice.h>
|
||||||
#include <projectexplorer/devicesupport/idevicefactory.h>
|
#include <projectexplorer/devicesupport/idevicefactory.h>
|
||||||
#include <coreplugin/documentmanager.h>
|
#include <coreplugin/documentmanager.h>
|
||||||
@@ -56,10 +58,10 @@ public:
|
|||||||
using Ptr = QSharedPointer<DockerDevice>;
|
using Ptr = QSharedPointer<DockerDevice>;
|
||||||
using ConstPtr = QSharedPointer<const DockerDevice>;
|
using ConstPtr = QSharedPointer<const DockerDevice>;
|
||||||
|
|
||||||
explicit DockerDevice(const DockerDeviceData &data);
|
explicit DockerDevice(QSharedPointer<DockerSettings> settings, const DockerDeviceData &data);
|
||||||
~DockerDevice();
|
~DockerDevice();
|
||||||
|
|
||||||
static Ptr create(const DockerDeviceData &data) { return Ptr(new DockerDevice(data)); }
|
static Ptr create(QSharedPointer<DockerSettings> settings, const DockerDeviceData &data) { return Ptr(new DockerDevice(settings, data)); }
|
||||||
|
|
||||||
ProjectExplorer::IDeviceWidget *createWidget() override;
|
ProjectExplorer::IDeviceWidget *createWidget() override;
|
||||||
QList<ProjectExplorer::Task> validate() const override;
|
QList<ProjectExplorer::Task> validate() const override;
|
||||||
@@ -133,7 +135,7 @@ private:
|
|||||||
class DockerDeviceFactory final : public ProjectExplorer::IDeviceFactory
|
class DockerDeviceFactory final : public ProjectExplorer::IDeviceFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DockerDeviceFactory();
|
DockerDeviceFactory(QSharedPointer<DockerSettings> settings);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Internal
|
} // Internal
|
||||||
|
|||||||
@@ -25,8 +25,6 @@
|
|||||||
|
|
||||||
#include "dockerplugin.h"
|
#include "dockerplugin.h"
|
||||||
|
|
||||||
#include "dockerconstants.h"
|
|
||||||
|
|
||||||
#include "dockerapi.h"
|
#include "dockerapi.h"
|
||||||
#include "dockerdevice.h"
|
#include "dockerdevice.h"
|
||||||
#include "dockersettings.h"
|
#include "dockersettings.h"
|
||||||
@@ -45,15 +43,14 @@ namespace Internal {
|
|||||||
class DockerPluginPrivate
|
class DockerPluginPrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// DockerSettings settings;
|
QSharedPointer<DockerSettings> m_settings{new DockerSettings};
|
||||||
// DockerOptionsPage optionsPage{&settings};
|
DockerDeviceFactory deviceFactory{m_settings};
|
||||||
|
DockerSettingsPage m_settingPage{m_settings};
|
||||||
DockerDeviceFactory deviceFactory;
|
|
||||||
|
|
||||||
// DockerBuildStepFactory buildStepFactory;
|
// DockerBuildStepFactory buildStepFactory;
|
||||||
Utils::optional<bool> daemonRunning;
|
Utils::optional<bool> daemonRunning;
|
||||||
|
|
||||||
DockerApi dockerApi;
|
DockerApi dockerApi{m_settings};
|
||||||
};
|
};
|
||||||
|
|
||||||
static DockerPlugin *s_instance = nullptr;
|
static DockerPlugin *s_instance = nullptr;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2021 The Qt Company Ltd.
|
** Copyright (C) 2022 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of Qt Creator.
|
** This file is part of Qt Creator.
|
||||||
@@ -23,107 +23,63 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "dockerconstants.h"
|
|
||||||
#include "dockersettings.h"
|
#include "dockersettings.h"
|
||||||
|
|
||||||
|
#include "dockerconstants.h"
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
#include <projectexplorer/projectexplorerconstants.h>
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
|
|
||||||
|
#include <utils/filepath.h>
|
||||||
#include <utils/layoutbuilder.h>
|
#include <utils/layoutbuilder.h>
|
||||||
#include <utils/qtcprocess.h>
|
|
||||||
#include <utils/qtcsettings.h>
|
|
||||||
|
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Docker {
|
namespace Docker {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
// DockerSettings
|
|
||||||
|
|
||||||
const char SETTINGS_KEY[] = "Docker";
|
|
||||||
|
|
||||||
static DockerSettings *theSettings = nullptr;
|
|
||||||
|
|
||||||
DockerSettings::DockerSettings()
|
DockerSettings::DockerSettings()
|
||||||
{
|
{
|
||||||
theSettings = this;
|
setSettingsGroup(Constants::DOCKER);
|
||||||
setAutoApply(false);
|
setAutoApply(false);
|
||||||
|
|
||||||
|
registerAspect(&dockerBinaryPath);
|
||||||
|
dockerBinaryPath.setDisplayStyle(StringAspect::PathChooserDisplay);
|
||||||
|
dockerBinaryPath.setExpectedKind(PathChooser::ExistingCommand);
|
||||||
|
dockerBinaryPath.setDefaultValue(FilePath::fromString("docker").searchInPath().toString());
|
||||||
|
dockerBinaryPath.setDisplayName(tr("Docker CLI"));
|
||||||
|
dockerBinaryPath.setHistoryCompleter("Docker.Command.History");
|
||||||
|
dockerBinaryPath.setLabelText(tr("Command:"));
|
||||||
|
dockerBinaryPath.setSettingsKey("cli");
|
||||||
|
|
||||||
readSettings(Core::ICore::settings());
|
readSettings(Core::ICore::settings());
|
||||||
|
|
||||||
imageListFilter.setSettingsKey("DockerListFilter");
|
|
||||||
imageListFilter.setPlaceHolderText(tr("<filter>"));
|
|
||||||
imageListFilter.setDisplayStyle(StringAspect::LineEditDisplay);
|
|
||||||
imageListFilter.setLabelText(tr("Filter:"));
|
|
||||||
|
|
||||||
imageList.setDisplayStyle(StringAspect::TextEditDisplay);
|
|
||||||
imageList.setLabelText(tr("Images:"));
|
|
||||||
|
|
||||||
connect(&imageListFilter, &BaseAspect::changed, this, &DockerSettings::updateImageList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DockerSettings *DockerSettings::instance()
|
// DockerSettingsPage
|
||||||
{
|
|
||||||
return theSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DockerSettings::writeSettings(QSettings *settings) const
|
DockerSettingsPage::DockerSettingsPage(QSharedPointer<DockerSettings> settings)
|
||||||
{
|
{
|
||||||
settings->remove(SETTINGS_KEY);
|
setId(Docker::Constants::DOCKER_SETTINGS_ID);
|
||||||
settings->beginGroup(SETTINGS_KEY);
|
|
||||||
forEachAspect([settings](BaseAspect *aspect) {
|
|
||||||
QtcSettings::setValueWithDefault(settings, aspect->settingsKey(),
|
|
||||||
aspect->value(), aspect->defaultValue());
|
|
||||||
});
|
|
||||||
settings->endGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DockerSettings::updateImageList()
|
|
||||||
{
|
|
||||||
QtcProcess process;
|
|
||||||
process.setCommand({"docker", {"search", imageListFilter.value()}});
|
|
||||||
process.start();
|
|
||||||
process.waitForFinished();
|
|
||||||
imageList.setValue(process.cleanedStdOut());
|
|
||||||
}
|
|
||||||
|
|
||||||
void DockerSettings::readSettings(const QSettings *settings)
|
|
||||||
{
|
|
||||||
const QString keyRoot = QString(SETTINGS_KEY) + '/';
|
|
||||||
forEachAspect([settings, keyRoot](BaseAspect *aspect) {
|
|
||||||
QString key = aspect->settingsKey();
|
|
||||||
const QVariant value = settings->value(keyRoot + key, aspect->defaultValue());
|
|
||||||
aspect->setValue(value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// DockerOptionsPage
|
|
||||||
|
|
||||||
DockerOptionsPage::DockerOptionsPage(DockerSettings *settings)
|
|
||||||
{
|
|
||||||
setId(Constants::DOCKER_SETTINGS_ID);
|
|
||||||
setDisplayName(DockerSettings::tr("Docker"));
|
setDisplayName(DockerSettings::tr("Docker"));
|
||||||
setCategory(ProjectExplorer::Constants::DEVICE_SETTINGS_CATEGORY);
|
setCategory(ProjectExplorer::Constants::DEVICE_SETTINGS_CATEGORY);
|
||||||
setDisplayCategory(QCoreApplication::translate("ProjectExplorer", "Devices"));
|
setSettings(settings.get());
|
||||||
setCategoryIconPath(":/projectexplorer/images/settingscategory_devices.png");
|
|
||||||
setSettings(settings);
|
|
||||||
|
|
||||||
setLayouter([settings](QWidget *widget) {
|
setLayouter([settings = settings.get()](QWidget *widget) {
|
||||||
using namespace Layouting;
|
|
||||||
DockerSettings &s = *settings;
|
DockerSettings &s = *settings;
|
||||||
|
using namespace Layouting;
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
Column {
|
Column {
|
||||||
Group {
|
Group {
|
||||||
Title(DockerSettings::tr("Search Images on Docker Hub")),
|
Title(DockerSettings::tr("Configuration")),
|
||||||
Form {
|
Row { s.dockerBinaryPath }
|
||||||
s.imageListFilter,
|
|
||||||
s.imageList
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
Stretch()
|
Stretch()
|
||||||
}.attachTo(widget);
|
}.attachTo(widget);
|
||||||
|
// clang-format on
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} // Internal
|
} // namespace Internal
|
||||||
} // Docker
|
} // namespace Docker
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2021 The Qt Company Ltd.
|
** Copyright (C) 2022 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of Qt Creator.
|
** This file is part of Qt Creator.
|
||||||
@@ -25,36 +25,27 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "coreplugin/dialogs/ioptionspage.h"
|
||||||
#include <utils/aspects.h>
|
#include <utils/aspects.h>
|
||||||
#include <utils/fileutils.h>
|
|
||||||
|
|
||||||
#include <coreplugin/dialogs/ioptionspage.h>
|
|
||||||
|
|
||||||
namespace Docker {
|
namespace Docker {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class DockerSettings : public Utils::AspectContainer
|
class DockerSettings final : public Utils::AspectContainer
|
||||||
{
|
{
|
||||||
Q_DECLARE_TR_FUNCTIONS(Docker::Internal::DockerSettings)
|
Q_DECLARE_TR_FUNCTIONS(Docker::Internal::DockerSettings)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DockerSettings();
|
DockerSettings();
|
||||||
static DockerSettings *instance();
|
|
||||||
|
|
||||||
void readSettings(const QSettings *settings);
|
Utils::StringAspect dockerBinaryPath;
|
||||||
void writeSettings(QSettings *settings) const;
|
|
||||||
|
|
||||||
void updateImageList();
|
|
||||||
|
|
||||||
Utils::StringAspect imageListFilter;
|
|
||||||
Utils::StringAspect imageList;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DockerOptionsPage final : public Core::IOptionsPage
|
class DockerSettingsPage final : public Core::IOptionsPage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit DockerOptionsPage(DockerSettings *settings);
|
explicit DockerSettingsPage(QSharedPointer<DockerSettings> settings);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Internal
|
} // namespace Internal
|
||||||
} // Docker
|
} // namespace Docker
|
||||||
|
|||||||
Reference in New Issue
Block a user