DockerDevice: Implements ensureReachable

Change-Id: I2c479b1cf7a61021f27222e2e936903a9f39e1d8
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Marcus Tillmanns
2022-09-14 16:40:28 +02:00
parent e3f375925d
commit 33abca1c0b
2 changed files with 75 additions and 16 deletions

View File

@@ -127,6 +127,7 @@ public:
void updateContainerAccess();
void changeMounts(QStringList newMounts);
bool ensureReachable(const FilePath &other);
void shutdown();
QString containerId() { return m_container; }
@@ -150,11 +151,18 @@ private:
void stopCurrentContainer();
void fetchSystemEnviroment();
bool addTemporaryMount(const FilePath &path, const FilePath &containerPath);
DockerDevice *const q;
DockerDeviceData m_data;
DockerSettings *m_settings;
// For local file access
struct TemporaryMountInfo {
FilePath path;
FilePath containerPath;
};
QList<TemporaryMountInfo> m_temporaryMounts;
std::unique_ptr<ContainerShell> m_shell;
@@ -469,6 +477,12 @@ bool DockerDevicePrivate::createContainer()
dockerCreate.addArgs({"-v", q->debugDumperPath().toUserOutput() + ':' + dumperPath.path()});
q->setDebugDumperPath(dumperPath);
for (const auto &[path, containerPath] : qAsConst(m_temporaryMounts)) {
if (path.isEmpty())
continue;
dockerCreate.addArgs({"-v", path.nativePath() + ':' + containerPath.nativePath()});
}
dockerCreate.addArgs({"--entrypoint", "/bin/sh"});
dockerCreate.addArg(m_data.repoAndTag());
@@ -846,6 +860,16 @@ bool DockerDevice::setPermissions(const FilePath &filePath, QFileDevice::Permiss
return false;
}
bool DockerDevice::ensureReachable(const FilePath &other) const
{
if (other.needsDevice())
return false;
if (other.isDir())
return d->ensureReachable(other);
return d->ensureReachable(other.parentDir());
}
void DockerDevice::iterateWithFind(const FilePath &filePath,
const std::function<bool(const Utils::FilePath &)> &callBack,
const FileFilter &filter) const
@@ -1256,6 +1280,21 @@ void DockerDeviceFactory::shutdownExistingDevices()
}
}
bool DockerDevicePrivate::addTemporaryMount(const FilePath &path, const FilePath &containerPath)
{
bool alreadyAdded = anyOf(m_temporaryMounts,
[containerPath](const TemporaryMountInfo &info) {
return info.containerPath == containerPath;
});
if (alreadyAdded)
return false;
qCDebug(dockerDeviceLog) << "Adding temporary mount:" << path;
m_temporaryMounts.append({path, containerPath});
stopCurrentContainer(); // Force re-start with new mounts.
return true;
}
Environment DockerDevicePrivate::environment()
{
if (!m_cachedEnviroment.isValid())
@@ -1281,6 +1320,26 @@ void DockerDevicePrivate::changeMounts(QStringList newMounts)
}
}
bool DockerDevicePrivate::ensureReachable(const FilePath &other)
{
for (const QString &mount : m_data.mounts) {
const FilePath fMount = FilePath::fromString(mount);
if (other.isChildOf(fMount))
return true;
}
for (const auto &[path, containerPath] : m_temporaryMounts) {
if (path.path() != containerPath.path())
continue;
if (other.isChildOf(path))
return true;
}
addTemporaryMount(other, other);
return true;
}
void DockerDevicePrivate::setData(const DockerDeviceData &data)
{
if (m_data != data) {

View File

@@ -5,9 +5,10 @@
#include "dockersettings.h"
#include <coreplugin/documentmanager.h>
#include <projectexplorer/devicesupport/idevice.h>
#include <projectexplorer/devicesupport/idevicefactory.h>
#include <coreplugin/documentmanager.h>
#include <utils/aspects.h>
@@ -20,17 +21,11 @@ class DockerDeviceData
public:
bool operator==(const DockerDeviceData &other) const
{
return imageId == other.imageId
&& repo == other.repo
&& tag == other.tag
&& useLocalUidGid == other.useLocalUidGid
&& mounts == other.mounts;
return imageId == other.imageId && repo == other.repo && tag == other.tag
&& useLocalUidGid == other.useLocalUidGid && mounts == other.mounts;
}
bool operator!=(const DockerDeviceData &other) const
{
return !(*this == other);
}
bool operator!=(const DockerDeviceData &other) const { return !(*this == other); }
// Used for "docker run"
QString repoAndTag() const
@@ -63,7 +58,10 @@ public:
void shutdown();
static Ptr create(DockerSettings *settings, const DockerDeviceData &data) { return Ptr(new DockerDevice(settings, data)); }
static Ptr create(DockerSettings *settings, const DockerDeviceData &data)
{
return Ptr(new DockerDevice(settings, data));
}
ProjectExplorer::IDeviceWidget *createWidget() override;
QList<ProjectExplorer::Task> validate() const override;
@@ -110,7 +108,9 @@ public:
QDateTime lastModified(const Utils::FilePath &filePath) const override;
qint64 fileSize(const Utils::FilePath &filePath) const override;
QFileDevice::Permissions permissions(const Utils::FilePath &filePath) const override;
bool setPermissions(const Utils::FilePath &filePath, QFileDevice::Permissions permissions) const override;
bool setPermissions(const Utils::FilePath &filePath,
QFileDevice::Permissions permissions) const override;
bool ensureReachable(const Utils::FilePath &other) const override;
Utils::Environment systemEnvironment() const override;
@@ -151,6 +151,6 @@ private:
std::vector<QWeakPointer<DockerDevice>> m_existingDevices;
};
} // Docker::Internal
} // namespace Docker::Internal
Q_DECLARE_METATYPE(Docker::Internal::DockerDeviceData)