Docker: Use repo + tag for image identification

Makes configurations a bit better exchangable (sdktool...).

Change-Id: Ia566a516afea2205c973527e02ce5664634ebbdc
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
hjk
2022-02-08 09:41:46 +01:00
parent a6fcb4b3ce
commit 0b131fae72
3 changed files with 60 additions and 27 deletions

View File

@@ -94,10 +94,20 @@ private:
{ {
MacroExpander *expander = target()->kit()->macroExpander(); MacroExpander *expander = target()->kit()->macroExpander();
expander->registerVariable("BuildDevice:DockerImage", expander->registerVariable("BuildDevice:DockerImage",
"Build Host Docker Image ID", [=]() -> QString { "Build Host Docker Image ID", [this] {
const DockerDevice *dockerDevice = dockerBuildDevice(); const DockerDevice *dockerDevice = dockerBuildDevice();
return dockerDevice ? dockerDevice->data().imageId : QString(); return dockerDevice ? dockerDevice->data().imageId : QString();
}, true); }, true);
expander->registerVariable("BuildDevice:DockerRepo",
"Build Host Docker Repo", [this] {
const DockerDevice *dockerDevice = dockerBuildDevice();
return dockerDevice ? dockerDevice->data().repo : QString();
}, true);
expander->registerVariable("BuildDevice:DockerTag",
"Build Host Docker Tag", [this] {
const DockerDevice *dockerDevice = dockerBuildDevice();
return dockerDevice ? dockerDevice->data().tag : QString();
}, true);
return expander; return expander;
} }

View File

