aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/docker/dockerdevice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/docker/dockerdevice.cpp')
-rw-r--r--src/plugins/docker/dockerdevice.cpp261
1 files changed, 40 insertions, 221 deletions
diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp
index bcab94bcb8b..be7124c995e 100644
--- a/src/plugins/docker/dockerdevice.cpp
+++ b/src/plugins/docker/dockerdevice.cpp
@@ -32,6 +32,7 @@
#include <utils/algorithm.h>
#include <utils/basetreeview.h>
+#include <utils/devicefileaccess.h>
#include <utils/deviceshell.h>
#include <utils/environment.h>
#include <utils/fileutils.h>
@@ -113,6 +114,25 @@ private:
FilePath m_devicePath;
};
+class DockerDeviceFileAccess : public UnixDeviceFileAccess
+{
+public:
+ DockerDeviceFileAccess(DockerDevicePrivate *dev)
+ : m_dev(dev)
+ {}
+
+ RunResult runInShell(const QString &executable,
+ const QStringList &arguments,
+ const QByteArray &stdInData) const override;
+
+ std::optional<QByteArray> fileContents(
+ const FilePath &filePath,
+ qint64 limit,
+ qint64 offset) const override;
+
+ DockerDevicePrivate *m_dev = nullptr;
+};
+
class DockerDevicePrivate : public QObject
{
public:
@@ -129,8 +149,6 @@ public:
return runInShell(cmd, stdInData).exitCode == 0;
}
- std::optional<QByteArray> fileContents(const FilePath &filePath, qint64 limit, qint64 offset);
-
void updateContainerAccess();
void changeMounts(QStringList newMounts);
bool ensureReachable(const FilePath &other);
@@ -177,8 +195,8 @@ public:
QString m_container;
Environment m_cachedEnviroment;
- bool m_useFind = true; // prefer find over ls and hacks, but be able to use ls as fallback
bool m_isShutdown = false;
+ DockerDeviceFileAccess m_fileAccess{this};
};
class DockerProcessImpl : public Utils::ProcessInterface
@@ -337,9 +355,28 @@ Tasks DockerDevicePrivate::validateMounts() const
return result;
}
+RunResult DockerDeviceFileAccess::runInShell(
+ const QString &executable,
+ const QStringList &arguments,
+ const QByteArray &stdInData) const
+{
+ QTC_ASSERT(m_dev, return {});
+ return m_dev->runInShell({FilePath::fromString(executable), arguments}, stdInData);
+}
+
+std::optional<QByteArray> DockerDeviceFileAccess::fileContents(
+ const FilePath &filePath,
+ qint64 limit,
+ qint64 offset) const
+{
+ m_dev->updateContainerAccess();
+ return UnixDeviceFileAccess::fileContents(filePath, limit, offset);
+}
+
DockerDevice::DockerDevice(DockerSettings *settings, const DockerDeviceData &data)
: d(new DockerDevicePrivate(this, settings, data))
{
+ setFileAccess(&d->m_fileAccess);
setDisplayType(Tr::tr("Docker"));
setOsType(OsTypeOtherUnix);
setDefaultDisplayName(Tr::tr("Docker Image"));
@@ -778,165 +815,6 @@ bool DockerDevice::handlesFile(const FilePath &filePath) const
return false;
}
-bool DockerDevice::isExecutableFile(const FilePath &filePath) const
-{
- QTC_ASSERT(handlesFile(filePath), return false);
- const QString path = filePath.path();
- return d->runInShellSuccess({"test", {"-x", path}});
-}
-
-bool DockerDevice::isReadableFile(const FilePath &filePath) const
-{
- QTC_ASSERT(handlesFile(filePath), return false);
- const QString path = filePath.path();
- return d->runInShellSuccess({"test", {"-r", path, "-a", "-f", path}});
-}
-
-bool DockerDevice::isWritableFile(const Utils::FilePath &filePath) const
-{
- QTC_ASSERT(handlesFile(filePath), return false);
- const QString path = filePath.path();
- return d->runInShellSuccess({"test", {"-w", path, "-a", "-f", path}});
-}
-
-bool DockerDevice::isReadableDirectory(const FilePath &filePath) const
-{
- QTC_ASSERT(handlesFile(filePath), return false);
- const QString path = filePath.path();
- return d->runInShellSuccess({"test", {"-r", path, "-a", "-d", path}});
-}
-
-bool DockerDevice::isWritableDirectory(const FilePath &filePath) const
-{
- QTC_ASSERT(handlesFile(filePath), return false);
- const QString path = filePath.path();
- return d->runInShellSuccess({"test", {"-w", path, "-a", "-d", path}});
-}
-
-bool DockerDevice::isFile(const FilePath &filePath) const
-{
- QTC_ASSERT(handlesFile(filePath), return false);
- const QString path = filePath.path();
- return d->runInShellSuccess({"test", {"-f", path}});
-}
-
-bool DockerDevice::isDirectory(const FilePath &filePath) const
-{
- QTC_ASSERT(handlesFile(filePath), return false);
- const QString path = filePath.path();
- return d->runInShellSuccess({"test", {"-d", path}});
-}
-
-bool DockerDevice::createDirectory(const FilePath &filePath) const
-{
- QTC_ASSERT(handlesFile(filePath), return false);
- const QString path = filePath.path();
- return d->runInShellSuccess({"mkdir", {"-p", path}});
-}
-
-bool DockerDevice::exists(const FilePath &filePath) const
-{
- QTC_ASSERT(handlesFile(filePath), return false);
- const QString path = filePath.path();
- return d->runInShellSuccess({"test", {"-e", path}});
-}
-
-bool DockerDevice::ensureExistingFile(const FilePath &filePath) const
-{
- QTC_ASSERT(handlesFile(filePath), return false);
- const QString path = filePath.path();
- return d->runInShellSuccess({"touch", {path}});
-}
-
-bool DockerDevice::removeFile(const FilePath &filePath) const
-{
- QTC_ASSERT(handlesFile(filePath), return false);
- return d->runInShellSuccess({"rm", {filePath.path()}});
-}
-
-bool DockerDevice::removeRecursively(const FilePath &filePath) const
-{
- QTC_ASSERT(handlesFile(filePath), return false);
- QTC_ASSERT(filePath.path().startsWith('/'), return false);
-
- const QString path = filePath.cleanPath().path();
- // We are expecting this only to be called in a context of build directories or similar.
- // Chicken out in some cases that _might_ be user code errors.
- QTC_ASSERT(path.startsWith('/'), return false);
- const int levelsNeeded = path.startsWith("/home/") ? 4 : 3;
- QTC_ASSERT(path.count('/') >= levelsNeeded, return false);
-
- return d->runInShellSuccess({"rm", {"-rf", "--", path}});
-}
-
-bool DockerDevice::copyFile(const FilePath &filePath, const FilePath &target) const
-{
- QTC_ASSERT(handlesFile(filePath), return false);
- QTC_ASSERT(handlesFile(target), return false);
- return d->runInShellSuccess({"cp", {filePath.path(), target.path()}});
-}
-
-bool DockerDevice::renameFile(const FilePath &filePath, const FilePath &target) const
-{
- QTC_ASSERT(handlesFile(filePath), return false);
- QTC_ASSERT(handlesFile(target), return false);
- return d->runInShellSuccess({"mv", {filePath.path(), target.path()}});
-}
-
-QDateTime DockerDevice::lastModified(const FilePath &filePath) const
-{
- QTC_ASSERT(handlesFile(filePath), return {});
- const RunResult result = d->runInShell({"stat", {"-L", "-c", "%Y", filePath.path()}});
- qint64 secs = result.stdOut.toLongLong();
- const QDateTime dt = QDateTime::fromSecsSinceEpoch(secs, Qt::UTC);
- return dt;
-}
-
-FilePath DockerDevice::symLinkTarget(const FilePath &filePath) const
-{
- QTC_ASSERT(handlesFile(filePath), return {});
- const RunResult result = d->runInShell({"readlink", {"-n", "-e", filePath.path()}});
- const QString out = QString::fromUtf8(result.stdOut);
- return out.isEmpty() ? FilePath() : filePath.withNewPath(out);
-}
-
-qint64 DockerDevice::fileSize(const FilePath &filePath) const
-{
- QTC_ASSERT(handlesFile(filePath), return -1);
- const RunResult result = d->runInShell({"stat", {"-L", "-c", "%s", filePath.path()}});
- return result.stdOut.toLongLong();
-}
-
-QFileDevice::Permissions DockerDevice::permissions(const FilePath &filePath) const
-{
- QTC_ASSERT(handlesFile(filePath), return {});
-
- const RunResult result = d->runInShell({"stat", {"-L", "-c", "%a", filePath.path()}});
- const uint bits = result.stdOut.toUInt(nullptr, 8);
- QFileDevice::Permissions perm = {};
-#define BIT(n, p) if (bits & (1<<n)) perm |= QFileDevice::p
- BIT(0, ExeOther);
- BIT(1, WriteOther);
- BIT(2, ReadOther);
- BIT(3, ExeGroup);
- BIT(4, WriteGroup);
- BIT(5, ReadGroup);
- BIT(6, ExeUser);
- BIT(7, WriteUser);
- BIT(8, ReadUser);
-#undef BIT
- return perm;
-}
-
-bool DockerDevice::setPermissions(const FilePath &filePath,
- QFileDevice::Permissions permissions) const
-{
- Q_UNUSED(permissions)
- QTC_ASSERT(handlesFile(filePath), return {});
- QTC_CHECK(false); // FIXME: Implement.
- return false;
-}
-
bool DockerDevice::ensureReachable(const FilePath &other) const
{
if (other.needsDevice())
@@ -947,43 +825,6 @@ bool DockerDevice::ensureReachable(const FilePath &other) const
return d->ensureReachable(other.parentDir());
}
-void DockerDevice::iterateDirectory(const FilePath &filePath,
- const FilePath::IterateDirCallback &callBack,
- const FileFilter &filter) const
-{
- QTC_ASSERT(handlesFile(filePath), return);
- auto runInShell = [this](const CommandLine &cmd) { return d->runInShell(cmd); };
- FileUtils::iterateUnixDirectory(filePath, filter, &d->m_useFind, runInShell, callBack);
-}
-
-std::optional<QByteArray> DockerDevice::fileContents(const FilePath &filePath,
- qint64 limit,
- qint64 offset) const
-{
- QTC_ASSERT(handlesFile(filePath), return {});
- return d->fileContents(filePath, limit, offset);
-}
-
-bool DockerDevice::writeFileContents(const FilePath &filePath,
- const QByteArray &data,
- qint64 offset) const
-{
- QTC_ASSERT(handlesFile(filePath), return {});
- CommandLine cmd({"dd", {"of=" + filePath.path()}});
- if (offset != 0) {
- cmd.addArg("bs=1");
- cmd.addArg(QString("seek=%1").arg(offset));
- }
- return d->runInShellSuccess(cmd, data);
-}
-
-FilePathInfo DockerDevice::filePathInfo(const FilePath &filePath) const
-{
- QTC_ASSERT(handlesFile(filePath), return {});
- const RunResult stat = d->runInShell({"stat", {"-L", "-c", "%f %Y %s", filePath.path()}});
- return FileUtils::filePathInfoFromTriple(QString::fromLatin1(stat.stdOut));
-}
-
Environment DockerDevice::systemEnvironment() const
{
return d->environment();
@@ -995,28 +836,6 @@ void DockerDevice::aboutToBeRemoved() const
detector.undoAutoDetect(id().toString());
}
-std::optional<QByteArray> DockerDevicePrivate::fileContents(const FilePath &filePath,
- qint64 limit,
- qint64 offset)
-{
- updateContainerAccess();
-
- QStringList args = {"if=" + filePath.path(), "status=none"};
- if (limit > 0 || offset > 0) {
- const qint64 gcd = std::gcd(limit, offset);
- args += {QString("bs=%1").arg(gcd),
- QString("count=%1").arg(limit / gcd),
- QString("seek=%1").arg(offset / gcd)};
- }
-
- const RunResult r = m_shell->runInShell({"dd", args});
-
- if (r.exitCode != 0)
- return {};
-
- return r.stdOut;
-}
-
void DockerDevicePrivate::fetchSystemEnviroment()
{
updateContainerAccess();