diff options
author | Marcus Tillmanns <[email protected]> | 2023-09-15 14:17:11 +0200 |
---|---|---|
committer | Marcus Tillmanns <[email protected]> | 2023-09-20 08:02:04 +0000 |
commit | 189cf8054f4a75637bab70afc90be7fe65b410ed (patch) | |
tree | 1fc1532229621d64a22b847f827ef94659902905 /src/plugins/docker | |
parent | 881c48fbe78ce6cfd10fd359df29c752add521a7 (diff) |
Docker: Add network option to settings
Change-Id: Idb18435aa668f9219ae0eb2db6bd55d040ba5243
Reviewed-by: hjk <[email protected]>
Diffstat (limited to 'src/plugins/docker')
-rw-r--r-- | src/plugins/docker/dockerapi.cpp | 72 | ||||
-rw-r--r-- | src/plugins/docker/dockerapi.h | 16 | ||||
-rw-r--r-- | src/plugins/docker/dockerdevice.cpp | 56 | ||||
-rw-r--r-- | src/plugins/docker/dockerdevice.h | 1 | ||||
-rw-r--r-- | src/plugins/docker/dockerdevicewidget.cpp | 1 |
5 files changed, 136 insertions, 10 deletions
diff --git a/src/plugins/docker/dockerapi.cpp b/src/plugins/docker/dockerapi.cpp index fe89d590591..900e5bb18b2 100644 --- a/src/plugins/docker/dockerapi.cpp +++ b/src/plugins/docker/dockerapi.cpp @@ -105,4 +105,76 @@ FilePath DockerApi::dockerClient() return settings().dockerBinaryPath(); } +QFuture<Utils::expected_str<QList<Network>>> DockerApi::networks() +{ + return Utils::asyncRun([this]() -> Utils::expected_str<QList<Network>> { + QList<Network> result; + + Process process; + FilePath dockerExe = dockerClient(); + if (dockerExe.isEmpty() || !dockerExe.isExecutableFile()) + return make_unexpected(Tr::tr("Docker executable not found")); + + process.setCommand( + CommandLine(dockerExe, QStringList{"network", "ls", "--format", "{{json .}}"})); + process.runBlocking(); + + if (process.result() != ProcessResult::FinishedWithSuccess) { + return make_unexpected( + Tr::tr("Failed to retrieve docker networks. Exit code: %1. Error: %2") + .arg(process.exitCode()) + .arg(process.allOutput())); + } + + for (const auto &line : process.readAllStandardOutput().split('\n')) { + if (line.isEmpty()) + continue; + + QJsonParseError error; + QJsonDocument doc = QJsonDocument::fromJson(line.toUtf8(), &error); + + if (error.error != QJsonParseError::NoError) { + qCWarning(dockerApiLog) + << "Failed to parse docker network info:" << error.errorString(); + continue; + } + + Network network; + network.id = doc["ID"].toString(); + network.name = doc["Name"].toString(); + network.driver = doc["Driver"].toString(); + network.scope = doc["Scope"].toString(); + network.internal = doc["Internal"].toString() == "true"; + network.ipv6 = doc["IPv6"].toString() == "true"; + network.createdAt = QDateTime::fromString(doc["CreatedAt"].toString(), Qt::ISODate); + network.labels = doc["Labels"].toString(); + + result.append(network); + } + + return result; + }); +} + +QString Network::toString() const +{ + return QString(R"(ID: "%1" +Name: "%2" +Driver: "%3" +Scope: "%4" +Internal: "%5" +IPv6: "%6" +CreatedAt: "%7" +Labels: "%8" + )") + .arg(id) + .arg(name) + .arg(driver) + .arg(scope) + .arg(internal) + .arg(ipv6) + .arg(createdAt.toString(Qt::ISODate)) + .arg(labels); +} + } // Docker::Internal diff --git a/src/plugins/docker/dockerapi.h b/src/plugins/docker/dockerapi.h index 4866e84c66a..3e697654a3a 100644 --- a/src/plugins/docker/dockerapi.h +++ b/src/plugins/docker/dockerapi.h @@ -5,6 +5,7 @@ #include "dockersettings.h" +#include <utils/expected.h> #include <utils/filepath.h> #include <utils/guard.h> @@ -15,6 +16,20 @@ namespace Docker::Internal { +struct Network +{ + QString id; + QString name; + QString driver; + QString scope; + bool internal; + bool ipv6; + QDateTime createdAt; + QString labels; + + QString toString() const; +}; + class DockerApi : public QObject { Q_OBJECT @@ -27,6 +42,7 @@ public: bool canConnect(); void checkCanConnect(bool async = true); static void recheckDockerDaemon(); + QFuture<Utils::expected_str<QList<Network>>> networks(); signals: void dockerDaemonAvailableChanged(); diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index ef90a78b582..e2646dcaf30 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -69,6 +69,7 @@ #include <QPushButton> #include <QRandomGenerator> #include <QRegularExpression> +#include <QStandardItem> #include <QTextBrowser> #include <QThread> #include <QToolButton> @@ -109,8 +110,8 @@ public: private: void setupShellProcess(Process *shellProcess) final { - shellProcess->setCommand({settings().dockerBinaryPath(), - {"container", "start", "-i", "-a", m_containerId}}); + shellProcess->setCommand( + {settings().dockerBinaryPath(), {"container", "start", "-i", "-a", m_containerId}}); } CommandLine createFallbackCommand(const CommandLine &cmdLine) @@ -132,8 +133,7 @@ public: : m_dev(dev) {} - RunResult runInShell(const CommandLine &cmdLine, - const QByteArray &stdInData) const override; + RunResult runInShell(const CommandLine &cmdLine, const QByteArray &stdInData) const override; QString mapToDevicePath(const QString &hostPath) const override; DockerDevicePrivate *m_dev = nullptr; @@ -191,6 +191,40 @@ DockerDeviceSettings::DockerDeviceSettings() clangdExecutable.setLabelText(Tr::tr("Clangd Executable:")); clangdExecutable.setAllowPathFromDevice(true); + network.setSettingsKey("Network"); + network.setLabelText(Tr::tr("Network:")); + network.setDefaultValue("bridge"); + network.setFillCallback([this](const StringSelectionAspect::ResultCallback &cb) { + auto future = DockerApi::instance()->networks(); + + auto watcher = new QFutureWatcher<expected_str<QList<Network>>>(this); + watcher->setFuture(future); + QObject::connect(watcher, + &QFutureWatcher<expected_str<QList<Network>>>::finished, + this, + [watcher, cb]() { + expected_str<QList<Network>> result = watcher->result(); + if (result) { + auto items = Utils::transform(*result, [](const Network &network) { + QStandardItem *item = new QStandardItem(network.name); + item->setData(network.name); + item->setToolTip(network.toString()); + return item; + }); + cb(items); + } else { + QStandardItem *errorItem = new QStandardItem(Tr::tr("Error!")); + errorItem->setToolTip(result.error()); + cb({errorItem}); + } + }); + }); + + connect(DockerApi::instance(), + &DockerApi::dockerDaemonAvailableChanged, + &network, + &StringSelectionAspect::refill); + clangdExecutable.setValidationFunction( [](const QString &newValue) -> FancyLineEdit::AsyncValidationFuture { return Utils::asyncRun([newValue]() -> expected_str<QString> { @@ -757,9 +791,7 @@ expected_str<QString> DockerDevicePrivate::createContainer() "-e", QString("DISPLAY=%1").arg(display), "-e", - "XAUTHORITY=/.Xauthority", - "--net", - "host"}}; + "XAUTHORITY=/.Xauthority"}}; #ifdef Q_OS_UNIX // no getuid() and getgid() on Windows. @@ -767,6 +799,11 @@ expected_str<QString> DockerDevicePrivate::createContainer() dockerCreate.addArgs({"-u", QString("%1:%2").arg(getuid()).arg(getgid())}); #endif + if (!deviceSettings->network().isEmpty()) { + dockerCreate.addArg("--network"); + dockerCreate.addArg(deviceSettings->network()); + } + dockerCreate.addArgs(createMountArgs()); if (!deviceSettings->keepEntryPoint()) @@ -1206,9 +1243,8 @@ bool DockerDevicePrivate::addTemporaryMount(const FilePath &path, const FilePath if (alreadyAdded) return false; - const bool alreadyManuallyAdded = anyOf(deviceSettings->mounts(), [path](const FilePath &mount) { - return mount == path; - }); + const bool alreadyManuallyAdded = anyOf(deviceSettings->mounts(), + [path](const FilePath &mount) { return mount == path; }); if (alreadyManuallyAdded) return false; diff --git a/src/plugins/docker/dockerdevice.h b/src/plugins/docker/dockerdevice.h index c38a7746dbd..51fc05be28a 100644 --- a/src/plugins/docker/dockerdevice.h +++ b/src/plugins/docker/dockerdevice.h @@ -32,6 +32,7 @@ public: Utils::BoolAspect keepEntryPoint{this}; Utils::BoolAspect enableLldbFlags{this}; Utils::FilePathAspect clangdExecutable{this}; + Utils::StringSelectionAspect network{this}; Utils::TextDisplay containerStatus{this}; }; diff --git a/src/plugins/docker/dockerdevicewidget.cpp b/src/plugins/docker/dockerdevicewidget.cpp index 018cabb07f6..eb910b41956 100644 --- a/src/plugins/docker/dockerdevicewidget.cpp +++ b/src/plugins/docker/dockerdevicewidget.cpp @@ -167,6 +167,7 @@ DockerDeviceWidget::DockerDeviceWidget(const IDevice::Ptr &device) deviceSettings->keepEntryPoint, br, deviceSettings->enableLldbFlags, br, deviceSettings->clangdExecutable, br, + deviceSettings->network, br, Column { pathListLabel, deviceSettings->mounts, |