diff options
author | Robert Griebl <[email protected]> | 2025-02-23 02:39:05 +0100 |
---|---|---|
committer | Robert Griebl <[email protected]> | 2025-06-06 15:27:52 +0200 |
commit | 6408f5a017ef3d1328a8e4a4a8e9c65fe9e90e07 (patch) | |
tree | c16ac74831dadfc289ebe44a3950e29472b82b97 | |
parent | 14986b7c2f700d15303c5ee425f98943b36f3d73 (diff) |
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.cpp | 26 | ||||
-rw-r--r-- | src/manager-lib/plugincontainer.h | 3 | ||||
-rw-r--r-- | src/plugin-interfaces/containerinterface.cpp | 21 | ||||
-rw-r--r-- | src/plugin-interfaces/containerinterface.h | 4 | ||||
-rw-r--r-- | src/plugins/bubblewrap-container-plugin/bubblewrapcontainer.cpp | 58 |
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") |