summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Griebl <[email protected]>2025-02-23 02:39:05 +0100
committerRobert Griebl <[email protected]>2025-06-06 15:27:52 +0200
commit6408f5a017ef3d1328a8e4a4a8e9c65fe9e90e07 (patch)
treec16ac74831dadfc289ebe44a3950e29472b82b97
parent14986b7c2f700d15303c5ee425f98943b36f3d73 (diff)
bwrap: move the DBus and Wayland socket parsing to ContainerHelpersHEADdev
We had to bump the plugin iid for the stop() change, so now's the perfect time to extend the Helpers API. Change-Id: I3070bbb12c721027594d629311f67890c6924696 Pick-to: 6.10 Reviewed-by: Dominik Holland <[email protected]>
-rw-r--r--src/manager-lib/plugincontainer.cpp26
-rw-r--r--src/manager-lib/plugincontainer.h3
-rw-r--r--src/plugin-interfaces/containerinterface.cpp21
-rw-r--r--src/plugin-interfaces/containerinterface.h4
-rw-r--r--src/plugins/bubblewrap-container-plugin/bubblewrapcontainer.cpp58
5 files changed, 74 insertions, 38 deletions
diff --git a/src/manager-lib/plugincontainer.cpp b/src/manager-lib/plugincontainer.cpp
index daabe0e4..63a8792a 100644
--- a/src/manager-lib/plugincontainer.cpp
+++ b/src/manager-lib/plugincontainer.cpp
@@ -206,6 +206,32 @@ int PluginContainerHelperFunctions::watchdogSignal()
return UnixSignalHandler::watchdogSignal();
}
+QString PluginContainerHelperFunctions::checkDBusSocketPath(const QString &dbusAddress, const QByteArray &typeHint)
+{
+ // parse the actual socket file name from the DBus address specification
+ QString socketPath = dbusAddress;
+ socketPath = socketPath.mid(socketPath.indexOf(u'=') + 1);
+ socketPath = socketPath.left(socketPath.indexOf(u','));
+ QFileInfo socketInfo(socketPath);
+ if (!socketInfo.exists()) {
+ QByteArray err = typeHint + " DBus socket doesn't exist: " + socketPath.toLocal8Bit();
+ throw std::runtime_error(err);
+ }
+ return socketInfo.absoluteFilePath();
+}
+
+QString PluginContainerHelperFunctions::checkWaylandSocketPath(const QString &xdgRuntimeDir, const QString &waylandDisplay)
+{
+ // parse the wayland socket name from wayland env variables
+ QString socketPath = xdgRuntimeDir + u'/' + waylandDisplay;
+ QFileInfo socketInfo(socketPath);
+ if (!socketInfo.exists()) {
+ QByteArray err = "Wayland socket doesn't exist: " + socketPath.toLocal8Bit();
+ throw std::runtime_error(err);
+ }
+ return socketInfo.absoluteFilePath();
+}
+
QT_END_NAMESPACE_AM
#include "moc_plugincontainer.cpp"
diff --git a/src/manager-lib/plugincontainer.h b/src/manager-lib/plugincontainer.h
index ddb575c0..5aa98c56 100644
--- a/src/manager-lib/plugincontainer.h
+++ b/src/manager-lib/plugincontainer.h
@@ -24,6 +24,9 @@ public:
quint64 namespacePid) override;
int watchdogSignal() override;
+
+ QString checkDBusSocketPath(const QString &dbusAddress, const QByteArray &typeHint) override;
+ QString checkWaylandSocketPath(const QString &xdgRuntimeDir, const QString &waylandDisplay) override;
};
class PluginContainerManager : public AbstractContainerManager
diff --git a/src/plugin-interfaces/containerinterface.cpp b/src/plugin-interfaces/containerinterface.cpp
index 1a27014f..6f390321 100644
--- a/src/plugin-interfaces/containerinterface.cpp
+++ b/src/plugin-interfaces/containerinterface.cpp
@@ -492,7 +492,7 @@ bool ContainerManagerInterface::initialize(ContainerHelperFunctions *) { return
namespace.
\note This function needs root privileges.
- \note This functions will throw \c std::exceptions on error and will simply return on
+ \note This functions will throw a \c std::exception on error and will simply return on
successful completion.
*/
@@ -504,3 +504,22 @@ bool ContainerManagerInterface::initialize(ContainerHelperFunctions *) { return
\l{ContainerInterface::stop}{stop} with \l{ContainerInterface::WatchdogExit}{WatchdogExit}
via ContainerInterface.
*/
+
+/*! \fn QString ContainerHelperFunctions::checkDBusSocketPath(const QString &dbusAddress, const QByteArray &typeHint)
+ \since 6.10
+
+ This function parses the given \a dbusAddress to check if the referenced D-Bus socket exists.
+ If it does, this function returns the absolute path to that socket.
+ If the socket does not exist, it throws a \c std::exception.
+
+ The \a typeHint is used to provide context for the exception's error message (e.g.
+ \c "session" or \c "p2p").
+*/
+
+/*! \fn QString ContainerHelperFunctions::checkWaylandSocketPath(const QString &xdgRuntimeDir, const QString &waylandDisplay)
+ \since 6.10
+
+ Checks if a Wayland socket exists in the given \a xdgRuntimeDir named \a waylandDisplay.
+ If it does, this function returns the absolute path to that socket.
+ If the socket does not exist, it throws a \c std::exception.
+*/
diff --git a/src/plugin-interfaces/containerinterface.h b/src/plugin-interfaces/containerinterface.h
index f64ece4b..4bfb3a19 100644
--- a/src/plugin-interfaces/containerinterface.h
+++ b/src/plugin-interfaces/containerinterface.h
@@ -104,6 +104,10 @@ public:
// added in 6.10:
virtual int watchdogSignal() = 0;
+
+ // these two will throw std::exceptions on error:
+ virtual QString checkDBusSocketPath(const QString &dbusAddress, const QByteArray &typeHint) = 0;
+ virtual QString checkWaylandSocketPath(const QString &xdgRuntimeDir, const QString &waylandDisplay) = 0;
};
class ContainerManagerInterface
diff --git a/src/plugins/bubblewrap-container-plugin/bubblewrapcontainer.cpp b/src/plugins/bubblewrap-container-plugin/bubblewrapcontainer.cpp
index 74085f87..67802c0f 100644
--- a/src/plugins/bubblewrap-container-plugin/bubblewrapcontainer.cpp
+++ b/src/plugins/bubblewrap-container-plugin/bubblewrapcontainer.cpp
@@ -501,44 +501,32 @@ bool BubblewrapContainer::start(const QStringList &arguments, const QMap<QString
// Pass the write end of the pipe to bwrap
bwrapCommand += { u"--json-status-fd"_s, QString::number(m_statusPipeFd[1]) };
- // parse the actual socket file name from the DBus specification
- // This could be moved into a helper class
- QString dbusP2PSocket = amConfig.value(u"dbus"_s).toMap().value(u"p2p"_s).toString();
- dbusP2PSocket = dbusP2PSocket.mid(dbusP2PSocket.indexOf(u'=') + 1);
- dbusP2PSocket = dbusP2PSocket.left(dbusP2PSocket.indexOf(u','));
- QFileInfo dbusP2PInfo(dbusP2PSocket);
- if (!dbusP2PInfo.exists()) {
- qCWarning(lcBwrap) << "p2p dbus socket doesn't exist: " << dbusP2PInfo.absoluteFilePath();
- return false;
- }
+ try {
+ // export all additional sockets
+ auto *h = manager()->helpers();
- // parse the actual socket file name from the DBus specification
- // This could be moved into a helper class
- QByteArray dbusSessionBusAddress = qgetenv("DBUS_SESSION_BUS_ADDRESS");
- QString sessionBusSocket = QString::fromLocal8Bit(dbusSessionBusAddress);
- sessionBusSocket = sessionBusSocket.mid(sessionBusSocket.indexOf(u'=') + 1);
- sessionBusSocket = sessionBusSocket.left(sessionBusSocket.indexOf(u','));
- QFileInfo sessionBusInfo(sessionBusSocket);
- if (!sessionBusInfo.exists()) {
- qCWarning(lcBwrap) << "session dbus socket doesn't exist: " << sessionBusInfo.absoluteFilePath();
- return false;
- }
+ const QString dbusP2PSocket = h->checkDBusSocketPath(
+ amConfig.value(u"dbus"_s).toMap().value(u"p2p"_s).toString(), "P2P");
+ bwrapCommand += { u"--ro-bind"_s, dbusP2PSocket, dbusP2PSocket };
+
+ const QString dbusSessionBusAddress = qEnvironmentVariable("DBUS_SESSION_BUS_ADDRESS");
+ const QString sessionBusSocket = h->checkDBusSocketPath(dbusSessionBusAddress, "Session");
+ bwrapCommand += { u"--ro-bind"_s, sessionBusSocket, sessionBusSocket };
+ bwrapCommand += { u"--setenv"_s, u"DBUS_SESSION_BUS_ADDRESS"_s, dbusSessionBusAddress };
- // parse the wayland socket name from wayland env variables
- // This could be moved into a helper class
- QByteArray waylandDisplayName = qgetenv("WAYLAND_DISPLAY");
- QByteArray xdgRuntimeDir = qgetenv("XDG_RUNTIME_DIR");
- QFileInfo waylandDisplayInfo(QString::fromLocal8Bit(xdgRuntimeDir) + u"/"_s + QString::fromLocal8Bit(waylandDisplayName));
- if (!waylandDisplayInfo.exists()) {
- qCWarning(lcBwrap) << "wayland socket doesn't exist: " << waylandDisplayInfo.absoluteFilePath();
+ const QString xdgRuntimeDir = qEnvironmentVariable("XDG_RUNTIME_DIR");
+ const QString waylandDisplay = qEnvironmentVariable("WAYLAND_DISPLAY");
+ const QString waylandSocket = h->checkWaylandSocketPath(xdgRuntimeDir, waylandDisplay);
+
+ bwrapCommand += { u"--ro-bind"_s, waylandSocket, waylandSocket };
+ bwrapCommand += { u"--setenv"_s, u"XDG_RUNTIME_DIR"_s, xdgRuntimeDir };
+ bwrapCommand += { u"--setenv"_s, u"WAYLAND_DISPLAY"_s, waylandDisplay };
+
+ } catch (const std::exception &e) {
+ qCWarning(lcBwrap) << e.what();
return false;
}
- // export all additional sockets and the actual appliaction
- bwrapCommand += { u"--ro-bind"_s, dbusP2PInfo.absoluteFilePath(), dbusP2PInfo.absoluteFilePath() };
- bwrapCommand += { u"--ro-bind"_s, sessionBusInfo.absoluteFilePath(), sessionBusInfo.absoluteFilePath() };
- bwrapCommand += { u"--ro-bind"_s, waylandDisplayInfo.absoluteFilePath(), waylandDisplayInfo.absoluteFilePath() };
-
// If the hostPath exists we can mount it directly.
// Otherwise we are quick launching a container and have to make sure the container path exists
// to be able to mount to it afterwards.
@@ -548,10 +536,6 @@ bool BubblewrapContainer::start(const QStringList &arguments, const QMap<QString
bwrapCommand += { u"--dir"_s, m_containerPath };
// Add all needed env variables
- bwrapCommand += { u"--setenv"_s, u"XDG_RUNTIME_DIR"_s, QString::fromLocal8Bit(xdgRuntimeDir) };
- bwrapCommand += { u"--setenv"_s, u"WAYLAND_DISPLAY"_s, QString::fromLocal8Bit(waylandDisplayName) };
- bwrapCommand += { u"--setenv"_s, u"DBUS_SESSION_BUS_ADDRESS"_s, QString::fromLocal8Bit(dbusSessionBusAddress) };
-
const auto allEnvKeys = QProcessEnvironment::systemEnvironment().keys();
for (const auto &key : allEnvKeys) {
if (key.startsWith(u"LC_"_s) || key == u"LANG")