forked from qt-creator/qt-creator
Docker: Make mounted volumes user-configurable
Still use the so-far hardcoded "/opt" and "/data" as default, i.e. not the intended final setup which should at least pick up the source and build dirs automatically. Change-Id: If632f3f5a6e824a952938c97336df8ff58b39d67 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -239,10 +239,6 @@ class DockerDevicePrivate : public QObject
|
|||||||
public:
|
public:
|
||||||
DockerDevicePrivate(DockerDevice *parent) : q(parent)
|
DockerDevicePrivate(DockerDevice *parent) : q(parent)
|
||||||
{
|
{
|
||||||
// FIXME: Make mounts flexible
|
|
||||||
m_mounts.append("/opt");
|
|
||||||
m_mounts.append("/data");
|
|
||||||
|
|
||||||
connect(&m_mergedDirWatcher, &QFileSystemWatcher::fileChanged, this, [](const QString &path) {
|
connect(&m_mergedDirWatcher, &QFileSystemWatcher::fileChanged, this, [](const QString &path) {
|
||||||
Q_UNUSED(path)
|
Q_UNUSED(path)
|
||||||
LOG("Container watcher change, file: " << path);
|
LOG("Container watcher change, file: " << path);
|
||||||
@@ -276,7 +272,6 @@ public:
|
|||||||
QPointer<QtcProcess> m_shell;
|
QPointer<QtcProcess> m_shell;
|
||||||
QString m_container;
|
QString m_container;
|
||||||
QString m_mergedDir;
|
QString m_mergedDir;
|
||||||
QStringList m_mounts;
|
|
||||||
QFileSystemWatcher m_mergedDirWatcher;
|
QFileSystemWatcher m_mergedDirWatcher;
|
||||||
|
|
||||||
Environment m_cachedEnviroment;
|
Environment m_cachedEnviroment;
|
||||||
@@ -293,12 +288,12 @@ public:
|
|||||||
auto dockerDevice = device.dynamicCast<DockerDevice>();
|
auto dockerDevice = device.dynamicCast<DockerDevice>();
|
||||||
QTC_ASSERT(dockerDevice, return);
|
QTC_ASSERT(dockerDevice, return);
|
||||||
|
|
||||||
m_idLabel = new QLabel(tr("Image Id:"));
|
auto idLabel = new QLabel(tr("Image Id:"));
|
||||||
m_idLineEdit = new QLineEdit;
|
m_idLineEdit = new QLineEdit;
|
||||||
m_idLineEdit->setText(dockerDevice->data().imageId);
|
m_idLineEdit->setText(dockerDevice->data().imageId);
|
||||||
m_idLineEdit->setEnabled(false);
|
m_idLineEdit->setEnabled(false);
|
||||||
|
|
||||||
m_repoLabel = new QLabel(tr("Repository:"));
|
auto repoLabel = new QLabel(tr("Repository:"));
|
||||||
m_repoLineEdit = new QLineEdit;
|
m_repoLineEdit = new QLineEdit;
|
||||||
m_repoLineEdit->setText(dockerDevice->data().repo);
|
m_repoLineEdit->setText(dockerDevice->data().repo);
|
||||||
m_repoLineEdit->setEnabled(false);
|
m_repoLineEdit->setEnabled(false);
|
||||||
@@ -309,6 +304,20 @@ public:
|
|||||||
m_runAsOutsideUser->setChecked(dockerDevice->data().useLocalUidGid);
|
m_runAsOutsideUser->setChecked(dockerDevice->data().useLocalUidGid);
|
||||||
m_runAsOutsideUser->setEnabled(HostOsInfo::isLinuxHost());
|
m_runAsOutsideUser->setEnabled(HostOsInfo::isLinuxHost());
|
||||||
|
|
||||||
|
connect(m_runAsOutsideUser, &QCheckBox::toggled, this, [this, dockerDevice](bool on) {
|
||||||
|
dockerDevice->data().useLocalUidGid = on;
|
||||||
|
});
|
||||||
|
|
||||||
|
m_pathsLineEdit = new QLineEdit;
|
||||||
|
m_pathsLineEdit->setText(dockerDevice->data().repo);
|
||||||
|
m_pathsLineEdit->setToolTip(tr("Paths in this semi-colon separated list will be "
|
||||||
|
"mapped one-to-one into the docker container."));
|
||||||
|
m_pathsLineEdit->setText(dockerDevice->data().mounts.join(';'));
|
||||||
|
|
||||||
|
connect(m_pathsLineEdit, &QLineEdit::textChanged, this, [this, dockerDevice](const QString &text) {
|
||||||
|
dockerDevice->data().mounts = text.split(';');
|
||||||
|
});
|
||||||
|
|
||||||
auto logView = new QTextBrowser;
|
auto logView = new QTextBrowser;
|
||||||
|
|
||||||
auto autoDetectButton = new QPushButton(tr("Auto-detect Kit Items"));
|
auto autoDetectButton = new QPushButton(tr("Auto-detect Kit Items"));
|
||||||
@@ -327,9 +336,10 @@ public:
|
|||||||
using namespace Layouting;
|
using namespace Layouting;
|
||||||
|
|
||||||
Form {
|
Form {
|
||||||
m_idLabel, m_idLineEdit, Break(),
|
idLabel, m_idLineEdit, Break(),
|
||||||
m_repoLabel, m_repoLineEdit, Break(),
|
repoLabel, m_repoLineEdit, Break(),
|
||||||
m_runAsOutsideUser, Break(),
|
m_runAsOutsideUser, Break(),
|
||||||
|
tr("Paths to mount:"), m_pathsLineEdit, Break(),
|
||||||
Column {
|
Column {
|
||||||
Space(20),
|
Space(20),
|
||||||
Row { autoDetectButton, undoAutoDetectButton, Stretch() },
|
Row { autoDetectButton, undoAutoDetectButton, Stretch() },
|
||||||
@@ -342,11 +352,10 @@ public:
|
|||||||
void updateDeviceFromUi() final {}
|
void updateDeviceFromUi() final {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QLabel *m_idLabel;
|
|
||||||
QLineEdit *m_idLineEdit;
|
QLineEdit *m_idLineEdit;
|
||||||
QLabel *m_repoLabel;
|
|
||||||
QLineEdit *m_repoLineEdit;
|
QLineEdit *m_repoLineEdit;
|
||||||
QCheckBox *m_runAsOutsideUser;
|
QCheckBox *m_runAsOutsideUser;
|
||||||
|
QLineEdit *m_pathsLineEdit;
|
||||||
};
|
};
|
||||||
|
|
||||||
IDeviceWidget *DockerDevice::createWidget()
|
IDeviceWidget *DockerDevice::createWidget()
|
||||||
@@ -410,6 +419,11 @@ const DockerDeviceData &DockerDevice::data() const
|
|||||||
return d->m_data;
|
return d->m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DockerDeviceData &DockerDevice::data()
|
||||||
|
{
|
||||||
|
return d->m_data;
|
||||||
|
}
|
||||||
|
|
||||||
void DockerDevicePrivate::undoAutoDetect(QTextBrowser *log) const
|
void DockerDevicePrivate::undoAutoDetect(QTextBrowser *log) const
|
||||||
{
|
{
|
||||||
const QString id = q->id().toString();
|
const QString id = q->id().toString();
|
||||||
@@ -597,7 +611,7 @@ void DockerDevicePrivate::tryCreateLocalFileAccess()
|
|||||||
dockerRun.addArgs({"-u", QString("%1:%2").arg(getuid()).arg(getgid())});
|
dockerRun.addArgs({"-u", QString("%1:%2").arg(getuid()).arg(getgid())});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (const QString &mount : qAsConst(m_mounts))
|
for (const QString &mount : qAsConst(m_data.mounts))
|
||||||
dockerRun.addArgs({"-v", mount + ':' + mount});
|
dockerRun.addArgs({"-v", mount + ':' + mount});
|
||||||
|
|
||||||
dockerRun.addArg(m_data.imageId);
|
dockerRun.addArg(m_data.imageId);
|
||||||
@@ -661,7 +675,7 @@ FilePath DockerDevice::mapToLocalAccess(const FilePath &filePath) const
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(!d->m_mergedDir.isEmpty(), return {});
|
QTC_ASSERT(!d->m_mergedDir.isEmpty(), return {});
|
||||||
QString path = filePath.path();
|
QString path = filePath.path();
|
||||||
for (const QString &mount : qAsConst(d->m_mounts)) {
|
for (const QString &mount : qAsConst(d->m_data.mounts)) {
|
||||||
if (path.startsWith(mount + '/'))
|
if (path.startsWith(mount + '/'))
|
||||||
return FilePath::fromString(path);
|
return FilePath::fromString(path);
|
||||||
}
|
}
|
||||||
@@ -688,6 +702,7 @@ const char DockerDeviceDataRepoKey[] = "DockerDeviceDataRepo";
|
|||||||
const char DockerDeviceDataTagKey[] = "DockerDeviceDataTag";
|
const char DockerDeviceDataTagKey[] = "DockerDeviceDataTag";
|
||||||
const char DockerDeviceDataSizeKey[] = "DockerDeviceDataSize";
|
const char DockerDeviceDataSizeKey[] = "DockerDeviceDataSize";
|
||||||
const char DockerDeviceUseOutsideUser[] = "DockerDeviceUseUidGid";
|
const char DockerDeviceUseOutsideUser[] = "DockerDeviceUseUidGid";
|
||||||
|
const char DockerDeviceMappedPaths[] = "DockerDeviceMappedPaths";
|
||||||
|
|
||||||
void DockerDevice::fromMap(const QVariantMap &map)
|
void DockerDevice::fromMap(const QVariantMap &map)
|
||||||
{
|
{
|
||||||
@@ -698,6 +713,7 @@ void DockerDevice::fromMap(const QVariantMap &map)
|
|||||||
d->m_data.size = map.value(DockerDeviceDataSizeKey).toString();
|
d->m_data.size = map.value(DockerDeviceDataSizeKey).toString();
|
||||||
d->m_data.useLocalUidGid = map.value(DockerDeviceUseOutsideUser,
|
d->m_data.useLocalUidGid = map.value(DockerDeviceUseOutsideUser,
|
||||||
HostOsInfo::isLinuxHost()).toBool();
|
HostOsInfo::isLinuxHost()).toBool();
|
||||||
|
d->m_data.mounts = map.value(DockerDeviceMappedPaths).toStringList();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap DockerDevice::toMap() const
|
QVariantMap DockerDevice::toMap() const
|
||||||
@@ -708,6 +724,7 @@ QVariantMap DockerDevice::toMap() const
|
|||||||
map.insert(DockerDeviceDataTagKey, d->m_data.tag);
|
map.insert(DockerDeviceDataTagKey, d->m_data.tag);
|
||||||
map.insert(DockerDeviceDataSizeKey, d->m_data.size);
|
map.insert(DockerDeviceDataSizeKey, d->m_data.size);
|
||||||
map.insert(DockerDeviceUseOutsideUser, d->m_data.useLocalUidGid);
|
map.insert(DockerDeviceUseOutsideUser, d->m_data.useLocalUidGid);
|
||||||
|
map.insert(DockerDeviceMappedPaths, d->m_data.mounts);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ public:
|
|||||||
QString tag;
|
QString tag;
|
||||||
QString size;
|
QString size;
|
||||||
bool useLocalUidGid = true;
|
bool useLocalUidGid = true;
|
||||||
|
QStringList mounts = {"/opt", "/data"};
|
||||||
};
|
};
|
||||||
|
|
||||||
class DockerDevice : public ProjectExplorer::IDevice
|
class DockerDevice : public ProjectExplorer::IDevice
|
||||||
@@ -100,6 +101,7 @@ public:
|
|||||||
Utils::Environment systemEnvironment() const override;
|
Utils::Environment systemEnvironment() const override;
|
||||||
|
|
||||||
const DockerDeviceData &data() const;
|
const DockerDeviceData &data() const;
|
||||||
|
DockerDeviceData &data();
|
||||||
|
|
||||||
void tryCreateLocalFileAccess() const;
|
void tryCreateLocalFileAccess() const;
|
||||||
bool hasLocalFileAccess() const;
|
bool hasLocalFileAccess() const;
|
||||||
|
|||||||
Reference in New Issue
Block a user