@@ -307,16 +307,21 @@ public:
DockerDeviceData &data = dockerDevice->data(); DockerDeviceData &data = dockerDevice->data();
auto idLabel = new QLabel(tr("Image ID:"));
m_idLineEdit = new QLineEdit;
m_idLineEdit->setText(data.imageId);
m_idLineEdit->setEnabled(false);
auto repoLabel = new QLabel(tr("Repository:")); auto repoLabel = new QLabel(tr("Repository:"));
m_repoLineEdit = new QLineEdit; m_repoLineEdit = new QLineEdit;
m_repoLineEdit->setText(data.repo); m_repoLineEdit->setText(data.repo);
m_repoLineEdit->setEnabled(false); m_repoLineEdit->setEnabled(false);
auto tagLabel = new QLabel(tr("Tag:"));
m_tagLineEdit = new QLineEdit;
m_tagLineEdit->setText(data.tag);
m_tagLineEdit->setEnabled(false);
auto idLabel = new QLabel(tr("Image ID:"));
m_idLineEdit = new QLineEdit;
m_idLineEdit->setText(data.imageId);
m_idLineEdit->setEnabled(false);
auto daemonStateLabel = new QLabel(tr("Daemon state:")); auto daemonStateLabel = new QLabel(tr("Daemon state:"));
m_daemonReset = new QToolButton; m_daemonReset = new QToolButton;
m_daemonReset->setToolTip(tr("Clears detected daemon state. " m_daemonReset->setToolTip(tr("Clears detected daemon state. "
@@ -399,11 +404,11 @@ public:
}; };
connect(autoDetectButton, &QPushButton::clicked, this, connect(autoDetectButton, &QPushButton::clicked, this,
[this, logView, id = data.id(), dockerDevice, searchPaths] { [this, logView, data, dockerDevice, searchPaths] {
logView->clear(); logView->clear();
dockerDevice->updateContainerAccess(); dockerDevice->updateContainerAccess();
m_kitItemDetector.autoDetect(id, searchPaths()); m_kitItemDetector.autoDetect(data.autodetectId(), searchPaths());
if (DockerPlugin::isDaemonRunning().value_or(false) == false) if (DockerPlugin::isDaemonRunning().value_or(false) == false)
logView->append(tr("Docker daemon appears to be not running.")); logView->append(tr("Docker daemon appears to be not running."));
@@ -412,21 +417,22 @@ public:
updateDaemonStateTexts(); updateDaemonStateTexts();
}); });
connect(undoAutoDetectButton, &QPushButton::clicked, this, [this, logView, id = data.id()] { connect(undoAutoDetectButton, &QPushButton::clicked, this, [this, logView, data] {
logView->clear(); logView->clear();
m_kitItemDetector.undoAutoDetect(id); m_kitItemDetector.undoAutoDetect(data.autodetectId());
}); });
connect(listAutoDetectedButton, &QPushButton::clicked, this, [this, logView, id = data.id()] { connect(listAutoDetectedButton, &QPushButton::clicked, this, [this, logView, data] {
logView->clear(); logView->clear();
m_kitItemDetector.listAutoDetected(id); m_kitItemDetector.listAutoDetected(data.autodetectId());
}); });
using namespace Layouting; using namespace Layouting;
Form { Form {
idLabel, m_idLineEdit, Break(),
repoLabel, m_repoLineEdit, Break(), repoLabel, m_repoLineEdit, Break(),
tagLabel, m_tagLineEdit, Break(),
idLabel, m_idLineEdit, Break(),
daemonStateLabel, m_daemonReset, m_daemonState, Break(), daemonStateLabel, m_daemonReset, m_daemonState, Break(),
m_runAsOutsideUser, Break(), m_runAsOutsideUser, Break(),
#ifdef ALLOW_LOCAL_ACCESS #ifdef ALLOW_LOCAL_ACCESS
@@ -465,8 +471,9 @@ public:
void updateDaemonStateTexts(); void updateDaemonStateTexts();
private: private:
QLineEdit *m_idLineEdit;
QLineEdit *m_repoLineEdit; QLineEdit *m_repoLineEdit;
QLineEdit *m_tagLineEdit;
QLineEdit *m_idLineEdit;
QToolButton *m_daemonReset; QToolButton *m_daemonReset;
QLabel *m_daemonState; QLabel *m_daemonState;
QCheckBox *m_runAsOutsideUser; QCheckBox *m_runAsOutsideUser;
@@ -496,6 +503,19 @@ Tasks DockerDevice::validate() const
} }
// DockerDeviceData
QString DockerDeviceData::dockerId() const
{
if (repo == "<none>")
return imageId;
if (tag == "<none>")
return repo;
return repo + ':' + tag;
}
// DockerDevice // DockerDevice
DockerDevice::DockerDevice(const DockerDeviceData &data) DockerDevice::DockerDevice(const DockerDeviceData &data)
@@ -506,7 +526,7 @@ DockerDevice::DockerDevice(const DockerDeviceData &data)
setDisplayType(tr("Docker")); setDisplayType(tr("Docker"));
setOsType(OsTypeOtherUnix); setOsType(OsTypeOtherUnix);
setDefaultDisplayName(tr("Docker Image"));; setDefaultDisplayName(tr("Docker Image"));;
setDisplayName(tr("Docker Image \"%1\" (%2)").arg(data.repo).arg(data.imageId)); setDisplayName(tr("Docker Image \"%1\" (%2)").arg(data.dockerId()).arg(data.imageId));
setAllowEmptyCommand(true); setAllowEmptyCommand(true);
setOpenTerminal([this](const Environment &env, const FilePath &workingDir) { setOpenTerminal([this](const Environment &env, const FilePath &workingDir) {
@@ -865,7 +885,7 @@ void DockerDevicePrivate::startContainer()
dockerCreate.addArgs({"-v", q->debugDumperPath().toUserOutput() + ':' + dumperPath.path()}); dockerCreate.addArgs({"-v", q->debugDumperPath().toUserOutput() + ':' + dumperPath.path()});
q->setDebugDumperPath(dumperPath); q->setDebugDumperPath(dumperPath);
dockerCreate.addArgs({"--entrypoint", "/bin/sh", m_data.imageId}); dockerCreate.addArgs({"--entrypoint", "/bin/sh", m_data.dockerId()});
LOG("RUNNING: " << dockerCreate.toUserOutput()); LOG("RUNNING: " << dockerCreate.toUserOutput());
QtcProcess createProcess; QtcProcess createProcess;
@@ -1044,9 +1064,9 @@ const char DockerDeviceMappedPaths[] = "DockerDeviceMappedPaths";
void DockerDevice::fromMap(const QVariantMap &map) void DockerDevice::fromMap(const QVariantMap &map)
{ {
ProjectExplorer::IDevice::fromMap(map); ProjectExplorer::IDevice::fromMap(map);
d->m_data.imageId = map.value(DockerDeviceDataImageIdKey).toString();
d->m_data.repo = map.value(DockerDeviceDataRepoKey).toString(); d->m_data.repo = map.value(DockerDeviceDataRepoKey).toString();
d->m_data.tag = map.value(DockerDeviceDataTagKey).toString(); d->m_data.tag = map.value(DockerDeviceDataTagKey).toString();
d->m_data.imageId = map.value(DockerDeviceDataImageIdKey).toString();
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();
@@ -1058,9 +1078,9 @@ void DockerDevice::fromMap(const QVariantMap &map)
QVariantMap DockerDevice::toMap() const QVariantMap DockerDevice::toMap() const
{ {
QVariantMap map = ProjectExplorer::IDevice::toMap(); QVariantMap map = ProjectExplorer::IDevice::toMap();
map.insert(DockerDeviceDataImageIdKey, d->m_data.imageId);
map.insert(DockerDeviceDataRepoKey, d->m_data.repo); map.insert(DockerDeviceDataRepoKey, d->m_data.repo);
map.insert(DockerDeviceDataTagKey, d->m_data.tag); map.insert(DockerDeviceDataTagKey, d->m_data.tag);
map.insert(DockerDeviceDataImageIdKey, d->m_data.imageId);
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(DockerDeviceUseFilePathMapping, d->m_data.useFilePathMapping); map.insert(DockerDeviceUseFilePathMapping, d->m_data.useFilePathMapping);
@@ -1112,7 +1132,7 @@ FilePath DockerDevice::mapToGlobalPath(const FilePath &pathOnDevice) const
} }
FilePath result; FilePath result;
result.setScheme("docker"); result.setScheme("docker");
result.setHost(d->m_data.imageId); result.setHost(d->m_data.dockerId());
result.setPath(pathOnDevice.path()); result.setPath(pathOnDevice.path());
return result; return result;
} }
@@ -1132,7 +1152,7 @@ QString DockerDevice::mapToDevicePath(const Utils::FilePath &globalPath) const
bool DockerDevice::handlesFile(const FilePath &filePath) const bool DockerDevice::handlesFile(const FilePath &filePath) const
{ {
return filePath.scheme() == "docker" && filePath.host() == d->m_data.imageId; return filePath.scheme() == "docker" && filePath.host() == d->m_data.dockerId();
} }
bool DockerDevice::isExecutableFile(const FilePath &filePath) const bool DockerDevice::isExecutableFile(const FilePath &filePath) const
@@ -1682,7 +1702,7 @@ Environment DockerDevice::systemEnvironment() const
void DockerDevice::aboutToBeRemoved() const void DockerDevice::aboutToBeRemoved() const
{ {
KitDetector detector(sharedFromThis()); KitDetector detector(sharedFromThis());
detector.undoAutoDetect(d->m_data.id()); detector.undoAutoDetect(d->m_data.autodetectId());
} }
void DockerDevicePrivate::fetchSystemEnviroment() void DockerDevicePrivate::fetchSystemEnviroment()
@@ -1785,15 +1805,15 @@ public:
switch (column) { switch (column) {
case 0: case 0:
if (role == Qt::DisplayRole) if (role == Qt::DisplayRole)
return imageId; return repo;
break; break;
case 1: case 1:
if (role == Qt::DisplayRole) if (role == Qt::DisplayRole)
return repo; return tag;
break; break;
case 2: case 2:
if (role == Qt::DisplayRole) if (role == Qt::DisplayRole)
return tag; return imageId;
break; break;
case 3: case 3:
if (role == Qt::DisplayRole) if (role == Qt::DisplayRole)
@@ -1814,7 +1834,7 @@ public:
setWindowTitle(DockerDevice::tr("Docker Image Selection")); setWindowTitle(DockerDevice::tr("Docker Image Selection"));
resize(800, 600); resize(800, 600);
m_model.setHeader({"Image", "Repository", "Tag", "Size"}); m_model.setHeader({"Repository", "Tag", "Image", "Size"});
m_view = new TreeView; m_view = new TreeView;
m_view->setModel(&m_model); m_view->setModel(&m_model);
@@ -1886,7 +1906,7 @@ public:
QTC_ASSERT(item, return {}); QTC_ASSERT(item, return {});
auto device = DockerDevice::create(*item); auto device = DockerDevice::create(*item);
device->setupId(IDevice::ManuallyAdded, Id::fromString(item->id())); device->setupId(IDevice::ManuallyAdded, Id::fromString(item->autodetectId()));
device->setType(Constants::DOCKER_DEVICE_TYPE); device->setType(Constants::DOCKER_DEVICE_TYPE);
device->setMachineType(IDevice::Hardware); device->setMachineType(IDevice::Hardware);

View File

@@ -37,7 +37,10 @@ namespace Internal {
class DockerDeviceData class DockerDeviceData
{ {
public: public:
QString id() const { return "docker:" + imageId; } // Used for "docker run" and for host parts of FilePaths
QString dockerId() const;
// Used as autodetection source string
QString autodetectId() const { return "docker:" + dockerId(); }
QString imageId; QString imageId;
QString repo; QString repo;