From 3944e9469916d9314cd575af45d10190fe8c1bc2 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sun, 7 Apr 2019 20:03:48 +0200 Subject: [PATCH 01/17] Initial work on an integrated system update mechanism --- .../qtavahiservicebrowserimplementation_p.cpp | 2 + libnymea-core/jsonrpc/jsonrpcserver.cpp | 2 + libnymea-core/jsonrpc/systemhandler.cpp | 147 ++++++++++++++++++ libnymea-core/jsonrpc/systemhandler.h | 60 +++++++ libnymea-core/libnymea-core.pro | 8 +- libnymea-core/nymeacore.cpp | 14 ++ libnymea-core/nymeacore.h | 6 + libnymea-core/platform/platform.cpp | 76 +++++++++ libnymea-core/platform/platform.h | 30 ++++ libnymea-core/system/system.cpp | 88 +++++++++++ libnymea-core/system/system.h | 45 ++++++ libnymea/coap/coap.h | 2 - libnymea/libnymea.pro | 10 +- libnymea/loggingcategories.cpp | 2 + libnymea/loggingcategories.h | 6 +- libnymea/plugin/platformplugin.cpp | 6 + libnymea/plugin/platformplugin.h | 24 +++ libnymea/plugin/platformsystemcontroller.cpp | 6 + libnymea/plugin/platformsystemcontroller.h | 26 ++++ libnymea/plugin/platformupdatecontroller.cpp | 15 ++ libnymea/plugin/platformupdatecontroller.h | 37 +++++ server/main.cpp | 4 +- 22 files changed, 607 insertions(+), 9 deletions(-) create mode 100644 libnymea-core/jsonrpc/systemhandler.cpp create mode 100644 libnymea-core/jsonrpc/systemhandler.h create mode 100644 libnymea-core/platform/platform.cpp create mode 100644 libnymea-core/platform/platform.h create mode 100644 libnymea-core/system/system.cpp create mode 100644 libnymea-core/system/system.h create mode 100644 libnymea/plugin/platformplugin.cpp create mode 100644 libnymea/plugin/platformplugin.h create mode 100644 libnymea/plugin/platformsystemcontroller.cpp create mode 100644 libnymea/plugin/platformsystemcontroller.h create mode 100644 libnymea/plugin/platformupdatecontroller.cpp create mode 100644 libnymea/plugin/platformupdatecontroller.h diff --git a/libnymea-core/hardware/network/avahi/qtavahiservicebrowserimplementation_p.cpp b/libnymea-core/hardware/network/avahi/qtavahiservicebrowserimplementation_p.cpp index 26614345..d35a6a6c 100644 --- a/libnymea-core/hardware/network/avahi/qtavahiservicebrowserimplementation_p.cpp +++ b/libnymea-core/hardware/network/avahi/qtavahiservicebrowserimplementation_p.cpp @@ -28,6 +28,8 @@ #include #include +#include + namespace nymeaserver { QtAvahiServiceBrowserImplementationPrivate::QtAvahiServiceBrowserImplementationPrivate(QtAvahiClient *client) : diff --git a/libnymea-core/jsonrpc/jsonrpcserver.cpp b/libnymea-core/jsonrpc/jsonrpcserver.cpp index a4e1d37e..09e499af 100644 --- a/libnymea-core/jsonrpc/jsonrpcserver.cpp +++ b/libnymea-core/jsonrpc/jsonrpcserver.cpp @@ -57,6 +57,7 @@ #include "configurationhandler.h" #include "networkmanagerhandler.h" #include "tagshandler.h" +#include "systemhandler.h" #include #include @@ -518,6 +519,7 @@ void JsonRPCServer::setup() registerHandler(new ConfigurationHandler(this)); registerHandler(new NetworkManagerHandler(this)); registerHandler(new TagsHandler(this)); + registerHandler(new SystemHandler(NymeaCore::instance()->system(), this)); connect(NymeaCore::instance()->cloudManager(), &CloudManager::pairingReply, this, &JsonRPCServer::pairingFinished); connect(NymeaCore::instance()->cloudManager(), &CloudManager::connectionStateChanged, this, &JsonRPCServer::onCloudConnectionStateChanged); diff --git a/libnymea-core/jsonrpc/systemhandler.cpp b/libnymea-core/jsonrpc/systemhandler.cpp new file mode 100644 index 00000000..a3e747c9 --- /dev/null +++ b/libnymea-core/jsonrpc/systemhandler.cpp @@ -0,0 +1,147 @@ +#include "systemhandler.h" + +#include "system/system.h" + +SystemHandler::SystemHandler(System *system, QObject *parent): + JsonHandler(parent), + m_system(system) +{ + // Methods + QVariantMap params; QVariantMap returns; + setDescription("GetCapabilities", "Get the list of capabilites on this system. This allows reading whether things like rebooting or shutting down the system running nymea:core is supported on this host."); + setParams("GetCapabilities", params); + returns.insert("powerManagement", JsonTypes::basicTypeToString(JsonTypes::Bool)); + returns.insert("updateManagement", JsonTypes::basicTypeToString(JsonTypes::Bool)); + setReturns("GetCapabilities", returns); + + params.clear(); returns.clear(); + setDescription("Reboot", "Initiate a reboot of the system. The return value will indicate whether the procedure has been initiated successfully."); + setParams("Reboot", params); + returns.insert("success", JsonTypes::basicTypeToString(JsonTypes::Bool)); + setReturns("Reboot", returns); + + params.clear(); returns.clear(); + setDescription("Shutdown", "Initiate a shutdown of the system. The return value will indicate whether the procedure has been initiated successfully."); + setParams("Shutdown", params); + returns.insert("success", JsonTypes::basicTypeToString(JsonTypes::Bool)); + setReturns("Shutdown", returns); + + params.clear(); returns.clear(); + setDescription("GetUpdateStatus", "Get the current system status in regard to updates. That is, the currently installed version, any candidate version available etc."); + setParams("GetUpdateStatus", params); + returns.insert("updateAvailable", JsonTypes::basicTypeToString(JsonTypes::Bool)); + returns.insert("currentVersion", JsonTypes::basicTypeToString(JsonTypes::String)); + returns.insert("candidateVersion", JsonTypes::basicTypeToString(JsonTypes::String)); + returns.insert("availableChannels", JsonTypes::basicTypeToString(JsonTypes::StringList)); + returns.insert("currentChannel", JsonTypes::basicTypeToString(JsonTypes::String)); + returns.insert("updateInProgress", JsonTypes::basicTypeToString(JsonTypes::Bool)); + setReturns("GetUpdateStatus", returns); + + params.clear(); returns.clear(); + setDescription("StartUpdate", "Starts a system update. Returns true if the upgrade has been started successfully."); + setParams("StartUpdate", params); + returns.insert("success", JsonTypes::basicTypeToString(JsonTypes::Bool)); + setReturns("StartUpdate", returns); + + params.clear(); returns.clear(); + setDescription("SelectChannel", "Select an update channel."); + params.insert("channel", JsonTypes::basicTypeToString(JsonTypes::String)); + setParams("SelectChannel", params); + returns.insert("success", JsonTypes::basicTypeToString(JsonTypes::Bool)); + setReturns("SelectChannel", returns); + + + // Notifications + params.clear(); + setDescription("UpdateStatusChanged", "Emitted whenever there is a change in the information from GetUpdateStatus"); + params.insert("updateAvailable", JsonTypes::basicTypeToString(JsonTypes::Bool)); + params.insert("currentVersion", JsonTypes::basicTypeToString(JsonTypes::String)); + params.insert("candidateVersion", JsonTypes::basicTypeToString(JsonTypes::String)); + params.insert("availableChannels", JsonTypes::basicTypeToString(JsonTypes::StringList)); + params.insert("currentChannel", JsonTypes::basicTypeToString(JsonTypes::String)); + params.insert("updateInProgress", JsonTypes::basicTypeToString(JsonTypes::Bool)); + setParams("UpdateStatusChanged", params); + + connect(m_system, &System::updateStatusChanged, this, &SystemHandler::onUpdateStatusChanged); +} + +QString SystemHandler::name() const +{ + return "System"; +} + +JsonReply *SystemHandler::GetCapabilities(const QVariantMap ¶ms) +{ + Q_UNUSED(params) + QVariantMap data; + data.insert("powerManagement", m_system->powerManagementAvailable()); + data.insert("updateManagement", m_system->updateManagementAvailable()); + return createReply(data); +} + +JsonReply *SystemHandler::Reboot(const QVariantMap ¶ms) const +{ + Q_UNUSED(params); + bool status = m_system->reboot(); + QVariantMap returns; + returns.insert("success", status); + return createReply(returns); +} + +JsonReply *SystemHandler::Shutdown(const QVariantMap ¶ms) const +{ + Q_UNUSED(params); + bool status = m_system->shutdown(); + QVariantMap returns; + returns.insert("success", status); + return createReply(returns); +} + +JsonReply *SystemHandler::GetUpdateStatus(const QVariantMap ¶ms) const +{ + Q_UNUSED(params); + QVariantMap returns; + returns.insert("updateAvailable", m_system->updateAvailable()); + returns.insert("currentVersion", m_system->currentVersion()); + returns.insert("candidateVersion", m_system->candidateVersion()); + returns.insert("availableChannels", m_system->availableChannels()); + returns.insert("currentChannel", m_system->currentChannel()); + returns.insert("updateInProgress", m_system->updateInProgress()); + return createReply(returns); +} + +JsonReply *SystemHandler::StartUpdate(const QVariantMap ¶ms) +{ + Q_UNUSED(params) + QVariantMap returns; + bool success = m_system->startUpdate(); + returns.insert("success", success); + return createReply(returns); +} + +JsonReply *SystemHandler::SelectChannel(const QVariantMap ¶ms) +{ + QString channel = params.value("channel").toString(); + + QVariantMap returns; + if (m_system->availableChannels().contains(channel)) { + bool success = m_system->selectChannel(channel); + returns.insert("success", success); + } else { + returns.insert("success", false); + } + return createReply(returns); +} + +void SystemHandler::onUpdateStatusChanged() +{ + QVariantMap params; + params.insert("updateAvailable", m_system->updateAvailable()); + params.insert("currentVersion", m_system->currentVersion()); + params.insert("candidateVersion", m_system->candidateVersion()); + params.insert("availableChannels", m_system->availableChannels()); + params.insert("currentChannel", m_system->currentChannel()); + params.insert("updateInProgress", m_system->updateInProgress()); + emit UpdateStatusChanged(params); + +} diff --git a/libnymea-core/jsonrpc/systemhandler.h b/libnymea-core/jsonrpc/systemhandler.h new file mode 100644 index 00000000..10ff913f --- /dev/null +++ b/libnymea-core/jsonrpc/systemhandler.h @@ -0,0 +1,60 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2019 Michael Zanetti * + * * + * This file is part of nymea. * + * * + * nymea is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, version 2 of the License. * + * * + * nymea is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with nymea. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef SYSTEMHANDLER_H +#define SYSTEMHANDLER_H + +#include + +#include "jsonhandler.h" + +namespace nymeaserver { + +class System; + +class SystemHandler : public JsonHandler +{ + Q_OBJECT +public: + explicit SystemHandler(System* system, QObject *parent = nullptr); + + QString name() const override; + + Q_INVOKABLE JsonReply *GetCapabilities(const QVariantMap ¶ms); + + Q_INVOKABLE JsonReply *Reboot(const QVariantMap ¶ms) const; + Q_INVOKABLE JsonReply *Shutdown(const QVariantMap ¶ms) const; + + Q_INVOKABLE JsonReply *GetUpdateStatus(const QVariantMap ¶ms) const; + Q_INVOKABLE JsonReply *StartUpdate(const QVariantMap ¶ms); + Q_INVOKABLE JsonReply *SelectChannel(const QVariantMap ¶ms); + +signals: + void UpdateStatusChanged(const QVariantMap ¶ms); + +private slots: + void onUpdateStatusChanged(); +private: + System *m_system = nullptr; +}; + +} + +#endif // SYSTEMHANDLER_H diff --git a/libnymea-core/libnymea-core.pro b/libnymea-core/libnymea-core.pro index b7a4adf1..11f686ff 100644 --- a/libnymea-core/libnymea-core.pro +++ b/libnymea-core/libnymea-core.pro @@ -99,7 +99,10 @@ HEADERS += nymeacore.h \ tagging/tag.h \ jsonrpc/tagshandler.h \ cloud/cloudtransport.h \ - debugreportgenerator.h + debugreportgenerator.h \ + platform/platform.h \ + system/system.h \ + jsonrpc/systemhandler.h SOURCES += nymeacore.cpp \ ruleengine.cpp \ @@ -184,3 +187,6 @@ SOURCES += nymeacore.cpp \ jsonrpc/tagshandler.cpp \ cloud/cloudtransport.cpp \ debugreportgenerator.cpp \ + platform/platform.cpp \ + system/system.cpp \ + jsonrpc/systemhandler.cpp diff --git a/libnymea-core/nymeacore.cpp b/libnymea-core/nymeacore.cpp index 149fd3c1..e213e4f8 100644 --- a/libnymea-core/nymeacore.cpp +++ b/libnymea-core/nymeacore.cpp @@ -106,11 +106,13 @@ #include "nymeacore.h" #include "loggingcategories.h" +#include "platform/platform.h" #include "jsonrpc/jsonrpcserver.h" #include "ruleengine.h" #include "networkmanager/networkmanager.h" #include "nymeasettings.h" #include "tagging/tagsstorage.h" +#include "system/system.h" #include "devicemanager.h" #include "plugin/device.h" @@ -143,12 +145,18 @@ NymeaCore::NymeaCore(QObject *parent) : void NymeaCore::init() { qCDebug(dcApplication()) << "Initializing NymeaCore"; + qCDebug(dcPlatform()) << "Loading platform abstraction"; + m_platform = new Platform(this); + qCDebug(dcApplication()) << "Loading nymea configurations" << NymeaSettings(NymeaSettings::SettingsRoleGlobal).fileName(); m_configuration = new NymeaConfiguration(this); qCDebug(dcApplication()) << "Creating Time Manager"; m_timeManager = new TimeManager(m_configuration->timeZone(), this); + qCDebug(dcApplication()) << "Loading System platform integration"; + m_system = new System(m_platform, this); + qCDebug(dcApplication) << "Creating Log Engine"; m_logger = new LogEngine(m_configuration->logDBDriver(), m_configuration->logDBName(), m_configuration->logDBHost(), m_configuration->logDBUser(), m_configuration->logDBPassword(), m_configuration->logDBMaxEntries(), this); @@ -660,6 +668,12 @@ TagsStorage *NymeaCore::tagsStorage() const return m_tagsStorage; } +/*! Returns a pointer to the \l{System} instance owned by NymeaCore. */ +System *NymeaCore::system() const +{ + return m_system; +} + /*! Connected to the DeviceManager's emitEvent signal. Events received in diff --git a/libnymea-core/nymeacore.h b/libnymea-core/nymeacore.h index 7911e5d9..835a645f 100644 --- a/libnymea-core/nymeacore.h +++ b/libnymea-core/nymeacore.h @@ -51,6 +51,8 @@ class NetworkManager; class NymeaConfiguration; class TagsStorage; class UserManager; +class Platform; +class System; class NymeaCore : public QObject { @@ -88,6 +90,7 @@ public: CloudManager *cloudManager() const; DebugServerHandler *debugServerHandler() const; TagsStorage *tagsStorage() const; + System *system() const; static QStringList getAvailableLanguages(); @@ -116,6 +119,8 @@ private: explicit NymeaCore(QObject *parent = nullptr); static NymeaCore *s_instance; + Platform *m_platform = nullptr; + NymeaConfiguration *m_configuration; ServerManager *m_serverManager; DeviceManager *m_deviceManager; @@ -129,6 +134,7 @@ private: NetworkManager *m_networkManager; UserManager *m_userManager; + System *m_system; QHash m_pendingActions; QList m_executingRules; diff --git a/libnymea-core/platform/platform.cpp b/libnymea-core/platform/platform.cpp new file mode 100644 index 00000000..dab21d53 --- /dev/null +++ b/libnymea-core/platform/platform.cpp @@ -0,0 +1,76 @@ +#include "platform.h" +#include "plugin/platformplugin.h" + +#include "loggingcategories.h" + +#include +#include +#include + +namespace nymeaserver { + +Platform::Platform(QObject *parent) : QObject(parent) +{ + foreach (const QString &path, pluginSearchDirs()) { + QDir dir(path); + qCDebug(dcPlatform) << "Loading plugins from:" << dir.absolutePath(); + foreach (const QString &entry, dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot)) { + qCDebug(dcPlatform()) << "Found dir entry" << entry; + QFileInfo fi; + if (entry.startsWith("libnymea_systemplugin") && entry.endsWith(".so")) { + fi.setFile(path + "/" + entry); + } else { + fi.setFile(path + "/" + entry + "/libnymea_platformplugin" + entry + ".so"); + } + + if (!fi.exists()) + continue; + + + QPluginLoader loader; + loader.setFileName(fi.absoluteFilePath()); + loader.setLoadHints(QLibrary::ResolveAllSymbolsHint); + + if (!loader.load()) { + qCWarning(dcPlatform) << "Could not load plugin data of" << entry << "\n" << loader.errorString(); + continue; + } + + m_platformPlugin = qobject_cast(loader.instance()); + if (!m_platformPlugin) { + qCWarning(dcPlatform) << "Could not get plugin instance of" << entry; + continue; + } + qCDebug(dcPlatform()) << "Loaded platform plugin:" << entry; + m_platformPlugin->setParent(this); + break; + } + if (m_platformPlugin) { + break; + } + } + if (!m_platformPlugin) { + qCWarning(dcPlatform()) << "Could not load a platform plugin. Platform related features won't be available."; + } + +} + +PlatformSystemController *Platform::systemController() const +{ + return m_platformPlugin->systemController(); +} + +PlatformUpdateController *Platform::updateController() const +{ + return m_platformPlugin->updateController(); +} + +QStringList Platform::pluginSearchDirs() const +{ + QStringList ret; + ret << QString(qgetenv("NYMEA_PLATFORM_PLUGINS_PATH")).split(':'); + ret << QCoreApplication::applicationDirPath(); + return ret; +} + +} diff --git a/libnymea-core/platform/platform.h b/libnymea-core/platform/platform.h new file mode 100644 index 00000000..b034411b --- /dev/null +++ b/libnymea-core/platform/platform.h @@ -0,0 +1,30 @@ +#ifndef PLATFORM_H +#define PLATFORM_H + +#include + +class PlatformPlugin; +class PlatformSystemController; +class PlatformUpdateController; + +namespace nymeaserver { + +class Platform : public QObject +{ + Q_OBJECT +public: + explicit Platform(QObject *parent = nullptr); + + PlatformSystemController *systemController() const; + PlatformUpdateController *updateController() const; + +private: + QStringList pluginSearchDirs() const; + +private: + PlatformPlugin *m_platformPlugin = nullptr; +}; + +} + +#endif // PLATFORM_H diff --git a/libnymea-core/system/system.cpp b/libnymea-core/system/system.cpp new file mode 100644 index 00000000..46dcd599 --- /dev/null +++ b/libnymea-core/system/system.cpp @@ -0,0 +1,88 @@ +#include "system.h" + +#include "loggingcategories.h" +#include "platform/platform.h" +#include "plugin/platformsystemcontroller.h" +#include "plugin/platformupdatecontroller.h" + +namespace nymeaserver { + + +System::System(Platform *platform, QObject *parent): + QObject(parent), + m_platform(platform) +{ + connect(m_platform->updateController(), &PlatformUpdateController::updateStatusChanged, this, &System::updateStatusChanged); +} + +bool System::powerManagementAvailable() const +{ + return m_platform->systemController()->capabilities().testFlag(PlatformSystemController::CapabilityPower); +} + +bool System::reboot() +{ + return m_platform->systemController()->reboot(); +} + +bool System::shutdown() +{ + return m_platform->systemController()->shutdown(); +} + +bool System::updateManagementAvailable() const +{ + return m_platform->updateController()->updateManagementAvailable(); +} + +bool System::updateAvailable() const +{ + return m_platform->updateController()->updateAvailable(); +} + +QString System::currentVersion() const +{ + return m_platform->updateController()->currentVersion(); +} + +QString System::candidateVersion() const +{ + return m_platform->updateController()->candidateVersion(); +} + +QStringList System::availableChannels() const +{ + return m_platform->updateController()->channels(); +} + +QString System::currentChannel() const +{ + return m_platform->updateController()->currentChannel(); +} + +bool System::selectChannel(const QString &channel) const +{ + return m_platform->updateController()->selectChannel(channel); +} + +bool System::canUpdate() const +{ + return m_platform->updateController() ; +} + +bool System::startUpdate() +{ + return m_platform->updateController()->startUpdate(); +} + +bool System::updateInProgress() const +{ + return m_platform->updateController()->updateInProgress(); +} + +bool System::rollbackAvailable() const +{ + return m_platform->updateController()->rollbackAvailable(); +} + +} diff --git a/libnymea-core/system/system.h b/libnymea-core/system/system.h new file mode 100644 index 00000000..d3bec8fb --- /dev/null +++ b/libnymea-core/system/system.h @@ -0,0 +1,45 @@ +#ifndef SYSTEM_H +#define SYSTEM_H + +#include + + +namespace nymeaserver { + +class Platform; + +class System : public QObject +{ + Q_OBJECT + +public: + explicit System(Platform *platform, QObject *parent = nullptr); + + bool powerManagementAvailable() const; + bool reboot(); + bool shutdown(); + + bool updateManagementAvailable() const; + bool updateAvailable() const; + QString currentVersion() const; + QString candidateVersion() const; + QStringList availableChannels() const; + QString currentChannel() const; + bool selectChannel(const QString &channel) const; + bool canUpdate() const; + bool startUpdate(); + bool updateInProgress() const; + + bool rollbackAvailable() const; + bool startRollback(); + +signals: + void updateStatusChanged(); + +private: + Platform *m_platform = nullptr; +}; + +} + +#endif // SYSTEM_H diff --git a/libnymea/coap/coap.h b/libnymea/coap/coap.h index 568b1030..cea66042 100644 --- a/libnymea/coap/coap.h +++ b/libnymea/coap/coap.h @@ -43,8 +43,6 @@ * */ -Q_DECLARE_LOGGING_CATEGORY(dcCoap) - class LIBNYMEA_EXPORT Coap : public QObject { Q_OBJECT diff --git a/libnymea/libnymea.pro b/libnymea/libnymea.pro index d5401e59..964940e3 100644 --- a/libnymea/libnymea.pro +++ b/libnymea/libnymea.pro @@ -65,7 +65,10 @@ HEADERS += devicemanager.h \ nymeadbusservice.h \ network/mqtt/mqttprovider.h \ network/mqtt/mqttchannel.h \ - translator.h + translator.h \ + plugin/platformplugin.h \ + plugin/platformsystemcontroller.h \ + plugin/platformupdatecontroller.h SOURCES += devicemanager.cpp \ loggingcategories.cpp \ @@ -120,7 +123,10 @@ SOURCES += devicemanager.cpp \ nymeadbusservice.cpp \ network/mqtt/mqttprovider.cpp \ network/mqtt/mqttchannel.cpp \ - translator.cpp + translator.cpp \ + plugin/platformplugin.cpp \ + plugin/platformsystemcontroller.cpp \ + plugin/platformupdatecontroller.cpp RESOURCES += \ diff --git a/libnymea/loggingcategories.cpp b/libnymea/loggingcategories.cpp index 80208bec..019efb0e 100644 --- a/libnymea/loggingcategories.cpp +++ b/libnymea/loggingcategories.cpp @@ -24,6 +24,8 @@ Q_LOGGING_CATEGORY(dcApplication, "Application") Q_LOGGING_CATEGORY(dcDeviceManager, "DeviceManager") +Q_LOGGING_CATEGORY(dcSystem, "System") +Q_LOGGING_CATEGORY(dcPlatform, "Platform") Q_LOGGING_CATEGORY(dcTimeManager, "TimeManager") Q_LOGGING_CATEGORY(dcRuleEngine, "RuleEngine") Q_LOGGING_CATEGORY(dcRuleEngineDebug, "RuleEngineDebug") diff --git a/libnymea/loggingcategories.h b/libnymea/loggingcategories.h index 6c5f4c43..dd32e1ea 100644 --- a/libnymea/loggingcategories.h +++ b/libnymea/loggingcategories.h @@ -26,12 +26,11 @@ #include #include -// Include dcCoap -#include "coap/coap.h" - // Core / libnymea Q_DECLARE_LOGGING_CATEGORY(dcApplication) Q_DECLARE_LOGGING_CATEGORY(dcDeviceManager) +Q_DECLARE_LOGGING_CATEGORY(dcSystem) +Q_DECLARE_LOGGING_CATEGORY(dcPlatform) Q_DECLARE_LOGGING_CATEGORY(dcTimeManager) Q_DECLARE_LOGGING_CATEGORY(dcRuleEngine) Q_DECLARE_LOGGING_CATEGORY(dcRuleEngineDebug) @@ -63,5 +62,6 @@ Q_DECLARE_LOGGING_CATEGORY(dcBluetoothServer) Q_DECLARE_LOGGING_CATEGORY(dcBluetoothServerTraffic) Q_DECLARE_LOGGING_CATEGORY(dcMqtt) Q_DECLARE_LOGGING_CATEGORY(dcTranslations) +Q_DECLARE_LOGGING_CATEGORY(dcCoap) #endif // LOGGINGCATEGORYS_H diff --git a/libnymea/plugin/platformplugin.cpp b/libnymea/plugin/platformplugin.cpp new file mode 100644 index 00000000..6fa6d816 --- /dev/null +++ b/libnymea/plugin/platformplugin.cpp @@ -0,0 +1,6 @@ +#include "platformplugin.h" + +PlatformPlugin::PlatformPlugin(QObject *parent) : QObject(parent) +{ + +} diff --git a/libnymea/plugin/platformplugin.h b/libnymea/plugin/platformplugin.h new file mode 100644 index 00000000..52228241 --- /dev/null +++ b/libnymea/plugin/platformplugin.h @@ -0,0 +1,24 @@ +#ifndef PLATFORMPLUGIN_H +#define PLATFORMPLUGIN_H + +#include + +#include "libnymea.h" + +class PlatformSystemController; +class PlatformUpdateController; + +class LIBNYMEA_EXPORT PlatformPlugin: public QObject +{ + Q_OBJECT +public: + explicit PlatformPlugin(QObject *parent = nullptr); + virtual ~PlatformPlugin() = default; + + virtual PlatformSystemController *systemController() const = 0; + virtual PlatformUpdateController *updateController() const = 0; +}; + +Q_DECLARE_INTERFACE(PlatformPlugin, "io.nymea.PlatformPlugin") + +#endif // PLATFORMPLUGIN_H diff --git a/libnymea/plugin/platformsystemcontroller.cpp b/libnymea/plugin/platformsystemcontroller.cpp new file mode 100644 index 00000000..a1d7dd6b --- /dev/null +++ b/libnymea/plugin/platformsystemcontroller.cpp @@ -0,0 +1,6 @@ +#include "platformsystemcontroller.h" + +PlatformSystemController::PlatformSystemController(QObject *parent) : QObject(parent) +{ + +} diff --git a/libnymea/plugin/platformsystemcontroller.h b/libnymea/plugin/platformsystemcontroller.h new file mode 100644 index 00000000..36af00f1 --- /dev/null +++ b/libnymea/plugin/platformsystemcontroller.h @@ -0,0 +1,26 @@ +#ifndef PLATFORMSYSTEMCONTROLLER_H +#define PLATFORMSYSTEMCONTROLLER_H + +#include + +class PlatformSystemController : public QObject +{ + Q_OBJECT +public: + enum Capability { + CapabilityNone = 0x00, + CapabilityPower = 0x01, + CapabilityAll = 0xFF + }; + Q_ENUM(Capability) + Q_DECLARE_FLAGS(Capabilities, Capability) + + explicit PlatformSystemController(QObject *parent = nullptr); + virtual ~PlatformSystemController() = default; + + virtual Capabilities capabilities() const = 0; + virtual bool reboot() = 0; + virtual bool shutdown() = 0; +}; + +#endif // PLATFORMSYSTEMCONTROLLER_H diff --git a/libnymea/plugin/platformupdatecontroller.cpp b/libnymea/plugin/platformupdatecontroller.cpp new file mode 100644 index 00000000..7464a4d8 --- /dev/null +++ b/libnymea/plugin/platformupdatecontroller.cpp @@ -0,0 +1,15 @@ +#include "platformupdatecontroller.h" + +PlatformUpdateController::PlatformUpdateController(QObject *parent) : QObject(parent) +{ + +} + +/*! Override this to indicate whether update management is available. Defaults to false. + When a plugin returns true here, it is assumed that the system is capable of updating and nymea + has permissions to do so. + */ +bool PlatformUpdateController::updateManagementAvailable() +{ + return false; +} diff --git a/libnymea/plugin/platformupdatecontroller.h b/libnymea/plugin/platformupdatecontroller.h new file mode 100644 index 00000000..743d8212 --- /dev/null +++ b/libnymea/plugin/platformupdatecontroller.h @@ -0,0 +1,37 @@ +#ifndef PLATFORMUPDATECONTROLLER_H +#define PLATFORMUPDATECONTROLLER_H + +#include + +class PlatformUpdateController : public QObject +{ + Q_OBJECT +public: + explicit PlatformUpdateController(QObject *parent = nullptr); + virtual ~PlatformUpdateController() = default; + + virtual bool updateManagementAvailable(); + + virtual QString currentVersion() const = 0; + virtual QString candidateVersion() const = 0; + +// virtual QMap changelog() const = 0; + + virtual void checkForUpdates() = 0; + virtual bool updateAvailable() const = 0; + virtual bool startUpdate() = 0; + + virtual bool rollbackAvailable() const = 0; + virtual bool startRollback() = 0; + + virtual bool updateInProgress() const = 0; + + virtual QStringList channels() const = 0; + virtual QString currentChannel() const = 0; + virtual bool selectChannel(const QString &channel) = 0; + +signals: + void updateStatusChanged(); +}; + +#endif // PLATFORMUPDATECONTROLLER_H diff --git a/server/main.cpp b/server/main.cpp index f333cd63..5e68ac92 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -99,8 +99,10 @@ int main(int argc, char *argv[]) // logging filers for core and libnymea QStringList loggingFilters = { - "Application", "Warnings", + "Application", + "System", + "Platform", "DeviceManager", "RuleEngine", "RuleEngineDebug", From 02b97a686e54ca99146e799f4ee1407547550891 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Fri, 10 May 2019 01:31:26 +0200 Subject: [PATCH 02/17] Simplify it a bit --- libnymea-core/jsonrpc/jsonrpcserver.cpp | 3 +- libnymea-core/jsonrpc/systemhandler.cpp | 49 ++++++----- libnymea-core/jsonrpc/systemhandler.h | 8 +- libnymea-core/libnymea-core.pro | 2 - libnymea-core/nymeacore.cpp | 14 ++- libnymea-core/nymeacore.h | 2 +- libnymea-core/platform/platform.cpp | 3 +- libnymea-core/system/system.cpp | 88 ------------------- libnymea-core/system/system.h | 45 ---------- libnymea/libnymea.pro | 12 +-- libnymea/platform/platformplugin.cpp | 16 ++++ .../{plugin => platform}/platformplugin.h | 8 +- .../platform/platformsystemcontroller.cpp | 21 +++++ .../platformsystemcontroller.h | 14 +-- .../platform/platformupdatecontroller.cpp | 71 +++++++++++++++ libnymea/platform/platformupdatecontroller.h | 37 ++++++++ libnymea/plugin/platformplugin.cpp | 6 -- libnymea/plugin/platformsystemcontroller.cpp | 6 -- libnymea/plugin/platformupdatecontroller.cpp | 15 ---- libnymea/plugin/platformupdatecontroller.h | 37 -------- 20 files changed, 200 insertions(+), 257 deletions(-) delete mode 100644 libnymea-core/system/system.cpp delete mode 100644 libnymea-core/system/system.h create mode 100644 libnymea/platform/platformplugin.cpp rename libnymea/{plugin => platform}/platformplugin.h (63%) create mode 100644 libnymea/platform/platformsystemcontroller.cpp rename libnymea/{plugin => platform}/platformsystemcontroller.h (51%) create mode 100644 libnymea/platform/platformupdatecontroller.cpp create mode 100644 libnymea/platform/platformupdatecontroller.h delete mode 100644 libnymea/plugin/platformplugin.cpp delete mode 100644 libnymea/plugin/platformsystemcontroller.cpp delete mode 100644 libnymea/plugin/platformupdatecontroller.cpp delete mode 100644 libnymea/plugin/platformupdatecontroller.h diff --git a/libnymea-core/jsonrpc/jsonrpcserver.cpp b/libnymea-core/jsonrpc/jsonrpcserver.cpp index 09e499af..5745e27b 100644 --- a/libnymea-core/jsonrpc/jsonrpcserver.cpp +++ b/libnymea-core/jsonrpc/jsonrpcserver.cpp @@ -47,6 +47,7 @@ #include "rule.h" #include "ruleengine.h" #include "loggingcategories.h" +#include "platform/platform.h" #include "devicehandler.h" #include "actionhandler.h" @@ -519,7 +520,7 @@ void JsonRPCServer::setup() registerHandler(new ConfigurationHandler(this)); registerHandler(new NetworkManagerHandler(this)); registerHandler(new TagsHandler(this)); - registerHandler(new SystemHandler(NymeaCore::instance()->system(), this)); + registerHandler(new SystemHandler(NymeaCore::instance()->platform(), this)); connect(NymeaCore::instance()->cloudManager(), &CloudManager::pairingReply, this, &JsonRPCServer::pairingFinished); connect(NymeaCore::instance()->cloudManager(), &CloudManager::connectionStateChanged, this, &JsonRPCServer::onCloudConnectionStateChanged); diff --git a/libnymea-core/jsonrpc/systemhandler.cpp b/libnymea-core/jsonrpc/systemhandler.cpp index a3e747c9..d222fd2f 100644 --- a/libnymea-core/jsonrpc/systemhandler.cpp +++ b/libnymea-core/jsonrpc/systemhandler.cpp @@ -1,10 +1,12 @@ #include "systemhandler.h" -#include "system/system.h" +#include "platform/platform.h" +#include "platform/platformupdatecontroller.h" +#include "platform/platformsystemcontroller.h" -SystemHandler::SystemHandler(System *system, QObject *parent): +SystemHandler::SystemHandler(Platform *platform, QObject *parent): JsonHandler(parent), - m_system(system) + m_platform(platform) { // Methods QVariantMap params; QVariantMap returns; @@ -62,7 +64,7 @@ SystemHandler::SystemHandler(System *system, QObject *parent): params.insert("updateInProgress", JsonTypes::basicTypeToString(JsonTypes::Bool)); setParams("UpdateStatusChanged", params); - connect(m_system, &System::updateStatusChanged, this, &SystemHandler::onUpdateStatusChanged); + connect(m_platform->updateController(), &PlatformUpdateController::updateStatusChanged, this, &SystemHandler::onUpdateStatusChanged); } QString SystemHandler::name() const @@ -74,15 +76,15 @@ JsonReply *SystemHandler::GetCapabilities(const QVariantMap ¶ms) { Q_UNUSED(params) QVariantMap data; - data.insert("powerManagement", m_system->powerManagementAvailable()); - data.insert("updateManagement", m_system->updateManagementAvailable()); + data.insert("powerManagement", m_platform->systemController()->powerManagementAvailable()); + data.insert("updateManagement", m_platform->updateController()->updateManagementAvailable()); return createReply(data); } JsonReply *SystemHandler::Reboot(const QVariantMap ¶ms) const { Q_UNUSED(params); - bool status = m_system->reboot(); + bool status = m_platform->systemController()->reboot(); QVariantMap returns; returns.insert("success", status); return createReply(returns); @@ -91,7 +93,7 @@ JsonReply *SystemHandler::Reboot(const QVariantMap ¶ms) const JsonReply *SystemHandler::Shutdown(const QVariantMap ¶ms) const { Q_UNUSED(params); - bool status = m_system->shutdown(); + bool status = m_platform->systemController()->shutdown(); QVariantMap returns; returns.insert("success", status); return createReply(returns); @@ -101,12 +103,12 @@ JsonReply *SystemHandler::GetUpdateStatus(const QVariantMap ¶ms) const { Q_UNUSED(params); QVariantMap returns; - returns.insert("updateAvailable", m_system->updateAvailable()); - returns.insert("currentVersion", m_system->currentVersion()); - returns.insert("candidateVersion", m_system->candidateVersion()); - returns.insert("availableChannels", m_system->availableChannels()); - returns.insert("currentChannel", m_system->currentChannel()); - returns.insert("updateInProgress", m_system->updateInProgress()); + returns.insert("updateAvailable", m_platform->updateController()->updateAvailable()); + returns.insert("currentVersion", m_platform->updateController()->currentVersion()); + returns.insert("candidateVersion", m_platform->updateController()->candidateVersion()); + returns.insert("availableChannels", m_platform->updateController()->availableChannels()); + returns.insert("currentChannel", m_platform->updateController()->currentChannel()); + returns.insert("updateInProgress", m_platform->updateController()->updateInProgress()); return createReply(returns); } @@ -114,7 +116,7 @@ JsonReply *SystemHandler::StartUpdate(const QVariantMap ¶ms) { Q_UNUSED(params) QVariantMap returns; - bool success = m_system->startUpdate(); + bool success = m_platform->updateController()->startUpdate(); returns.insert("success", success); return createReply(returns); } @@ -124,8 +126,8 @@ JsonReply *SystemHandler::SelectChannel(const QVariantMap ¶ms) QString channel = params.value("channel").toString(); QVariantMap returns; - if (m_system->availableChannels().contains(channel)) { - bool success = m_system->selectChannel(channel); + if (m_platform->updateController()->availableChannels().contains(channel)) { + bool success = m_platform->updateController()->selectChannel(channel); returns.insert("success", success); } else { returns.insert("success", false); @@ -136,12 +138,11 @@ JsonReply *SystemHandler::SelectChannel(const QVariantMap ¶ms) void SystemHandler::onUpdateStatusChanged() { QVariantMap params; - params.insert("updateAvailable", m_system->updateAvailable()); - params.insert("currentVersion", m_system->currentVersion()); - params.insert("candidateVersion", m_system->candidateVersion()); - params.insert("availableChannels", m_system->availableChannels()); - params.insert("currentChannel", m_system->currentChannel()); - params.insert("updateInProgress", m_system->updateInProgress()); + params.insert("updateAvailable", m_platform->updateController()->updateAvailable()); + params.insert("currentVersion", m_platform->updateController()->currentVersion()); + params.insert("candidateVersion", m_platform->updateController()->candidateVersion()); + params.insert("availableChannels", m_platform->updateController()->availableChannels()); + params.insert("currentChannel", m_platform->updateController()->currentChannel()); + params.insert("updateInProgress", m_platform->updateController()->updateInProgress()); emit UpdateStatusChanged(params); - } diff --git a/libnymea-core/jsonrpc/systemhandler.h b/libnymea-core/jsonrpc/systemhandler.h index 10ff913f..27c9fd93 100644 --- a/libnymea-core/jsonrpc/systemhandler.h +++ b/libnymea-core/jsonrpc/systemhandler.h @@ -25,15 +25,15 @@ #include "jsonhandler.h" -namespace nymeaserver { +#include "platform/platform.h" -class System; +namespace nymeaserver { class SystemHandler : public JsonHandler { Q_OBJECT public: - explicit SystemHandler(System* system, QObject *parent = nullptr); + explicit SystemHandler(Platform *platform, QObject *parent = nullptr); QString name() const override; @@ -52,7 +52,7 @@ signals: private slots: void onUpdateStatusChanged(); private: - System *m_system = nullptr; + Platform *m_platform = nullptr; }; } diff --git a/libnymea-core/libnymea-core.pro b/libnymea-core/libnymea-core.pro index 11f686ff..b66bc2c6 100644 --- a/libnymea-core/libnymea-core.pro +++ b/libnymea-core/libnymea-core.pro @@ -101,7 +101,6 @@ HEADERS += nymeacore.h \ cloud/cloudtransport.h \ debugreportgenerator.h \ platform/platform.h \ - system/system.h \ jsonrpc/systemhandler.h SOURCES += nymeacore.cpp \ @@ -188,5 +187,4 @@ SOURCES += nymeacore.cpp \ cloud/cloudtransport.cpp \ debugreportgenerator.cpp \ platform/platform.cpp \ - system/system.cpp \ jsonrpc/systemhandler.cpp diff --git a/libnymea-core/nymeacore.cpp b/libnymea-core/nymeacore.cpp index e213e4f8..e7d8ee2f 100644 --- a/libnymea-core/nymeacore.cpp +++ b/libnymea-core/nymeacore.cpp @@ -112,7 +112,7 @@ #include "networkmanager/networkmanager.h" #include "nymeasettings.h" #include "tagging/tagsstorage.h" -#include "system/system.h" +#include "platform/platform.h" #include "devicemanager.h" #include "plugin/device.h" @@ -154,9 +154,6 @@ void NymeaCore::init() { qCDebug(dcApplication()) << "Creating Time Manager"; m_timeManager = new TimeManager(m_configuration->timeZone(), this); - qCDebug(dcApplication()) << "Loading System platform integration"; - m_system = new System(m_platform, this); - qCDebug(dcApplication) << "Creating Log Engine"; m_logger = new LogEngine(m_configuration->logDBDriver(), m_configuration->logDBName(), m_configuration->logDBHost(), m_configuration->logDBUser(), m_configuration->logDBPassword(), m_configuration->logDBMaxEntries(), this); @@ -668,14 +665,15 @@ TagsStorage *NymeaCore::tagsStorage() const return m_tagsStorage; } -/*! Returns a pointer to the \l{System} instance owned by NymeaCore. */ -System *NymeaCore::system() const +/*! Returns a pointer to the \l{Platform} instance owned by NymeaCore. + The Platform represents the host system this nymea instance is running on. +*/ +Platform *NymeaCore::platform() const { - return m_system; + return m_platform; } - /*! Connected to the DeviceManager's emitEvent signal. Events received in here will be evaluated by the \l{RuleEngine} and the according \l{RuleAction}{RuleActions} are executed.*/ void NymeaCore::gotEvent(const Event &event) diff --git a/libnymea-core/nymeacore.h b/libnymea-core/nymeacore.h index 835a645f..4c1be9ec 100644 --- a/libnymea-core/nymeacore.h +++ b/libnymea-core/nymeacore.h @@ -90,7 +90,7 @@ public: CloudManager *cloudManager() const; DebugServerHandler *debugServerHandler() const; TagsStorage *tagsStorage() const; - System *system() const; + Platform *platform() const; static QStringList getAvailableLanguages(); diff --git a/libnymea-core/platform/platform.cpp b/libnymea-core/platform/platform.cpp index dab21d53..56750c20 100644 --- a/libnymea-core/platform/platform.cpp +++ b/libnymea-core/platform/platform.cpp @@ -1,5 +1,5 @@ #include "platform.h" -#include "plugin/platformplugin.h" +#include "platform/platformplugin.h" #include "loggingcategories.h" @@ -51,6 +51,7 @@ Platform::Platform(QObject *parent) : QObject(parent) } if (!m_platformPlugin) { qCWarning(dcPlatform()) << "Could not load a platform plugin. Platform related features won't be available."; + m_platformPlugin = new PlatformPlugin(this); } } diff --git a/libnymea-core/system/system.cpp b/libnymea-core/system/system.cpp deleted file mode 100644 index 46dcd599..00000000 --- a/libnymea-core/system/system.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "system.h" - -#include "loggingcategories.h" -#include "platform/platform.h" -#include "plugin/platformsystemcontroller.h" -#include "plugin/platformupdatecontroller.h" - -namespace nymeaserver { - - -System::System(Platform *platform, QObject *parent): - QObject(parent), - m_platform(platform) -{ - connect(m_platform->updateController(), &PlatformUpdateController::updateStatusChanged, this, &System::updateStatusChanged); -} - -bool System::powerManagementAvailable() const -{ - return m_platform->systemController()->capabilities().testFlag(PlatformSystemController::CapabilityPower); -} - -bool System::reboot() -{ - return m_platform->systemController()->reboot(); -} - -bool System::shutdown() -{ - return m_platform->systemController()->shutdown(); -} - -bool System::updateManagementAvailable() const -{ - return m_platform->updateController()->updateManagementAvailable(); -} - -bool System::updateAvailable() const -{ - return m_platform->updateController()->updateAvailable(); -} - -QString System::currentVersion() const -{ - return m_platform->updateController()->currentVersion(); -} - -QString System::candidateVersion() const -{ - return m_platform->updateController()->candidateVersion(); -} - -QStringList System::availableChannels() const -{ - return m_platform->updateController()->channels(); -} - -QString System::currentChannel() const -{ - return m_platform->updateController()->currentChannel(); -} - -bool System::selectChannel(const QString &channel) const -{ - return m_platform->updateController()->selectChannel(channel); -} - -bool System::canUpdate() const -{ - return m_platform->updateController() ; -} - -bool System::startUpdate() -{ - return m_platform->updateController()->startUpdate(); -} - -bool System::updateInProgress() const -{ - return m_platform->updateController()->updateInProgress(); -} - -bool System::rollbackAvailable() const -{ - return m_platform->updateController()->rollbackAvailable(); -} - -} diff --git a/libnymea-core/system/system.h b/libnymea-core/system/system.h deleted file mode 100644 index d3bec8fb..00000000 --- a/libnymea-core/system/system.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef SYSTEM_H -#define SYSTEM_H - -#include - - -namespace nymeaserver { - -class Platform; - -class System : public QObject -{ - Q_OBJECT - -public: - explicit System(Platform *platform, QObject *parent = nullptr); - - bool powerManagementAvailable() const; - bool reboot(); - bool shutdown(); - - bool updateManagementAvailable() const; - bool updateAvailable() const; - QString currentVersion() const; - QString candidateVersion() const; - QStringList availableChannels() const; - QString currentChannel() const; - bool selectChannel(const QString &channel) const; - bool canUpdate() const; - bool startUpdate(); - bool updateInProgress() const; - - bool rollbackAvailable() const; - bool startRollback(); - -signals: - void updateStatusChanged(); - -private: - Platform *m_platform = nullptr; -}; - -} - -#endif // SYSTEM_H diff --git a/libnymea/libnymea.pro b/libnymea/libnymea.pro index 964940e3..97b7d889 100644 --- a/libnymea/libnymea.pro +++ b/libnymea/libnymea.pro @@ -66,9 +66,9 @@ HEADERS += devicemanager.h \ network/mqtt/mqttprovider.h \ network/mqtt/mqttchannel.h \ translator.h \ - plugin/platformplugin.h \ - plugin/platformsystemcontroller.h \ - plugin/platformupdatecontroller.h + platform/platformplugin.h \ + platform/platformsystemcontroller.h \ + platform/platformupdatecontroller.h SOURCES += devicemanager.cpp \ loggingcategories.cpp \ @@ -124,9 +124,9 @@ SOURCES += devicemanager.cpp \ network/mqtt/mqttprovider.cpp \ network/mqtt/mqttchannel.cpp \ translator.cpp \ - plugin/platformplugin.cpp \ - plugin/platformsystemcontroller.cpp \ - plugin/platformupdatecontroller.cpp + platform/platformplugin.cpp \ + platform/platformsystemcontroller.cpp \ + platform/platformupdatecontroller.cpp RESOURCES += \ diff --git a/libnymea/platform/platformplugin.cpp b/libnymea/platform/platformplugin.cpp new file mode 100644 index 00000000..d07ef052 --- /dev/null +++ b/libnymea/platform/platformplugin.cpp @@ -0,0 +1,16 @@ +#include "platformplugin.h" + +PlatformPlugin::PlatformPlugin(QObject *parent) : QObject(parent) +{ + +} + +PlatformSystemController *PlatformPlugin::systemController() const +{ + return m_systemStub; +} + +PlatformUpdateController *PlatformPlugin::updateController() const +{ + return m_updateStub; +} diff --git a/libnymea/plugin/platformplugin.h b/libnymea/platform/platformplugin.h similarity index 63% rename from libnymea/plugin/platformplugin.h rename to libnymea/platform/platformplugin.h index 52228241..177440d2 100644 --- a/libnymea/plugin/platformplugin.h +++ b/libnymea/platform/platformplugin.h @@ -15,8 +15,12 @@ public: explicit PlatformPlugin(QObject *parent = nullptr); virtual ~PlatformPlugin() = default; - virtual PlatformSystemController *systemController() const = 0; - virtual PlatformUpdateController *updateController() const = 0; + virtual PlatformSystemController *systemController() const; + virtual PlatformUpdateController *updateController() const; + +private: + PlatformSystemController *m_systemStub = nullptr; + PlatformUpdateController *m_updateStub = nullptr; }; Q_DECLARE_INTERFACE(PlatformPlugin, "io.nymea.PlatformPlugin") diff --git a/libnymea/platform/platformsystemcontroller.cpp b/libnymea/platform/platformsystemcontroller.cpp new file mode 100644 index 00000000..1034844a --- /dev/null +++ b/libnymea/platform/platformsystemcontroller.cpp @@ -0,0 +1,21 @@ +#include "platformsystemcontroller.h" + +PlatformSystemController::PlatformSystemController(QObject *parent) : QObject(parent) +{ + +} + +bool PlatformSystemController::powerManagementAvailable() const +{ + return false; +} + +bool PlatformSystemController::reboot() +{ + return false; +} + +bool PlatformSystemController::shutdown() +{ + return false; +} diff --git a/libnymea/plugin/platformsystemcontroller.h b/libnymea/platform/platformsystemcontroller.h similarity index 51% rename from libnymea/plugin/platformsystemcontroller.h rename to libnymea/platform/platformsystemcontroller.h index 36af00f1..2a56738b 100644 --- a/libnymea/plugin/platformsystemcontroller.h +++ b/libnymea/platform/platformsystemcontroller.h @@ -7,20 +7,12 @@ class PlatformSystemController : public QObject { Q_OBJECT public: - enum Capability { - CapabilityNone = 0x00, - CapabilityPower = 0x01, - CapabilityAll = 0xFF - }; - Q_ENUM(Capability) - Q_DECLARE_FLAGS(Capabilities, Capability) - explicit PlatformSystemController(QObject *parent = nullptr); virtual ~PlatformSystemController() = default; - virtual Capabilities capabilities() const = 0; - virtual bool reboot() = 0; - virtual bool shutdown() = 0; + virtual bool powerManagementAvailable() const; + virtual bool reboot(); + virtual bool shutdown(); }; #endif // PLATFORMSYSTEMCONTROLLER_H diff --git a/libnymea/platform/platformupdatecontroller.cpp b/libnymea/platform/platformupdatecontroller.cpp new file mode 100644 index 00000000..33a292bf --- /dev/null +++ b/libnymea/platform/platformupdatecontroller.cpp @@ -0,0 +1,71 @@ +#include "platformupdatecontroller.h" + +PlatformUpdateController::PlatformUpdateController(QObject *parent) : QObject(parent) +{ + +} + +/*! Override this to indicate whether update management is available. Defaults to false. + When a plugin returns true here, it is assumed that the system is capable of updating and nymea + has permissions to do so. + */ +bool PlatformUpdateController::updateManagementAvailable() +{ + return false; +} + +QString PlatformUpdateController::currentVersion() const +{ + return tr("N/A"); +} + +QString PlatformUpdateController::candidateVersion() const +{ + return tr("N/A"); +} + +void PlatformUpdateController::checkForUpdates() +{ + // Nothing to do here +} + +bool PlatformUpdateController::updateAvailable() const +{ + return false; +} + +bool PlatformUpdateController::startUpdate() +{ + return false; +} + +bool PlatformUpdateController::rollbackAvailable() const +{ + return false; +} + +bool PlatformUpdateController::startRollback() +{ + return false; +} + +bool PlatformUpdateController::updateInProgress() const +{ + return false; +} + +QStringList PlatformUpdateController::availableChannels() const +{ + return {}; +} + +QString PlatformUpdateController::currentChannel() const +{ + return tr("N/A"); +} + +bool PlatformUpdateController::selectChannel(const QString &channel) +{ + Q_UNUSED(channel) + return false; +} diff --git a/libnymea/platform/platformupdatecontroller.h b/libnymea/platform/platformupdatecontroller.h new file mode 100644 index 00000000..0a2c6b1a --- /dev/null +++ b/libnymea/platform/platformupdatecontroller.h @@ -0,0 +1,37 @@ +#ifndef PLATFORMUPDATECONTROLLER_H +#define PLATFORMUPDATECONTROLLER_H + +#include + +class PlatformUpdateController : public QObject +{ + Q_OBJECT +public: + explicit PlatformUpdateController(QObject *parent = nullptr); + virtual ~PlatformUpdateController() = default; + + virtual bool updateManagementAvailable(); + + virtual QString currentVersion() const; + virtual QString candidateVersion() const; + +// virtual QMap changelog() const = 0; + + virtual void checkForUpdates(); + virtual bool updateAvailable() const; + virtual bool startUpdate(); + + virtual bool rollbackAvailable() const; + virtual bool startRollback(); + + virtual bool updateInProgress() const; + + virtual QStringList availableChannels() const; + virtual QString currentChannel() const; + virtual bool selectChannel(const QString &channel); + +signals: + void updateStatusChanged(); +}; + +#endif // PLATFORMUPDATECONTROLLER_H diff --git a/libnymea/plugin/platformplugin.cpp b/libnymea/plugin/platformplugin.cpp deleted file mode 100644 index 6fa6d816..00000000 --- a/libnymea/plugin/platformplugin.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "platformplugin.h" - -PlatformPlugin::PlatformPlugin(QObject *parent) : QObject(parent) -{ - -} diff --git a/libnymea/plugin/platformsystemcontroller.cpp b/libnymea/plugin/platformsystemcontroller.cpp deleted file mode 100644 index a1d7dd6b..00000000 --- a/libnymea/plugin/platformsystemcontroller.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "platformsystemcontroller.h" - -PlatformSystemController::PlatformSystemController(QObject *parent) : QObject(parent) -{ - -} diff --git a/libnymea/plugin/platformupdatecontroller.cpp b/libnymea/plugin/platformupdatecontroller.cpp deleted file mode 100644 index 7464a4d8..00000000 --- a/libnymea/plugin/platformupdatecontroller.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "platformupdatecontroller.h" - -PlatformUpdateController::PlatformUpdateController(QObject *parent) : QObject(parent) -{ - -} - -/*! Override this to indicate whether update management is available. Defaults to false. - When a plugin returns true here, it is assumed that the system is capable of updating and nymea - has permissions to do so. - */ -bool PlatformUpdateController::updateManagementAvailable() -{ - return false; -} diff --git a/libnymea/plugin/platformupdatecontroller.h b/libnymea/plugin/platformupdatecontroller.h deleted file mode 100644 index 743d8212..00000000 --- a/libnymea/plugin/platformupdatecontroller.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef PLATFORMUPDATECONTROLLER_H -#define PLATFORMUPDATECONTROLLER_H - -#include - -class PlatformUpdateController : public QObject -{ - Q_OBJECT -public: - explicit PlatformUpdateController(QObject *parent = nullptr); - virtual ~PlatformUpdateController() = default; - - virtual bool updateManagementAvailable(); - - virtual QString currentVersion() const = 0; - virtual QString candidateVersion() const = 0; - -// virtual QMap changelog() const = 0; - - virtual void checkForUpdates() = 0; - virtual bool updateAvailable() const = 0; - virtual bool startUpdate() = 0; - - virtual bool rollbackAvailable() const = 0; - virtual bool startRollback() = 0; - - virtual bool updateInProgress() const = 0; - - virtual QStringList channels() const = 0; - virtual QString currentChannel() const = 0; - virtual bool selectChannel(const QString &channel) = 0; - -signals: - void updateStatusChanged(); -}; - -#endif // PLATFORMUPDATECONTROLLER_H From 0948ffb11eb326e2fde9151d217d96950bcf52da Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Fri, 10 May 2019 12:17:00 +0200 Subject: [PATCH 03/17] Fix plugin search dirs --- libnymea-core/platform/platform.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/libnymea-core/platform/platform.cpp b/libnymea-core/platform/platform.cpp index 56750c20..35335ce2 100644 --- a/libnymea-core/platform/platform.cpp +++ b/libnymea-core/platform/platform.cpp @@ -17,7 +17,7 @@ Platform::Platform(QObject *parent) : QObject(parent) foreach (const QString &entry, dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot)) { qCDebug(dcPlatform()) << "Found dir entry" << entry; QFileInfo fi; - if (entry.startsWith("libnymea_systemplugin") && entry.endsWith(".so")) { + if (entry.startsWith("libnymea_platformplugin") && entry.endsWith(".so")) { fi.setFile(path + "/" + entry); } else { fi.setFile(path + "/" + entry + "/libnymea_platformplugin" + entry + ".so"); @@ -68,10 +68,19 @@ PlatformUpdateController *Platform::updateController() const QStringList Platform::pluginSearchDirs() const { - QStringList ret; - ret << QString(qgetenv("NYMEA_PLATFORM_PLUGINS_PATH")).split(':'); - ret << QCoreApplication::applicationDirPath(); - return ret; + QStringList searchDirs; + QByteArray envPath = qgetenv("NYMEA_PLATFORM_PLUGINS_PATH"); + if (!envPath.isEmpty()) { + searchDirs << QString(envPath).split(':'); + } + + foreach (QString libraryPath, QCoreApplication::libraryPaths()) { + searchDirs << libraryPath.replace("qt5", "nymea").replace("plugins", "platforms"); + } + searchDirs << QCoreApplication::applicationDirPath() + "/../lib/nymea/platforms"; + searchDirs << QCoreApplication::applicationDirPath() + "/../platforms/"; + searchDirs << QCoreApplication::applicationDirPath() + "/../../../platforms/"; + return searchDirs; } } From 5a2734b793209d6d3e13d9ae7e3a2aa38fbdc2ad Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Fri, 10 May 2019 12:19:10 +0200 Subject: [PATCH 04/17] bump versions --- debian/changelog | 5 +++++ nymea.pri | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index a4c4cea2..b5079fdf 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,8 @@ +nymea (0.13.0) UNRELEASED; urgency=medium + + + -- Michael Zanetti Fri, 10 May 2019 12:18:54 +0200 + nymea (0.12.1) xenial; urgency=medium [ Michael Zanetti ] diff --git a/nymea.pri b/nymea.pri index 3a1a78eb..914914a5 100644 --- a/nymea.pri +++ b/nymea.pri @@ -3,7 +3,7 @@ NYMEA_VERSION_STRING=$$system('dpkg-parsechangelog | sed -n -e "s/^Version: //p" # define protocol versions JSON_PROTOCOL_VERSION_MAJOR=2 -JSON_PROTOCOL_VERSION_MINOR=0 +JSON_PROTOCOL_VERSION_MINOR=1 REST_API_VERSION=1 COPYRIGHT_YEAR_FROM=2013 From 99260c67b03efbf0416018adf28cb28ffeb04b69 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Fri, 10 May 2019 12:23:03 +0200 Subject: [PATCH 05/17] update API description --- tests/auto/api.json | 68 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/tests/auto/api.json b/tests/auto/api.json index 70bb436e..ac71eb7e 100644 --- a/tests/auto/api.json +++ b/tests/auto/api.json @@ -1,4 +1,4 @@ -2.0 +2.1 { "methods": { "Actions.ExecuteAction": { @@ -867,6 +867,61 @@ "o:stateType": "$ref:StateType" } }, + "System.GetCapabilities": { + "description": "Get the list of capabilites on this system. This allows reading whether things like rebooting or shutting down the system running nymea:core is supported on this host.", + "params": { + }, + "returns": { + "powerManagement": "Bool", + "updateManagement": "Bool" + } + }, + "System.GetUpdateStatus": { + "description": "Get the current system status in regard to updates. That is, the currently installed version, any candidate version available etc.", + "params": { + }, + "returns": { + "availableChannels": "StringList", + "candidateVersion": "String", + "currentChannel": "String", + "currentVersion": "String", + "updateAvailable": "Bool", + "updateInProgress": "Bool" + } + }, + "System.Reboot": { + "description": "Initiate a reboot of the system. The return value will indicate whether the procedure has been initiated successfully.", + "params": { + }, + "returns": { + "success": "Bool" + } + }, + "System.SelectChannel": { + "description": "Select an update channel.", + "params": { + "channel": "String" + }, + "returns": { + "success": "Bool" + } + }, + "System.Shutdown": { + "description": "Initiate a shutdown of the system. The return value will indicate whether the procedure has been initiated successfully.", + "params": { + }, + "returns": { + "success": "Bool" + } + }, + "System.StartUpdate": { + "description": "Starts a system update. Returns true if the upgrade has been started successfully.", + "params": { + }, + "returns": { + "success": "Bool" + } + }, "Tags.AddTag": { "description": "Add a Tag. A Tag must have a deviceId OR a ruleId (call this method twice if you want to attach the same tag to a device and a rule), an appId (Use the appId of your app), a tagId (e.g. \"favorites\") and a value. Upon success, a TagAdded notification will be emitted. Calling this method twice for the same ids (device/rule, appId and tagId) but with a different value will update the tag's value and the TagValueChanged notification will be emitted.", "params": { @@ -1127,6 +1182,17 @@ "ruleId": "Uuid" } }, + "System.UpdateStatusChanged": { + "description": "Emitted whenever there is a change in the information from GetUpdateStatus", + "params": { + "availableChannels": "StringList", + "candidateVersion": "String", + "currentChannel": "String", + "currentVersion": "String", + "updateAvailable": "Bool", + "updateInProgress": "Bool" + } + }, "Tags.TagAdded": { "description": "Emitted whenever a tag is added to the system. ", "params": { From 10d28889168d8dbe78b1207085e6d29c068cb5c5 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Fri, 10 May 2019 12:49:37 +0200 Subject: [PATCH 06/17] add missing namespace --- libnymea-core/jsonrpc/systemhandler.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libnymea-core/jsonrpc/systemhandler.cpp b/libnymea-core/jsonrpc/systemhandler.cpp index d222fd2f..bd907c10 100644 --- a/libnymea-core/jsonrpc/systemhandler.cpp +++ b/libnymea-core/jsonrpc/systemhandler.cpp @@ -4,6 +4,8 @@ #include "platform/platformupdatecontroller.h" #include "platform/platformsystemcontroller.h" +namespace nymeaserver { + SystemHandler::SystemHandler(Platform *platform, QObject *parent): JsonHandler(parent), m_platform(platform) @@ -146,3 +148,5 @@ void SystemHandler::onUpdateStatusChanged() params.insert("updateInProgress", m_platform->updateController()->updateInProgress()); emit UpdateStatusChanged(params); } + +} From 07cd3d94814d5f976734e9f4ca4f8cb00c80ae90 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Mon, 13 May 2019 19:52:20 +0200 Subject: [PATCH 07/17] add license headers --- libnymea-core/jsonrpc/systemhandler.cpp | 22 +++++++++++++++++++ libnymea-core/platform/platform.cpp | 22 +++++++++++++++++++ libnymea-core/platform/platform.h | 22 +++++++++++++++++++ libnymea/platform/platformplugin.cpp | 21 ++++++++++++++++++ libnymea/platform/platformplugin.h | 22 +++++++++++++++++++ .../platform/platformsystemcontroller.cpp | 22 +++++++++++++++++++ libnymea/platform/platformsystemcontroller.h | 22 +++++++++++++++++++ .../platform/platformupdatecontroller.cpp | 22 +++++++++++++++++++ libnymea/platform/platformupdatecontroller.h | 22 +++++++++++++++++++ 9 files changed, 197 insertions(+) diff --git a/libnymea-core/jsonrpc/systemhandler.cpp b/libnymea-core/jsonrpc/systemhandler.cpp index bd907c10..63580213 100644 --- a/libnymea-core/jsonrpc/systemhandler.cpp +++ b/libnymea-core/jsonrpc/systemhandler.cpp @@ -1,3 +1,25 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2019 Michael Zanetti * + * * + * This file is part of nymea. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; If not, see * + * . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + #include "systemhandler.h" #include "platform/platform.h" diff --git a/libnymea-core/platform/platform.cpp b/libnymea-core/platform/platform.cpp index 35335ce2..771b7461 100644 --- a/libnymea-core/platform/platform.cpp +++ b/libnymea-core/platform/platform.cpp @@ -1,3 +1,25 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2019 Michael Zanetti * + * * + * This file is part of nymea. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; If not, see * + * . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + #include "platform.h" #include "platform/platformplugin.h" diff --git a/libnymea-core/platform/platform.h b/libnymea-core/platform/platform.h index b034411b..b7660fe3 100644 --- a/libnymea-core/platform/platform.h +++ b/libnymea-core/platform/platform.h @@ -1,3 +1,25 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2019 Michael Zanetti * + * * + * This file is part of nymea. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; If not, see * + * . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + #ifndef PLATFORM_H #define PLATFORM_H diff --git a/libnymea/platform/platformplugin.cpp b/libnymea/platform/platformplugin.cpp index d07ef052..fb43a61f 100644 --- a/libnymea/platform/platformplugin.cpp +++ b/libnymea/platform/platformplugin.cpp @@ -1,3 +1,24 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2019 Michael Zanetti * + * * + * This file is part of nymea. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; If not, see * + * . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "platformplugin.h" PlatformPlugin::PlatformPlugin(QObject *parent) : QObject(parent) diff --git a/libnymea/platform/platformplugin.h b/libnymea/platform/platformplugin.h index 177440d2..011aabb5 100644 --- a/libnymea/platform/platformplugin.h +++ b/libnymea/platform/platformplugin.h @@ -1,3 +1,25 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2019 Michael Zanetti * + * * + * This file is part of nymea. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; If not, see * + * . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + #ifndef PLATFORMPLUGIN_H #define PLATFORMPLUGIN_H diff --git a/libnymea/platform/platformsystemcontroller.cpp b/libnymea/platform/platformsystemcontroller.cpp index 1034844a..dda77859 100644 --- a/libnymea/platform/platformsystemcontroller.cpp +++ b/libnymea/platform/platformsystemcontroller.cpp @@ -1,3 +1,25 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2019 Michael Zanetti * + * * + * This file is part of nymea. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; If not, see * + * . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + #include "platformsystemcontroller.h" PlatformSystemController::PlatformSystemController(QObject *parent) : QObject(parent) diff --git a/libnymea/platform/platformsystemcontroller.h b/libnymea/platform/platformsystemcontroller.h index 2a56738b..f0da5cb6 100644 --- a/libnymea/platform/platformsystemcontroller.h +++ b/libnymea/platform/platformsystemcontroller.h @@ -1,3 +1,25 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2019 Michael Zanetti * + * * + * This file is part of nymea. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; If not, see * + * . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + #ifndef PLATFORMSYSTEMCONTROLLER_H #define PLATFORMSYSTEMCONTROLLER_H diff --git a/libnymea/platform/platformupdatecontroller.cpp b/libnymea/platform/platformupdatecontroller.cpp index 33a292bf..7c684827 100644 --- a/libnymea/platform/platformupdatecontroller.cpp +++ b/libnymea/platform/platformupdatecontroller.cpp @@ -1,3 +1,25 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2019 Michael Zanetti * + * * + * This file is part of nymea. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; If not, see * + * . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + #include "platformupdatecontroller.h" PlatformUpdateController::PlatformUpdateController(QObject *parent) : QObject(parent) diff --git a/libnymea/platform/platformupdatecontroller.h b/libnymea/platform/platformupdatecontroller.h index 0a2c6b1a..fee426b4 100644 --- a/libnymea/platform/platformupdatecontroller.h +++ b/libnymea/platform/platformupdatecontroller.h @@ -1,3 +1,25 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2019 Michael Zanetti * + * * + * This file is part of nymea. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; If not, see * + * . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + #ifndef PLATFORMUPDATECONTROLLER_H #define PLATFORMUPDATECONTROLLER_H From 06bd361e2f3808cf4a6124055b47f03ac0ac5cd1 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Tue, 14 May 2019 02:25:27 +0200 Subject: [PATCH 08/17] Add the platform plugin to dpkg recommends --- debian/control | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/control b/debian/control index b9ff6750..ac5ba9b5 100644 --- a/debian/control +++ b/debian/control @@ -68,7 +68,8 @@ Depends: libqt5network5, ${shlibs:Depends}, ${misc:Depends} Recommends: nymea-cli, - network-manager + network-manager, + nymea-platform-plugin-impl, Replaces: guhd Description: An open source IoT server - daemon The nymea daemon is a plugin based IoT (Internet of Things) server. The From afa1126e6ef8819dd88084f6104dcd85a94d0a7e Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sat, 18 May 2019 00:51:51 +0200 Subject: [PATCH 09/17] More work on the system management api --- libnymea-core/jsonrpc/jsontypes.cpp | 50 ++++ libnymea-core/jsonrpc/jsontypes.h | 7 + libnymea-core/jsonrpc/systemhandler.cpp | 214 +++++++++++++----- libnymea-core/jsonrpc/systemhandler.h | 18 +- libnymea-core/platform/platform.cpp | 112 +++++---- libnymea-core/platform/platform.h | 7 +- libnymea/libnymea.pro | 6 +- libnymea/loggingcategories.cpp | 1 + libnymea/loggingcategories.h | 1 + libnymea/platform/package.cpp | 98 ++++++++ libnymea/platform/package.h | 46 ++++ libnymea/platform/platformplugin.cpp | 37 --- libnymea/platform/platformplugin.h | 50 ---- libnymea/platform/platformsystemcontroller.h | 5 + .../platform/platformupdatecontroller.cpp | 46 ++-- libnymea/platform/platformupdatecontroller.h | 33 +-- libnymea/platform/repository.cpp | 34 +++ libnymea/platform/repository.h | 24 ++ server/main.cpp | 1 + tests/auto/api.json | 113 +++++++-- 20 files changed, 656 insertions(+), 247 deletions(-) create mode 100644 libnymea/platform/package.cpp create mode 100644 libnymea/platform/package.h delete mode 100644 libnymea/platform/platformplugin.cpp delete mode 100644 libnymea/platform/platformplugin.h create mode 100644 libnymea/platform/repository.cpp create mode 100644 libnymea/platform/repository.h diff --git a/libnymea-core/jsonrpc/jsontypes.cpp b/libnymea-core/jsonrpc/jsontypes.cpp index ddf3e851..39d1c21a 100644 --- a/libnymea-core/jsonrpc/jsontypes.cpp +++ b/libnymea-core/jsonrpc/jsontypes.cpp @@ -126,6 +126,8 @@ QVariantMap JsonTypes::s_serverConfiguration; QVariantMap JsonTypes::s_webServerConfiguration; QVariantMap JsonTypes::s_tag; QVariantMap JsonTypes::s_mqttPolicy; +QVariantMap JsonTypes::s_package; +QVariantMap JsonTypes::s_repository; void JsonTypes::init() { @@ -400,6 +402,19 @@ void JsonTypes::init() s_tag.insert("tagId", basicTypeToString(QVariant::String)); s_tag.insert("o:value", basicTypeToString(QVariant::String)); + s_package.insert("id", basicTypeToString(QVariant::String)); + s_package.insert("displayName", basicTypeToString(QVariant::String)); + s_package.insert("installedVersion", basicTypeToString(QVariant::String)); + s_package.insert("candidateVersion", basicTypeToString(QVariant::String)); + s_package.insert("changelog", basicTypeToString(QVariant::String)); + s_package.insert("updateAvailable", basicTypeToString(QVariant::Bool)); + s_package.insert("rollbackAvailable", basicTypeToString(QVariant::Bool)); + s_package.insert("canRemove", basicTypeToString(QVariant::Bool)); + + s_repository.insert("id", basicTypeToString(QVariant::String)); + s_repository.insert("displayName", basicTypeToString(QVariant::String)); + s_repository.insert("enabled", basicTypeToString(QVariant::Bool)); + s_initialized = true; } @@ -1268,6 +1283,29 @@ QVariantMap JsonTypes::packTokenInfo(const TokenInfo &tokenInfo) return ret; } +QVariantMap JsonTypes::packPackage(const Package &package) +{ + QVariantMap ret; + ret.insert("id", package.packageId()); + ret.insert("displayName", package.displayName()); + ret.insert("installedVersion", package.installedVersion()); + ret.insert("candidateVersion", package.candidateVersion()); + ret.insert("changelog", package.changelog()); + ret.insert("updateAvailable", package.updateAvailable()); + ret.insert("rollbackAvailable", package.rollbackAvailable()); + ret.insert("canRemove", package.canRemove()); + return ret; +} + +QVariantMap JsonTypes::packRepository(const Repository &repository) +{ + QVariantMap ret; + ret.insert("id", repository.id()); + ret.insert("displayName", repository.displayName()); + ret.insert("enabled", repository.enabled()); + return ret; +} + /*! Returns the type string for the given \a type. */ QString JsonTypes::basicTypeToString(const QVariant::Type &type) { @@ -2013,6 +2051,18 @@ QPair JsonTypes::validateVariant(const QVariant &templateVariant, qCWarning(dcJsonRpc) << "Tag not matching"; return result; } + } else if (refName == packageRef()) { + QPair result = validateMap(packageDescription(), variant.toMap()); + if (!result.first) { + qCWarning(dcJsonRpc) << "Package not matching"; + return result; + } + } else if (refName == repositoryRef()) { + QPair result = validateMap(repositoryDescription(), variant.toMap()); + if (!result.first) { + qCWarning(dcJsonRpc) << "Repository not matching"; + return result; + } } else if (refName == basicTypeRef()) { QPair result = validateBasicType(variant); if (!result.first) { diff --git a/libnymea-core/jsonrpc/jsontypes.h b/libnymea-core/jsonrpc/jsontypes.h index 6fc417eb..5be24709 100644 --- a/libnymea-core/jsonrpc/jsontypes.h +++ b/libnymea-core/jsonrpc/jsontypes.h @@ -57,6 +57,8 @@ #include "networkmanager/wirelessaccesspoint.h" #include "cloud/cloudmanager.h" +#include "platform/package.h" +#include "platform/repository.h" #include @@ -176,6 +178,8 @@ public: DECLARE_OBJECT(webServerConfiguration, "WebServerConfiguration") DECLARE_OBJECT(tag, "Tag") DECLARE_OBJECT(mqttPolicy, "MqttPolicy") + DECLARE_OBJECT(package, "Package") + DECLARE_OBJECT(repository, "Repository") // pack types static QVariantMap packEventType(const EventType &eventType, const PluginId &pluginId, const QLocale &locale); @@ -232,6 +236,9 @@ public: static QVariantMap packTokenInfo(const TokenInfo &tokenInfo); + static QVariantMap packPackage(const Package &package); + static QVariantMap packRepository(const Repository &repository); + static QString basicTypeToString(const QVariant::Type &type); // unpack Types diff --git a/libnymea-core/jsonrpc/systemhandler.cpp b/libnymea-core/jsonrpc/systemhandler.cpp index 63580213..23b184a6 100644 --- a/libnymea-core/jsonrpc/systemhandler.cpp +++ b/libnymea-core/jsonrpc/systemhandler.cpp @@ -53,42 +53,127 @@ SystemHandler::SystemHandler(Platform *platform, QObject *parent): setReturns("Shutdown", returns); params.clear(); returns.clear(); - setDescription("GetUpdateStatus", "Get the current system status in regard to updates. That is, the currently installed version, any candidate version available etc."); - setParams("GetUpdateStatus", params); - returns.insert("updateAvailable", JsonTypes::basicTypeToString(JsonTypes::Bool)); - returns.insert("currentVersion", JsonTypes::basicTypeToString(JsonTypes::String)); - returns.insert("candidateVersion", JsonTypes::basicTypeToString(JsonTypes::String)); - returns.insert("availableChannels", JsonTypes::basicTypeToString(JsonTypes::StringList)); - returns.insert("currentChannel", JsonTypes::basicTypeToString(JsonTypes::String)); - returns.insert("updateInProgress", JsonTypes::basicTypeToString(JsonTypes::Bool)); - setReturns("GetUpdateStatus", returns); + setDescription("GetPackages", "Get the list of packages currently available to the system. This includes installed and available but not installed packages."); + setParams("GetPackages", params); + returns.insert("packages", QVariantList() << JsonTypes::packageRef()); + setReturns("GetPackages", returns); params.clear(); returns.clear(); - setDescription("StartUpdate", "Starts a system update. Returns true if the upgrade has been started successfully."); - setParams("StartUpdate", params); + setDescription("UpdatePackages", "Starts updating/installing packages with the given ids. Returns true if the upgrade has been started successfully. Note that it might still fail later."); + params.insert("o:packageIds", QVariantList() << JsonTypes::basicTypeToString(JsonTypes::String)); + setParams("UpdatePackages", params); returns.insert("success", JsonTypes::basicTypeToString(JsonTypes::Bool)); - setReturns("StartUpdate", returns); + setReturns("UpdatePackages", returns); params.clear(); returns.clear(); - setDescription("SelectChannel", "Select an update channel."); - params.insert("channel", JsonTypes::basicTypeToString(JsonTypes::String)); - setParams("SelectChannel", params); + setDescription("RollbackPackages", "Starts a rollback. Returns true if the rollback has been started successfully."); + params.insert("packageIds", QVariantList() << JsonTypes::basicTypeToString(JsonTypes::String)); + setParams("RollbackPackages", params); returns.insert("success", JsonTypes::basicTypeToString(JsonTypes::Bool)); - setReturns("SelectChannel", returns); + setReturns("RollbackPackages", returns); + + params.clear(); returns.clear(); + setDescription("RemovePackages", "Starts removing a package. Returns true if the removal has been started successfully."); + params.insert("packageIds", QVariantList() << JsonTypes::basicTypeToString(JsonTypes::String)); + setParams("RemovePackages", params); + returns.insert("success", JsonTypes::basicTypeToString(JsonTypes::Bool)); + setReturns("RemovePackages", returns); + + params.clear(); returns.clear(); + setDescription("GetRepositories", "Get the list of repositories currently available to the system."); + setParams("GetRepositories", params); + returns.insert("repositories", QVariantList() << JsonTypes::repositoryRef()); + setReturns("GetRepositories", returns); + + params.clear(); returns.clear(); + setDescription("EnableRepository", "Enable or disable a repository."); + params.insert("repositoryId", JsonTypes::basicTypeToString(JsonTypes::String)); + params.insert("enabled", JsonTypes::basicTypeToString(JsonTypes::Bool)); + setParams("EnableRepository", params); + returns.insert("success", JsonTypes::basicTypeToString(JsonTypes::Bool)); + setReturns("EnableRepository", returns); // Notifications params.clear(); - setDescription("UpdateStatusChanged", "Emitted whenever there is a change in the information from GetUpdateStatus"); - params.insert("updateAvailable", JsonTypes::basicTypeToString(JsonTypes::Bool)); - params.insert("currentVersion", JsonTypes::basicTypeToString(JsonTypes::String)); - params.insert("candidateVersion", JsonTypes::basicTypeToString(JsonTypes::String)); - params.insert("availableChannels", JsonTypes::basicTypeToString(JsonTypes::StringList)); - params.insert("currentChannel", JsonTypes::basicTypeToString(JsonTypes::String)); - params.insert("updateInProgress", JsonTypes::basicTypeToString(JsonTypes::Bool)); + setDescription("CapabilitiesChanged", "Emitted whenever the system capabilities change."); + params.insert("powerManagement", JsonTypes::basicTypeToString(JsonTypes::Bool)); + params.insert("updateManagement", JsonTypes::basicTypeToString(JsonTypes::Bool)); + setParams("CapabilitiesChanged", params); + + params.clear(); + setDescription("UpdateStatusChanged", "Emitted whenever the update status changes."); + params.insert("updateRunning", JsonTypes::basicTypeToString(JsonTypes::Bool)); setParams("UpdateStatusChanged", params); - connect(m_platform->updateController(), &PlatformUpdateController::updateStatusChanged, this, &SystemHandler::onUpdateStatusChanged); + params.clear(); + setDescription("PackageAdded", "Emitted whenever a package is added to the list of packages."); + params.insert("package", JsonTypes::packageRef()); + setParams("PackageAdded", params); + + params.clear(); + setDescription("PackageChanged", "Emitted whenever a package in the list of packages changes."); + params.insert("package", JsonTypes::packageRef()); + setParams("PackageChanged", params); + + params.clear(); + setDescription("PackageRemoved", "Emitted whenever a package is removed from the list of packages."); + params.insert("packageId", JsonTypes::basicTypeToString(JsonTypes::String)); + setParams("PackageRemoved", params); + + params.clear(); + setDescription("RepositoryAdded", "Emitted whenever a repository is added to the list of repositories."); + params.insert("repository", JsonTypes::repositoryRef()); + setParams("RepositoryAdded", params); + + params.clear(); + setDescription("RepositoryChanged", "Emitted whenever a repository in the list of repositories changes."); + params.insert("repository", JsonTypes::repositoryRef()); + setParams("RepositoryChanged", params); + + params.clear(); + setDescription("RepositoryRemoved", "Emitted whenever a repository is removed from the list of repositories."); + params.insert("repository", JsonTypes::basicTypeToString(JsonTypes::String)); + setParams("RepositoryRemoved", params); + + + connect(m_platform->systemController(), &PlatformSystemController::availableChanged, this, &SystemHandler::onCapabilitiesChanged); + connect(m_platform->updateController(), &PlatformUpdateController::availableChanged, this, &SystemHandler::onCapabilitiesChanged); + connect(m_platform->updateController(), &PlatformUpdateController::updateRunningChanged, this, [this](){ + QVariantMap params; + params.insert("updateRunning", m_platform->updateController()->updateRunning()); + emit UpdateStatusChanged(params); + }); + connect(m_platform->updateController(), &PlatformUpdateController::packageAdded, this, [this](const Package &package){ + QVariantMap params; + params.insert("package", JsonTypes::packPackage(package)); + emit PackageAdded(params); + }); + connect(m_platform->updateController(), &PlatformUpdateController::packageChanged, this, [this](const Package &package){ + QVariantMap params; + params.insert("package", JsonTypes::packPackage(package)); + emit PackageChanged(params); + }); + connect(m_platform->updateController(), &PlatformUpdateController::packageRemoved, this, [this](const QString &packageId){ + QVariantMap params; + params.insert("packageId", packageId); + emit PackageRemoved(params); + }); + connect(m_platform->updateController(), &PlatformUpdateController::repositoryAdded, this, [this](const Repository &repository){ + QVariantMap params; + params.insert("repository", JsonTypes::packRepository(repository)); + emit RepositoryAdded(params); + }); + connect(m_platform->updateController(), &PlatformUpdateController::repositoryChanged, this, [this](const Repository &repository){ + QVariantMap params; + params.insert("repository", JsonTypes::packRepository(repository)); + emit RepositoryChanged(params); + }); + connect(m_platform->updateController(), &PlatformUpdateController::repositoryRemoved, this, [this](const QString &repositoryId){ + QVariantMap params; + params.insert("repositoryId", repositoryId); + emit RepositoryRemoved(params); + }); } QString SystemHandler::name() const @@ -125,50 +210,75 @@ JsonReply *SystemHandler::Shutdown(const QVariantMap ¶ms) const JsonReply *SystemHandler::GetUpdateStatus(const QVariantMap ¶ms) const { - Q_UNUSED(params); + Q_UNUSED(params) + QVariantMap ret; + ret.insert("updateRunning", m_platform->updateController()->updateRunning()); + return createReply(ret); +} + +JsonReply *SystemHandler::GetPackages(const QVariantMap ¶ms) const +{ + Q_UNUSED(params) + QVariantList packagelist; + foreach (const Package &package, m_platform->updateController()->packages()) { + packagelist.append(JsonTypes::packPackage(package)); + } QVariantMap returns; - returns.insert("updateAvailable", m_platform->updateController()->updateAvailable()); - returns.insert("currentVersion", m_platform->updateController()->currentVersion()); - returns.insert("candidateVersion", m_platform->updateController()->candidateVersion()); - returns.insert("availableChannels", m_platform->updateController()->availableChannels()); - returns.insert("currentChannel", m_platform->updateController()->currentChannel()); - returns.insert("updateInProgress", m_platform->updateController()->updateInProgress()); + returns.insert("packages", packagelist); return createReply(returns); } -JsonReply *SystemHandler::StartUpdate(const QVariantMap ¶ms) +JsonReply *SystemHandler::UpdatePackages(const QVariantMap ¶ms) const { - Q_UNUSED(params) + bool success = m_platform->updateController()->startUpdate(params.value("packageIds").toStringList()); QVariantMap returns; - bool success = m_platform->updateController()->startUpdate(); returns.insert("success", success); return createReply(returns); } -JsonReply *SystemHandler::SelectChannel(const QVariantMap ¶ms) +JsonReply *SystemHandler::RollbackPackages(const QVariantMap ¶ms) const { - QString channel = params.value("channel").toString(); - + bool success = m_platform->updateController()->rollback(params.value("packageIds").toStringList()); QVariantMap returns; - if (m_platform->updateController()->availableChannels().contains(channel)) { - bool success = m_platform->updateController()->selectChannel(channel); - returns.insert("success", success); - } else { - returns.insert("success", false); - } + returns.insert("success", success); return createReply(returns); } -void SystemHandler::onUpdateStatusChanged() +JsonReply *SystemHandler::RemovePackages(const QVariantMap ¶ms) const { - QVariantMap params; - params.insert("updateAvailable", m_platform->updateController()->updateAvailable()); - params.insert("currentVersion", m_platform->updateController()->currentVersion()); - params.insert("candidateVersion", m_platform->updateController()->candidateVersion()); - params.insert("availableChannels", m_platform->updateController()->availableChannels()); - params.insert("currentChannel", m_platform->updateController()->currentChannel()); - params.insert("updateInProgress", m_platform->updateController()->updateInProgress()); - emit UpdateStatusChanged(params); + bool success = m_platform->updateController()->removePackages(params.value("packageIds").toStringList()); + QVariantMap returns; + returns.insert("success", success); + return createReply(returns); +} + +JsonReply *SystemHandler::GetRepositories(const QVariantMap ¶ms) const +{ + Q_UNUSED(params); + QVariantList repos; + foreach (const Repository &repository, m_platform->updateController()->repositories()) { + repos.append(JsonTypes::packRepository(repository)); + } + QVariantMap returns; + returns.insert("repositories", repos); + return createReply(returns); + +} + +JsonReply *SystemHandler::EnableRepository(const QVariantMap ¶ms) const +{ + bool success = m_platform->updateController()->enableRepository(params.value("repositoryId").toString(), params.value("enabled").toBool()); + QVariantMap returns; + returns.insert("success", success); + return createReply(returns); +} + +void SystemHandler::onCapabilitiesChanged() +{ + QVariantMap caps; + caps.insert("powerManagement", m_platform->systemController()->powerManagementAvailable()); + caps.insert("updateManagement", m_platform->updateController()->updateManagementAvailable()); + emit CapabilitiesChanged(caps); } } diff --git a/libnymea-core/jsonrpc/systemhandler.h b/libnymea-core/jsonrpc/systemhandler.h index 27c9fd93..727d4465 100644 --- a/libnymea-core/jsonrpc/systemhandler.h +++ b/libnymea-core/jsonrpc/systemhandler.h @@ -43,14 +43,26 @@ public: Q_INVOKABLE JsonReply *Shutdown(const QVariantMap ¶ms) const; Q_INVOKABLE JsonReply *GetUpdateStatus(const QVariantMap ¶ms) const; - Q_INVOKABLE JsonReply *StartUpdate(const QVariantMap ¶ms); - Q_INVOKABLE JsonReply *SelectChannel(const QVariantMap ¶ms); + Q_INVOKABLE JsonReply *GetPackages(const QVariantMap ¶ms) const; + Q_INVOKABLE JsonReply *UpdatePackages(const QVariantMap ¶ms) const; + Q_INVOKABLE JsonReply *RollbackPackages(const QVariantMap ¶ms) const; + Q_INVOKABLE JsonReply *RemovePackages(const QVariantMap ¶ms) const; + Q_INVOKABLE JsonReply *GetRepositories(const QVariantMap ¶ms) const; + Q_INVOKABLE JsonReply *EnableRepository(const QVariantMap ¶ms) const; signals: + void CapabilitiesChanged(const QVariantMap ¶ms); void UpdateStatusChanged(const QVariantMap ¶ms); + void PackageAdded(const QVariantMap ¶ms); + void PackageChanged(const QVariantMap ¶ms); + void PackageRemoved(const QVariantMap ¶ms); + void RepositoryAdded(const QVariantMap ¶ms); + void RepositoryChanged(const QVariantMap ¶ms); + void RepositoryRemoved(const QVariantMap ¶ms); private slots: - void onUpdateStatusChanged(); + void onCapabilitiesChanged(); + private: Platform *m_platform = nullptr; }; diff --git a/libnymea-core/platform/platform.cpp b/libnymea-core/platform/platform.cpp index 771b7461..445913a3 100644 --- a/libnymea-core/platform/platform.cpp +++ b/libnymea-core/platform/platform.cpp @@ -21,7 +21,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "platform.h" -#include "platform/platformplugin.h" +#include "platform/platformsystemcontroller.h" +#include "platform/platformupdatecontroller.h" #include "loggingcategories.h" @@ -38,54 +39,43 @@ Platform::Platform(QObject *parent) : QObject(parent) qCDebug(dcPlatform) << "Loading plugins from:" << dir.absolutePath(); foreach (const QString &entry, dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot)) { qCDebug(dcPlatform()) << "Found dir entry" << entry; - QFileInfo fi; - if (entry.startsWith("libnymea_platformplugin") && entry.endsWith(".so")) { - fi.setFile(path + "/" + entry); - } else { - fi.setFile(path + "/" + entry + "/libnymea_platformplugin" + entry + ".so"); + QFileInfo fi(path + "/" + entry); + if (fi.isFile()) { + if (entry.startsWith("libnymea_systemplugin") && entry.endsWith(".so")) { + loadSystemPlugin(path + "/" + entry); + } else if (entry.startsWith("libnymea_updateplugin") && entry.endsWith(".so")) { + loadUpdatePlugin(path + "/" + entry); + } + } else if (fi.isDir()) { + if (QFileInfo::exists(path + "/" + entry + "/libnymea_systemplugin" + entry + ".so")) { + loadSystemPlugin(path + "/" + entry + "/libnymea_systemplugin" + entry + ".so"); + } else if (QFileInfo::exists(path + "/" + entry + "/libnymea_platformplugin" + entry + ".so")) { + loadUpdatePlugin(path + "/" + entry + "/libnymea_platformplugin" + entry + ".so"); + } } - - if (!fi.exists()) - continue; - - - QPluginLoader loader; - loader.setFileName(fi.absoluteFilePath()); - loader.setLoadHints(QLibrary::ResolveAllSymbolsHint); - - if (!loader.load()) { - qCWarning(dcPlatform) << "Could not load plugin data of" << entry << "\n" << loader.errorString(); - continue; - } - - m_platformPlugin = qobject_cast(loader.instance()); - if (!m_platformPlugin) { - qCWarning(dcPlatform) << "Could not get plugin instance of" << entry; - continue; - } - qCDebug(dcPlatform()) << "Loaded platform plugin:" << entry; - m_platformPlugin->setParent(this); - break; } - if (m_platformPlugin) { + if (m_platformSystemController && m_platformUpdateController) { break; } } - if (!m_platformPlugin) { - qCWarning(dcPlatform()) << "Could not load a platform plugin. Platform related features won't be available."; - m_platformPlugin = new PlatformPlugin(this); + if (!m_platformSystemController) { + qCWarning(dcPlatform()) << "Could not load a system plugin. System control features won't be available."; + m_platformSystemController = new PlatformSystemController(this); + } + if (!m_platformUpdateController) { + qCWarning(dcPlatform()) << "Could not load an update plugin. System update features won't be available."; + m_platformUpdateController = new PlatformUpdateController(this); } - } PlatformSystemController *Platform::systemController() const { - return m_platformPlugin->systemController(); + return m_platformSystemController; } PlatformUpdateController *Platform::updateController() const { - return m_platformPlugin->updateController(); + return m_platformUpdateController; } QStringList Platform::pluginSearchDirs() const @@ -97,12 +87,56 @@ QStringList Platform::pluginSearchDirs() const } foreach (QString libraryPath, QCoreApplication::libraryPaths()) { - searchDirs << libraryPath.replace("qt5", "nymea").replace("plugins", "platforms"); + searchDirs << libraryPath.replace("qt5", "nymea").replace("plugins", "platform"); } - searchDirs << QCoreApplication::applicationDirPath() + "/../lib/nymea/platforms"; - searchDirs << QCoreApplication::applicationDirPath() + "/../platforms/"; - searchDirs << QCoreApplication::applicationDirPath() + "/../../../platforms/"; + searchDirs << QCoreApplication::applicationDirPath() + "/../lib/nymea/platform"; + searchDirs << QCoreApplication::applicationDirPath() + "/../platform/"; + searchDirs << QCoreApplication::applicationDirPath() + "/../../../platform/"; return searchDirs; } +void Platform::loadSystemPlugin(const QString &file) +{ + if (m_platformSystemController) { + return; // Not loading another... + } + QPluginLoader loader; + loader.setFileName(file); + loader.setLoadHints(QLibrary::ResolveAllSymbolsHint); + if (!loader.load()) { + qCWarning(dcPlatform) << "Could not load plugin data of" << file << "\n" << loader.errorString(); + return; + } + m_platformSystemController = qobject_cast(loader.instance()); + if (!m_platformSystemController) { + qCWarning(dcPlatform) << "Could not get plugin instance of" << file; + loader.unload(); + return; + } + qCDebug(dcPlatform()) << "Loaded system plugin:" << file; + m_platformSystemController->setParent(this); +} + +void Platform::loadUpdatePlugin(const QString &file) +{ + if (m_platformUpdateController) { + return; // Not loading another... + } + QPluginLoader loader; + loader.setFileName(file); + loader.setLoadHints(QLibrary::ResolveAllSymbolsHint); + if (!loader.load()) { + qCWarning(dcPlatform) << "Could not load plugin data of" << file << "\n" << loader.errorString(); + return; + } + m_platformUpdateController = qobject_cast(loader.instance()); + if (!m_platformUpdateController) { + qCWarning(dcPlatform) << "Could not get plugin instance of" << file; + loader.unload(); + return; + } + qCDebug(dcPlatform()) << "Loaded update plugin:" << file; + m_platformUpdateController->setParent(this); +} + } diff --git a/libnymea-core/platform/platform.h b/libnymea-core/platform/platform.h index b7660fe3..2b8657b7 100644 --- a/libnymea-core/platform/platform.h +++ b/libnymea-core/platform/platform.h @@ -25,7 +25,6 @@ #include -class PlatformPlugin; class PlatformSystemController; class PlatformUpdateController; @@ -43,8 +42,12 @@ public: private: QStringList pluginSearchDirs() const; + void loadSystemPlugin(const QString &file); + void loadUpdatePlugin(const QString &file); + private: - PlatformPlugin *m_platformPlugin = nullptr; + PlatformSystemController *m_platformSystemController = nullptr; + PlatformUpdateController *m_platformUpdateController = nullptr; }; } diff --git a/libnymea/libnymea.pro b/libnymea/libnymea.pro index 97b7d889..56e6a37e 100644 --- a/libnymea/libnymea.pro +++ b/libnymea/libnymea.pro @@ -12,6 +12,8 @@ LIBS += -lavahi-common -lavahi-client HEADERS += devicemanager.h \ libnymea.h \ + platform/package.h \ + platform/repository.h \ typeutils.h \ loggingcategories.h \ nymeasettings.h \ @@ -66,13 +68,14 @@ HEADERS += devicemanager.h \ network/mqtt/mqttprovider.h \ network/mqtt/mqttchannel.h \ translator.h \ - platform/platformplugin.h \ platform/platformsystemcontroller.h \ platform/platformupdatecontroller.h SOURCES += devicemanager.cpp \ loggingcategories.cpp \ nymeasettings.cpp \ + platform/package.cpp \ + platform/repository.cpp \ plugin/device.cpp \ plugin/deviceplugin.cpp \ plugin/devicedescriptor.cpp \ @@ -124,7 +127,6 @@ SOURCES += devicemanager.cpp \ network/mqtt/mqttprovider.cpp \ network/mqtt/mqttchannel.cpp \ translator.cpp \ - platform/platformplugin.cpp \ platform/platformsystemcontroller.cpp \ platform/platformupdatecontroller.cpp diff --git a/libnymea/loggingcategories.cpp b/libnymea/loggingcategories.cpp index 019efb0e..657174a2 100644 --- a/libnymea/loggingcategories.cpp +++ b/libnymea/loggingcategories.cpp @@ -26,6 +26,7 @@ Q_LOGGING_CATEGORY(dcApplication, "Application") Q_LOGGING_CATEGORY(dcDeviceManager, "DeviceManager") Q_LOGGING_CATEGORY(dcSystem, "System") Q_LOGGING_CATEGORY(dcPlatform, "Platform") +Q_LOGGING_CATEGORY(dcPlatformUpdate, "PlatformUpdate") Q_LOGGING_CATEGORY(dcTimeManager, "TimeManager") Q_LOGGING_CATEGORY(dcRuleEngine, "RuleEngine") Q_LOGGING_CATEGORY(dcRuleEngineDebug, "RuleEngineDebug") diff --git a/libnymea/loggingcategories.h b/libnymea/loggingcategories.h index dd32e1ea..d9c8ef42 100644 --- a/libnymea/loggingcategories.h +++ b/libnymea/loggingcategories.h @@ -31,6 +31,7 @@ Q_DECLARE_LOGGING_CATEGORY(dcApplication) Q_DECLARE_LOGGING_CATEGORY(dcDeviceManager) Q_DECLARE_LOGGING_CATEGORY(dcSystem) Q_DECLARE_LOGGING_CATEGORY(dcPlatform) +Q_DECLARE_LOGGING_CATEGORY(dcPlatformUpdate) Q_DECLARE_LOGGING_CATEGORY(dcTimeManager) Q_DECLARE_LOGGING_CATEGORY(dcRuleEngine) Q_DECLARE_LOGGING_CATEGORY(dcRuleEngineDebug) diff --git a/libnymea/platform/package.cpp b/libnymea/platform/package.cpp new file mode 100644 index 00000000..982791ef --- /dev/null +++ b/libnymea/platform/package.cpp @@ -0,0 +1,98 @@ +#include "package.h" + +Package::Package(const QString &packageId, const QString &displayName, const QString &installedVersion, const QString &candidateVersion, const QString &changelog): + m_packageId(packageId), + m_displayName(displayName), + m_installedVersion(installedVersion), + m_candidateVersion(candidateVersion), + m_changeLog(changelog) +{ + +} + +QString Package::packageId() const +{ + return m_packageId; +} + +QString Package::displayName() const +{ + return m_displayName; +} + +QString Package::installedVersion() const +{ + return m_installedVersion; +} + +void Package::setInstalledVersion(const QString &installedVersion) +{ + m_installedVersion = installedVersion; +} + +QString Package::candidateVersion() const +{ + return m_candidateVersion; +} + +void Package::setCandidateVersion(const QString &candidateVersion) +{ + m_candidateVersion = candidateVersion; +} + +QString Package::changelog() const +{ + return m_changeLog; +} + +void Package::setChangelog(const QString &changelog) +{ + m_changeLog = changelog; +} + +bool Package::updateAvailable() const +{ + return m_updateAvailable; +} + +void Package::setUpdateAvailable(bool updateAvailable) +{ + m_updateAvailable = updateAvailable; +} + +bool Package::rollbackAvailable() const +{ + return m_rollbackAvailable; +} + +void Package::setRollbackAvailable(bool rollbackAvailable) +{ + m_rollbackAvailable = rollbackAvailable; +} + +bool Package::canRemove() const +{ + return m_canRemove; +} + +void Package::setCanRemove(bool canRemove) +{ + m_canRemove = canRemove; +} + +bool Package::operator==(const Package &other) const +{ + return m_packageId == other.packageId() && + m_displayName == other.displayName() && + m_installedVersion == other.installedVersion() && + m_candidateVersion == other.candidateVersion() && + m_changeLog == other.changelog() && + m_updateAvailable == other.updateAvailable() && + m_rollbackAvailable == other.rollbackAvailable() && + m_canRemove == other.canRemove(); +} + +bool Package::operator!=(const Package &other) const +{ + return !operator==(other); +} diff --git a/libnymea/platform/package.h b/libnymea/platform/package.h new file mode 100644 index 00000000..797faa2d --- /dev/null +++ b/libnymea/platform/package.h @@ -0,0 +1,46 @@ +#ifndef PACKAGE_H +#define PACKAGE_H + +#include + +class Package +{ +public: + explicit Package(const QString &packageId = QString(), const QString &displayName = QString(), const QString &installedVersion = QString(), const QString &candidateVersion = QString(), const QString &changelog = QString()); + + QString packageId() const; + QString displayName() const; + QString installedVersion() const; + void setInstalledVersion(const QString &installedVersion); + + QString candidateVersion() const; + void setCandidateVersion(const QString &candidateVersion); + + QString changelog() const; + void setChangelog(const QString &changelog); + + bool updateAvailable() const; + void setUpdateAvailable(bool updateAvailable); + + bool rollbackAvailable() const; + void setRollbackAvailable(bool rollbackAvailable); + + bool canRemove() const; + void setCanRemove(bool canRemove); + + bool operator==(const Package &other) const; + bool operator!=(const Package &other) const; + +private: + QString m_packageId; + QString m_displayName; + QString m_installedVersion; + QString m_candidateVersion; + QString m_changeLog; + + bool m_updateAvailable = false; + bool m_rollbackAvailable = false; + bool m_canRemove = false; +}; + +#endif // PACKAGE_H diff --git a/libnymea/platform/platformplugin.cpp b/libnymea/platform/platformplugin.cpp deleted file mode 100644 index fb43a61f..00000000 --- a/libnymea/platform/platformplugin.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * * - * Copyright (C) 2019 Michael Zanetti * - * * - * This file is part of nymea. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public * - * License as published by the Free Software Foundation; either * - * version 2.1 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this library; If not, see * - * . * - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include "platformplugin.h" - -PlatformPlugin::PlatformPlugin(QObject *parent) : QObject(parent) -{ - -} - -PlatformSystemController *PlatformPlugin::systemController() const -{ - return m_systemStub; -} - -PlatformUpdateController *PlatformPlugin::updateController() const -{ - return m_updateStub; -} diff --git a/libnymea/platform/platformplugin.h b/libnymea/platform/platformplugin.h deleted file mode 100644 index 011aabb5..00000000 --- a/libnymea/platform/platformplugin.h +++ /dev/null @@ -1,50 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * * - * Copyright (C) 2019 Michael Zanetti * - * * - * This file is part of nymea. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public * - * License as published by the Free Software Foundation; either * - * version 2.1 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this library; If not, see * - * . * - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef PLATFORMPLUGIN_H -#define PLATFORMPLUGIN_H - -#include - -#include "libnymea.h" - -class PlatformSystemController; -class PlatformUpdateController; - -class LIBNYMEA_EXPORT PlatformPlugin: public QObject -{ - Q_OBJECT -public: - explicit PlatformPlugin(QObject *parent = nullptr); - virtual ~PlatformPlugin() = default; - - virtual PlatformSystemController *systemController() const; - virtual PlatformUpdateController *updateController() const; - -private: - PlatformSystemController *m_systemStub = nullptr; - PlatformUpdateController *m_updateStub = nullptr; -}; - -Q_DECLARE_INTERFACE(PlatformPlugin, "io.nymea.PlatformPlugin") - -#endif // PLATFORMPLUGIN_H diff --git a/libnymea/platform/platformsystemcontroller.h b/libnymea/platform/platformsystemcontroller.h index f0da5cb6..a1de5fa9 100644 --- a/libnymea/platform/platformsystemcontroller.h +++ b/libnymea/platform/platformsystemcontroller.h @@ -35,6 +35,11 @@ public: virtual bool powerManagementAvailable() const; virtual bool reboot(); virtual bool shutdown(); + +signals: + void availableChanged(); }; +Q_DECLARE_INTERFACE(PlatformSystemController, "io.nymea.PlatformSystemController") + #endif // PLATFORMSYSTEMCONTROLLER_H diff --git a/libnymea/platform/platformupdatecontroller.cpp b/libnymea/platform/platformupdatecontroller.cpp index 7c684827..34ba4635 100644 --- a/libnymea/platform/platformupdatecontroller.cpp +++ b/libnymea/platform/platformupdatecontroller.cpp @@ -36,14 +36,19 @@ bool PlatformUpdateController::updateManagementAvailable() return false; } -QString PlatformUpdateController::currentVersion() const +bool PlatformUpdateController::updateRunning() const { - return tr("N/A"); + return false; } -QString PlatformUpdateController::candidateVersion() const +QList PlatformUpdateController::packages() const { - return tr("N/A"); + return {}; +} + +QList PlatformUpdateController::repositories() const +{ + return {}; } void PlatformUpdateController::checkForUpdates() @@ -51,43 +56,28 @@ void PlatformUpdateController::checkForUpdates() // Nothing to do here } -bool PlatformUpdateController::updateAvailable() const +bool PlatformUpdateController::startUpdate(const QStringList &packageIds) { + Q_UNUSED(packageIds) return false; } -bool PlatformUpdateController::startUpdate() +bool PlatformUpdateController::rollback(const QStringList &packageIds) { + Q_UNUSED(packageIds) return false; } -bool PlatformUpdateController::rollbackAvailable() const +bool PlatformUpdateController::removePackages(const QStringList &packageIds) { + Q_UNUSED(packageIds) return false; } -bool PlatformUpdateController::startRollback() +bool PlatformUpdateController::enableRepository(const QString &repositoryId, bool enabled) { + Q_UNUSED(repositoryId) + Q_UNUSED(enabled) return false; } -bool PlatformUpdateController::updateInProgress() const -{ - return false; -} - -QStringList PlatformUpdateController::availableChannels() const -{ - return {}; -} - -QString PlatformUpdateController::currentChannel() const -{ - return tr("N/A"); -} - -bool PlatformUpdateController::selectChannel(const QString &channel) -{ - Q_UNUSED(channel) - return false; -} diff --git a/libnymea/platform/platformupdatecontroller.h b/libnymea/platform/platformupdatecontroller.h index fee426b4..cfcac33e 100644 --- a/libnymea/platform/platformupdatecontroller.h +++ b/libnymea/platform/platformupdatecontroller.h @@ -23,6 +23,9 @@ #ifndef PLATFORMUPDATECONTROLLER_H #define PLATFORMUPDATECONTROLLER_H +#include "package.h" +#include "repository.h" + #include class PlatformUpdateController : public QObject @@ -34,26 +37,30 @@ public: virtual bool updateManagementAvailable(); - virtual QString currentVersion() const; - virtual QString candidateVersion() const; + virtual bool updateRunning() const; -// virtual QMap changelog() const = 0; + virtual QList packages() const; + virtual QList repositories() const; virtual void checkForUpdates(); - virtual bool updateAvailable() const; - virtual bool startUpdate(); - virtual bool rollbackAvailable() const; - virtual bool startRollback(); + virtual bool startUpdate(const QStringList &packageIds = QStringList()); + virtual bool rollback(const QStringList &packageIds); + virtual bool removePackages(const QStringList &packageIds); - virtual bool updateInProgress() const; - - virtual QStringList availableChannels() const; - virtual QString currentChannel() const; - virtual bool selectChannel(const QString &channel); + virtual bool enableRepository(const QString &repositoryId, bool enabled); signals: - void updateStatusChanged(); + void availableChanged(); + void updateRunningChanged(); + void packageAdded(const Package &pacakge); + void packageChanged(const Package &package); + void packageRemoved(const QString &packageId); + void repositoryAdded(const Repository &repository); + void repositoryChanged(const Repository &repository); + void repositoryRemoved(const QString &repositoryId); }; +Q_DECLARE_INTERFACE(PlatformUpdateController, "io.nymea.PlatformUpdateController") + #endif // PLATFORMUPDATECONTROLLER_H diff --git a/libnymea/platform/repository.cpp b/libnymea/platform/repository.cpp new file mode 100644 index 00000000..986b03ca --- /dev/null +++ b/libnymea/platform/repository.cpp @@ -0,0 +1,34 @@ +#include "repository.h" + +Repository::Repository(const QString &id, const QString &displayName, bool enabled): + m_id(id), + m_displayName(displayName), + m_enabled(enabled) +{ + +} + +Repository::Repository() +{ + +} + +QString Repository::id() const +{ + return m_id; +} + +QString Repository::displayName() const +{ + return m_displayName; +} + +bool Repository::enabled() const +{ + return m_enabled; +} + +void Repository::setEnabled(bool enabled) +{ + m_enabled = enabled; +} diff --git a/libnymea/platform/repository.h b/libnymea/platform/repository.h new file mode 100644 index 00000000..f91825e9 --- /dev/null +++ b/libnymea/platform/repository.h @@ -0,0 +1,24 @@ +#ifndef REPOSITORY_H +#define REPOSITORY_H + +#include + +class Repository +{ +public: + Repository(); + Repository(const QString &id, const QString &displayName, bool enabled); + + QString id() const; + QString displayName() const; + + bool enabled() const; + void setEnabled(bool enabled); + +private: + QString m_id; + QString m_displayName; + bool m_enabled = false; +}; + +#endif // REPOSITORY_H diff --git a/server/main.cpp b/server/main.cpp index 5e68ac92..1633fc9a 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -103,6 +103,7 @@ int main(int argc, char *argv[]) "Application", "System", "Platform", + "PlatformUpdate", "DeviceManager", "RuleEngine", "RuleEngineDebug", diff --git a/tests/auto/api.json b/tests/auto/api.json index ac71eb7e..59a52349 100644 --- a/tests/auto/api.json +++ b/tests/auto/api.json @@ -867,6 +867,16 @@ "o:stateType": "$ref:StateType" } }, + "System.EnableRepository": { + "description": "Enable or disable a repository.", + "params": { + "enabled": "Bool", + "repositoryId": "String" + }, + "returns": { + "success": "Bool" + } + }, "System.GetCapabilities": { "description": "Get the list of capabilites on this system. This allows reading whether things like rebooting or shutting down the system running nymea:core is supported on this host.", "params": { @@ -876,17 +886,24 @@ "updateManagement": "Bool" } }, - "System.GetUpdateStatus": { - "description": "Get the current system status in regard to updates. That is, the currently installed version, any candidate version available etc.", + "System.GetPackages": { + "description": "Get the list of packages currently available to the system. This includes installed and available but not installed packages.", "params": { }, "returns": { - "availableChannels": "StringList", - "candidateVersion": "String", - "currentChannel": "String", - "currentVersion": "String", - "updateAvailable": "Bool", - "updateInProgress": "Bool" + "packages": [ + "$ref:Package" + ] + } + }, + "System.GetRepositories": { + "description": "Get the list of repositories currently available to the system.", + "params": { + }, + "returns": { + "repositories": [ + "$ref:Repository" + ] } }, "System.Reboot": { @@ -897,10 +914,23 @@ "success": "Bool" } }, - "System.SelectChannel": { - "description": "Select an update channel.", + "System.RemovePackages": { + "description": "Starts removing a package. Returns true if the removal has been started successfully.", "params": { - "channel": "String" + "packageIds": [ + "String" + ] + }, + "returns": { + "success": "Bool" + } + }, + "System.RollbackPackages": { + "description": "Starts a rollback. Returns true if the rollback has been started successfully.", + "params": { + "packageIds": [ + "String" + ] }, "returns": { "success": "Bool" @@ -914,9 +944,12 @@ "success": "Bool" } }, - "System.StartUpdate": { - "description": "Starts a system update. Returns true if the upgrade has been started successfully.", + "System.UpdatePackages": { + "description": "Starts updating/installing packages with the given ids. Returns true if the upgrade has been started successfully. Note that it might still fail later.", "params": { + "o:packageIds": [ + "String" + ] }, "returns": { "success": "Bool" @@ -1182,15 +1215,53 @@ "ruleId": "Uuid" } }, - "System.UpdateStatusChanged": { - "description": "Emitted whenever there is a change in the information from GetUpdateStatus", + "System.CapabilitiesChanged": { + "description": "Emitted whenever the system capabilities change.", "params": { - "availableChannels": "StringList", - "candidateVersion": "String", - "currentChannel": "String", - "currentVersion": "String", - "updateAvailable": "Bool", - "updateInProgress": "Bool" + "powerManagement": "Bool", + "updateManagement": "Bool" + } + }, + "System.PackageAdded": { + "description": "Emitted whenever a package is added to the list of packages.", + "params": { + "package": "$ref:Package" + } + }, + "System.PackageChanged": { + "description": "Emitted whenever a package in the list of packages changes.", + "params": { + "package": "$ref:Package" + } + }, + "System.PackageRemoved": { + "description": "Emitted whenever a package is removed from the list of packages.", + "params": { + "packageId": "String" + } + }, + "System.RepositoryAdded": { + "description": "Emitted whenever a repository is added to the list of repositories.", + "params": { + "repository": "$ref:Repository" + } + }, + "System.RepositoryChanged": { + "description": "Emitted whenever a repository in the list of repositories changes.", + "params": { + "repository": "$ref:Repository" + } + }, + "System.RepositoryRemoved": { + "description": "Emitted whenever a repository is removed from the list of repositories.", + "params": { + "repository": "String" + } + }, + "System.UpdateStatusChanged": { + "description": "Emitted whenever the update status changes.", + "params": { + "updateRunning": "Bool" } }, "Tags.TagAdded": { From 6324658f50d22dcfddf4da9440b1070a7325bdc1 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sat, 18 May 2019 01:11:08 +0200 Subject: [PATCH 10/17] fix recommends --- debian/control | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/control b/debian/control index ac5ba9b5..70b67873 100644 --- a/debian/control +++ b/debian/control @@ -69,7 +69,8 @@ Depends: libqt5network5, ${misc:Depends} Recommends: nymea-cli, network-manager, - nymea-platform-plugin-impl, + nymea-update-plugin-impl, + nymea-system-plugin-impl, Replaces: guhd Description: An open source IoT server - daemon The nymea daemon is a plugin based IoT (Internet of Things) server. The From 56f874d72100f7c48b4ecb6253db4ba97135d4a6 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sat, 18 May 2019 01:19:50 +0200 Subject: [PATCH 11/17] Add copyright headers --- libnymea/platform/package.cpp | 22 ++++++++++++++++++++++ libnymea/platform/package.h | 22 ++++++++++++++++++++++ libnymea/platform/repository.cpp | 22 ++++++++++++++++++++++ libnymea/platform/repository.h | 22 ++++++++++++++++++++++ 4 files changed, 88 insertions(+) diff --git a/libnymea/platform/package.cpp b/libnymea/platform/package.cpp index 982791ef..5b45cbfb 100644 --- a/libnymea/platform/package.cpp +++ b/libnymea/platform/package.cpp @@ -1,3 +1,25 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2019 Michael Zanetti * + * * + * This file is part of nymea. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; If not, see * + * . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + #include "package.h" Package::Package(const QString &packageId, const QString &displayName, const QString &installedVersion, const QString &candidateVersion, const QString &changelog): diff --git a/libnymea/platform/package.h b/libnymea/platform/package.h index 797faa2d..a4f693cc 100644 --- a/libnymea/platform/package.h +++ b/libnymea/platform/package.h @@ -1,3 +1,25 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2019 Michael Zanetti * + * * + * This file is part of nymea. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; If not, see * + * . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + #ifndef PACKAGE_H #define PACKAGE_H diff --git a/libnymea/platform/repository.cpp b/libnymea/platform/repository.cpp index 986b03ca..c3eeac53 100644 --- a/libnymea/platform/repository.cpp +++ b/libnymea/platform/repository.cpp @@ -1,3 +1,25 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2019 Michael Zanetti * + * * + * This file is part of nymea. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; If not, see * + * . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + #include "repository.h" Repository::Repository(const QString &id, const QString &displayName, bool enabled): diff --git a/libnymea/platform/repository.h b/libnymea/platform/repository.h index f91825e9..5ec2b86b 100644 --- a/libnymea/platform/repository.h +++ b/libnymea/platform/repository.h @@ -1,3 +1,25 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2019 Michael Zanetti * + * * + * This file is part of nymea. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; If not, see * + * . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + #ifndef REPOSITORY_H #define REPOSITORY_H From d8e49470385611930d8d8c569ad7532cec68cfb9 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sat, 18 May 2019 13:18:21 +0200 Subject: [PATCH 12/17] Add new json types to allTypes --- libnymea-core/jsonrpc/jsontypes.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libnymea-core/jsonrpc/jsontypes.cpp b/libnymea-core/jsonrpc/jsontypes.cpp index 39d1c21a..08b3ab6e 100644 --- a/libnymea-core/jsonrpc/jsontypes.cpp +++ b/libnymea-core/jsonrpc/jsontypes.cpp @@ -497,6 +497,8 @@ QVariantMap JsonTypes::allTypes() allTypes.insert("WebServerConfiguration", serverConfigurationDescription()); allTypes.insert("Tag", tagDescription()); allTypes.insert("MqttPolicy", mqttPolicyDescription()); + allTypes.insert("Package", packageDescription()); + allTypes.insert("Repository", repositoryDescription()); return allTypes; } From 5865ddb34112e4f6fe7c5c28dbccfdf6720486d4 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sat, 18 May 2019 13:34:56 +0200 Subject: [PATCH 13/17] Update json --- tests/auto/api.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/auto/api.json b/tests/auto/api.json index 59a52349..e3330909 100644 --- a/tests/auto/api.json +++ b/tests/auto/api.json @@ -1535,6 +1535,16 @@ "NetworkManagerStateConnectedSite", "NetworkManagerStateConnectedGlobal" ], + "Package": { + "canRemove": "Bool", + "candidateVersion": "String", + "changelog": "String", + "displayName": "String", + "id": "String", + "installedVersion": "String", + "rollbackAvailable": "Bool", + "updateAvailable": "Bool" + }, "Param": { "paramTypeId": "Uuid", "value": "$ref:BasicType" @@ -1590,6 +1600,11 @@ "Int" ] }, + "Repository": { + "displayName": "String", + "enabled": "Bool", + "id": "String" + }, "Rule": { "actions": [ "$ref:RuleAction" From 4539058e118fc77a69a6ca50647f8f2319d429ca Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sun, 19 May 2019 18:21:37 +0200 Subject: [PATCH 14/17] drop unused method --- libnymea/platform/platformupdatecontroller.cpp | 5 ----- libnymea/platform/platformupdatecontroller.h | 2 -- 2 files changed, 7 deletions(-) diff --git a/libnymea/platform/platformupdatecontroller.cpp b/libnymea/platform/platformupdatecontroller.cpp index 34ba4635..553ea2ec 100644 --- a/libnymea/platform/platformupdatecontroller.cpp +++ b/libnymea/platform/platformupdatecontroller.cpp @@ -51,11 +51,6 @@ QList PlatformUpdateController::repositories() const return {}; } -void PlatformUpdateController::checkForUpdates() -{ - // Nothing to do here -} - bool PlatformUpdateController::startUpdate(const QStringList &packageIds) { Q_UNUSED(packageIds) diff --git a/libnymea/platform/platformupdatecontroller.h b/libnymea/platform/platformupdatecontroller.h index cfcac33e..8dc5fdc5 100644 --- a/libnymea/platform/platformupdatecontroller.h +++ b/libnymea/platform/platformupdatecontroller.h @@ -42,8 +42,6 @@ public: virtual QList packages() const; virtual QList repositories() const; - virtual void checkForUpdates(); - virtual bool startUpdate(const QStringList &packageIds = QStringList()); virtual bool rollback(const QStringList &packageIds); virtual bool removePackages(const QStringList &packageIds); From a8092d6faf34066891cf16ba1f5cfca80c85cc44 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sun, 19 May 2019 22:14:55 +0200 Subject: [PATCH 15/17] little cleanup --- libnymea-core/platform/platform.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libnymea-core/platform/platform.cpp b/libnymea-core/platform/platform.cpp index 445913a3..4a5c8b05 100644 --- a/libnymea-core/platform/platform.cpp +++ b/libnymea-core/platform/platform.cpp @@ -36,9 +36,8 @@ Platform::Platform(QObject *parent) : QObject(parent) { foreach (const QString &path, pluginSearchDirs()) { QDir dir(path); - qCDebug(dcPlatform) << "Loading plugins from:" << dir.absolutePath(); + qCDebug(dcPlatform) << "Loading platform plugins from:" << dir.absolutePath(); foreach (const QString &entry, dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot)) { - qCDebug(dcPlatform()) << "Found dir entry" << entry; QFileInfo fi(path + "/" + entry); if (fi.isFile()) { if (entry.startsWith("libnymea_systemplugin") && entry.endsWith(".so")) { @@ -49,8 +48,8 @@ Platform::Platform(QObject *parent) : QObject(parent) } else if (fi.isDir()) { if (QFileInfo::exists(path + "/" + entry + "/libnymea_systemplugin" + entry + ".so")) { loadSystemPlugin(path + "/" + entry + "/libnymea_systemplugin" + entry + ".so"); - } else if (QFileInfo::exists(path + "/" + entry + "/libnymea_platformplugin" + entry + ".so")) { - loadUpdatePlugin(path + "/" + entry + "/libnymea_platformplugin" + entry + ".so"); + } else if (QFileInfo::exists(path + "/" + entry + "/libnymea_updateplugin" + entry + ".so")) { + loadUpdatePlugin(path + "/" + entry + "/libnymea_updateplugin" + entry + ".so"); } } } From 2e2e86d68a77c6df8082e628ed6cfaebe88199e7 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Mon, 20 May 2019 22:23:46 +0200 Subject: [PATCH 16/17] Documentation and finetuning --- debian/control | 2 +- libnymea-core/jsonrpc/jsonrpcserver.cpp | 3 +- libnymea-core/jsonrpc/jsontypes.cpp | 2 + libnymea-core/jsonrpc/logginghandler.cpp | 4 - libnymea-core/jsonrpc/systemhandler.cpp | 62 +++++++++++- libnymea-core/jsonrpc/systemhandler.h | 1 + libnymea/platform/package.cpp | 11 +++ libnymea/platform/package.h | 5 + .../platform/platformupdatecontroller.cpp | 94 ++++++++++++++++++- libnymea/platform/platformupdatecontroller.h | 5 +- tests/auto/api.json | 27 +++++- 11 files changed, 197 insertions(+), 19 deletions(-) diff --git a/debian/control b/debian/control index 70b67873..617d1184 100644 --- a/debian/control +++ b/debian/control @@ -133,7 +133,7 @@ Description: Translation files for nymead and plugins - translations Package: nymea-tests -Section: misc +Section: devel Architecture: any Multi-Arch: same Depends: nymea (= ${binary:Version}), diff --git a/libnymea-core/jsonrpc/jsonrpcserver.cpp b/libnymea-core/jsonrpc/jsonrpcserver.cpp index 5745e27b..1bea5280 100644 --- a/libnymea-core/jsonrpc/jsonrpcserver.cpp +++ b/libnymea-core/jsonrpc/jsonrpcserver.cpp @@ -687,7 +687,8 @@ void JsonRPCServer::sendNotification(const QVariantMap ¶ms) Q_ASSERT_X(handler->validateParams(method.name(), params).first, "validating return value", formatAssertion(handler->name(), method.name(), QMetaMethod::Signal, handler, notification).toLatin1().data()); QByteArray data = QJsonDocument::fromVariant(notification).toJson(QJsonDocument::Compact); - qCDebug(dcJsonRpcTraffic()) << "Sending notification:" << data; + qCDebug(dcJsonRpc()) << "Sending notification:" << handler->name() + "." + method.name(); + qCDebug(dcJsonRpcTraffic()) << "Notification content:" << data; foreach (const QUuid &clientId, m_clientNotifications.keys(true)) { m_clientTransports.value(clientId)->sendData(clientId, data); diff --git a/libnymea-core/jsonrpc/jsontypes.cpp b/libnymea-core/jsonrpc/jsontypes.cpp index 08b3ab6e..e7de6f8b 100644 --- a/libnymea-core/jsonrpc/jsontypes.cpp +++ b/libnymea-core/jsonrpc/jsontypes.cpp @@ -404,6 +404,7 @@ void JsonTypes::init() s_package.insert("id", basicTypeToString(QVariant::String)); s_package.insert("displayName", basicTypeToString(QVariant::String)); + s_package.insert("summary", basicTypeToString(QVariant::String)); s_package.insert("installedVersion", basicTypeToString(QVariant::String)); s_package.insert("candidateVersion", basicTypeToString(QVariant::String)); s_package.insert("changelog", basicTypeToString(QVariant::String)); @@ -1290,6 +1291,7 @@ QVariantMap JsonTypes::packPackage(const Package &package) QVariantMap ret; ret.insert("id", package.packageId()); ret.insert("displayName", package.displayName()); + ret.insert("summary", package.summary()); ret.insert("installedVersion", package.installedVersion()); ret.insert("candidateVersion", package.candidateVersion()); ret.insert("changelog", package.changelog()); diff --git a/libnymea-core/jsonrpc/logginghandler.cpp b/libnymea-core/jsonrpc/logginghandler.cpp index c50c6e61..abbeaadf 100644 --- a/libnymea-core/jsonrpc/logginghandler.cpp +++ b/libnymea-core/jsonrpc/logginghandler.cpp @@ -118,7 +118,6 @@ QString LoggingHandler::name() const void LoggingHandler::logEntryAdded(const LogEntry &logEntry) { - qCDebug(dcJsonRpc) << "Notify \"Logging.LogEntryAdded\""; QVariantMap params; params.insert("logEntry", JsonTypes::packLogEntry(logEntry)); emit LogEntryAdded(params); @@ -126,14 +125,11 @@ void LoggingHandler::logEntryAdded(const LogEntry &logEntry) void LoggingHandler::logDatabaseUpdated() { - qCDebug(dcJsonRpc) << "Notify \"Logging.LogDatabaseUpdated\""; emit LogDatabaseUpdated(QVariantMap()); } JsonReply* LoggingHandler::GetLogEntries(const QVariantMap ¶ms) const { - qCDebug(dcJsonRpc) << "Asked for log entries" << params; - LogFilter filter = JsonTypes::unpackLogFilter(params); QVariantList entries; diff --git a/libnymea-core/jsonrpc/systemhandler.cpp b/libnymea-core/jsonrpc/systemhandler.cpp index 23b184a6..40c7e280 100644 --- a/libnymea-core/jsonrpc/systemhandler.cpp +++ b/libnymea-core/jsonrpc/systemhandler.cpp @@ -53,27 +53,63 @@ SystemHandler::SystemHandler(Platform *platform, QObject *parent): setReturns("Shutdown", returns); params.clear(); returns.clear(); - setDescription("GetPackages", "Get the list of packages currently available to the system. This includes installed and available but not installed packages."); + setDescription("GetUpdateStatus", + "Get the current status of the update system. \"busy\" indicates that the system is current busy with " + "an operation regarding updates. This does not necessarily mean an actual update is running. When this " + "is true, update related functions on the client should be marked as busy and no interaction with update " + "components shall be allowed. An example for such a state is when the system queries the server if there " + "are updates available, typically after a call to CheckForUpdates. \"updateRunning\" on the other hand " + "indicates an actual update process is ongoing. The user should be informed about it, the system also " + "might restart at any point while an update is running."); + setParams("GetUpdateStatus", params); + returns.insert("busy", JsonTypes::basicTypeToString(JsonTypes::Bool)); + returns.insert("updateRunning", JsonTypes::basicTypeToString(JsonTypes::Bool)); + setReturns("GetUpdateStatus", returns); + + params.clear(); returns.clear(); + setDescription("CheckForUpdates", + "Instruct the system to poll the server for updates. Normally the system should automatically do this " + "in regular intervals, however, if the client wants to allow the user to manually check for new updates " + "now, this can be called. Returns true if the operation has been started successfully and the update " + "manager will become busy. In order to know whether there are updates available, clients should walk through " + "the list of packages retrieved from GetPackages and check whether there are packages with the updateAvailable " + "flag set to true."); + setParams("CheckForUpdates", params); + returns.insert("success", JsonTypes::basicTypeToString(JsonTypes::Bool)); + setReturns("CheckForUpdates", returns); + + params.clear(); returns.clear(); + setDescription("GetPackages", + "Get the list of packages currently available to the system. This might include installed available but " + "not installed packages. Installed packages will have the installedVersion set to a non-empty value."); setParams("GetPackages", params); returns.insert("packages", QVariantList() << JsonTypes::packageRef()); setReturns("GetPackages", returns); params.clear(); returns.clear(); - setDescription("UpdatePackages", "Starts updating/installing packages with the given ids. Returns true if the upgrade has been started successfully. Note that it might still fail later."); + setDescription("UpdatePackages", + "Starts updating/installing packages with the given ids. Returns true if the upgrade has been started " + "successfully. Note that it might still fail later. Before calling this method, clients should " + "check the packages whether they are in a state where they can either be installed (no installedVersion " + "set) or upgraded (updateAvailable set to true)."); params.insert("o:packageIds", QVariantList() << JsonTypes::basicTypeToString(JsonTypes::String)); setParams("UpdatePackages", params); returns.insert("success", JsonTypes::basicTypeToString(JsonTypes::Bool)); setReturns("UpdatePackages", returns); params.clear(); returns.clear(); - setDescription("RollbackPackages", "Starts a rollback. Returns true if the rollback has been started successfully."); + setDescription("RollbackPackages", + "Starts a rollback. Returns true if the rollback has been started successfully. Before calling this " + "method, clients should check whether the package can be rolled back (canRollback set to true)."); params.insert("packageIds", QVariantList() << JsonTypes::basicTypeToString(JsonTypes::String)); setParams("RollbackPackages", params); returns.insert("success", JsonTypes::basicTypeToString(JsonTypes::Bool)); setReturns("RollbackPackages", returns); params.clear(); returns.clear(); - setDescription("RemovePackages", "Starts removing a package. Returns true if the removal has been started successfully."); + setDescription("RemovePackages", + "Starts removing a package. Returns true if the removal has been started successfully. Before calling " + "this method, clients should check whether the package can be removed (canRemove set to true)."); params.insert("packageIds", QVariantList() << JsonTypes::basicTypeToString(JsonTypes::String)); setParams("RemovePackages", params); returns.insert("success", JsonTypes::basicTypeToString(JsonTypes::Bool)); @@ -103,6 +139,7 @@ SystemHandler::SystemHandler(Platform *platform, QObject *parent): params.clear(); setDescription("UpdateStatusChanged", "Emitted whenever the update status changes."); + params.insert("busy", JsonTypes::basicTypeToString(JsonTypes::Bool)); params.insert("updateRunning", JsonTypes::basicTypeToString(JsonTypes::Bool)); setParams("UpdateStatusChanged", params); @@ -139,8 +176,15 @@ SystemHandler::SystemHandler(Platform *platform, QObject *parent): connect(m_platform->systemController(), &PlatformSystemController::availableChanged, this, &SystemHandler::onCapabilitiesChanged); connect(m_platform->updateController(), &PlatformUpdateController::availableChanged, this, &SystemHandler::onCapabilitiesChanged); + connect(m_platform->updateController(), &PlatformUpdateController::busyChanged, this, [this](){ + QVariantMap params; + params.insert("busy", m_platform->updateController()->busy()); + params.insert("updateRunning", m_platform->updateController()->updateRunning()); + emit UpdateStatusChanged(params); + }); connect(m_platform->updateController(), &PlatformUpdateController::updateRunningChanged, this, [this](){ QVariantMap params; + params.insert("busy", m_platform->updateController()->busy()); params.insert("updateRunning", m_platform->updateController()->updateRunning()); emit UpdateStatusChanged(params); }); @@ -212,10 +256,20 @@ JsonReply *SystemHandler::GetUpdateStatus(const QVariantMap ¶ms) const { Q_UNUSED(params) QVariantMap ret; + ret.insert("busy", m_platform->updateController()->updateRunning()); ret.insert("updateRunning", m_platform->updateController()->updateRunning()); return createReply(ret); } +JsonReply *SystemHandler::CheckForUpdates(const QVariantMap ¶ms) const +{ + Q_UNUSED(params) + QVariantMap ret; + bool success = m_platform->updateController()->checkForUpdates(); + ret.insert("success", success); + return createReply(ret); +} + JsonReply *SystemHandler::GetPackages(const QVariantMap ¶ms) const { Q_UNUSED(params) diff --git a/libnymea-core/jsonrpc/systemhandler.h b/libnymea-core/jsonrpc/systemhandler.h index 727d4465..36dc09df 100644 --- a/libnymea-core/jsonrpc/systemhandler.h +++ b/libnymea-core/jsonrpc/systemhandler.h @@ -43,6 +43,7 @@ public: Q_INVOKABLE JsonReply *Shutdown(const QVariantMap ¶ms) const; Q_INVOKABLE JsonReply *GetUpdateStatus(const QVariantMap ¶ms) const; + Q_INVOKABLE JsonReply *CheckForUpdates(const QVariantMap ¶ms) const; Q_INVOKABLE JsonReply *GetPackages(const QVariantMap ¶ms) const; Q_INVOKABLE JsonReply *UpdatePackages(const QVariantMap ¶ms) const; Q_INVOKABLE JsonReply *RollbackPackages(const QVariantMap ¶ms) const; diff --git a/libnymea/platform/package.cpp b/libnymea/platform/package.cpp index 5b45cbfb..195205ec 100644 --- a/libnymea/platform/package.cpp +++ b/libnymea/platform/package.cpp @@ -42,6 +42,16 @@ QString Package::displayName() const return m_displayName; } +QString Package::summary() const +{ + return m_summary; +} + +void Package::setSummary(const QString &summary) +{ + m_summary = summary; +} + QString Package::installedVersion() const { return m_installedVersion; @@ -106,6 +116,7 @@ bool Package::operator==(const Package &other) const { return m_packageId == other.packageId() && m_displayName == other.displayName() && + m_summary == other.summary() && m_installedVersion == other.installedVersion() && m_candidateVersion == other.candidateVersion() && m_changeLog == other.changelog() && diff --git a/libnymea/platform/package.h b/libnymea/platform/package.h index a4f693cc..a0c90ab1 100644 --- a/libnymea/platform/package.h +++ b/libnymea/platform/package.h @@ -32,6 +32,10 @@ public: QString packageId() const; QString displayName() const; + + QString summary() const; + void setSummary(const QString &summary); + QString installedVersion() const; void setInstalledVersion(const QString &installedVersion); @@ -56,6 +60,7 @@ public: private: QString m_packageId; QString m_displayName; + QString m_summary; QString m_installedVersion; QString m_candidateVersion; QString m_changeLog; diff --git a/libnymea/platform/platformupdatecontroller.cpp b/libnymea/platform/platformupdatecontroller.cpp index 553ea2ec..00c997cc 100644 --- a/libnymea/platform/platformupdatecontroller.cpp +++ b/libnymea/platform/platformupdatecontroller.cpp @@ -27,48 +27,134 @@ PlatformUpdateController::PlatformUpdateController(QObject *parent) : QObject(pa } -/*! Override this to indicate whether update management is available. Defaults to false. - When a plugin returns true here, it is assumed that the system is capable of updating and nymea - has permissions to do so. +/*! Whether or not the update management is available. Returns true if the system is ready + to perform any upgrade tasks. When the return value is true, it is assumed that the + system is capable of updating and nymea has permissions to do so. + + A backend plugin should override this to indicate whether update management is available. Defaults to false. + If the update mechanism becomes available during runtime, \l{availableChanged()} should be emitted + to indicate the change. */ -bool PlatformUpdateController::updateManagementAvailable() +bool PlatformUpdateController::updateManagementAvailable() const { return false; } +/*! Triggers a cache update on the update system, e.g. call "apt-get update" on the system. + + A backend plugin may override this to to allow the system triggering package manager cache updates. + */ +bool PlatformUpdateController::checkForUpdates() +{ + return false; +} + +/*! Indicates whether the update system is busy. This might be the case when \l{checkForUpdates()} or + \l{enableRepository()} are called. In general, this indicates a state where the update system + is working and might not be ready to take additional requests. Clients should not perform any operations + on the upgrade system while this is true. + + A backend plugin may override this and return true when appropriate. For instance if \l{checkForUpdates()} + is a long-running task and the client should be informed about it being worked on. Additionally, + whenever the value changes \l{busyChanged()} should be emitted. + */ +bool PlatformUpdateController::busy() const +{ + return false; +} + +/*! Indicates whether an update is running. While this is true, clients should not perform + any operations on the upgrade system and in general expect the system to go down for + restart any moment. This flag can be used by clients to indicate the running update + and may restrict interaction with the system. + + A backend plugin should override this and return true when an update is running. Additionally. + whenever the value changes, \l{updateRunningChanged()} should be emitted. + */ bool PlatformUpdateController::updateRunning() const { return false; } +/*! Returns a list of packages availabe in the system. If a backend supports installation of new packages, + the list of packages may contain not installed packages. Such packages are marked by + returning an empty \l{Package::installedVersion()}. If the backend supports removal + of installed packages, uninstallable packages are marked with \l{Package::canRemove()}. + Packages that can be updated or rolled back will be marked with \l{Package::updateAvailable()} + and \l{Package::rollbackAvailable()}. + + A backend plugin should override this and return the list of all packages available in the system + filling in \l{Package} details as described above. + + */ QList PlatformUpdateController::packages() const { return {}; } +/*! Returns a list of all optional repositories available in the system. Such repositories + can be enabled or disabled in order to follow prereleases. + + A backend plugin may override this if enabling different repositories is supported. + */ QList PlatformUpdateController::repositories() const { return {}; } +/*! Starts upgrading the packages with the given \a packageIds. If \a packageIds is an empty + list, a full system upgrade will be performed. Use \l {Package::updateAvailable()} + to find packages with available upgrades. Passing packageIds for packages which are not + installed at this time will install the packages, provided the backend supports package + installation. If \l{canInstallPackages()} is false, only installed packages should + be provided for upgrades. The return value indicates whether the update has been started or not. + + A backend plugin should override this and start the system upgrades indicating success in + the return value. Additionally, once the update procedure has started, it should emit + \l {updateRunningChanged()} and \l {updateRunning()} should return true. + */ bool PlatformUpdateController::startUpdate(const QStringList &packageIds) { Q_UNUSED(packageIds) return false; } +/*! Starts a rollback of the packages with the given \a packageIds. Use \l {Package::rollbackAvailable()} + to find packages with available rollbacks. + + A backend plugin should override this and start the rollback process indicating success in + the return value. Once the rollback procedure has started, it should emit + \l {updateRunningChanged()} and \l {updateRunning()} should return true. + */ bool PlatformUpdateController::rollback(const QStringList &packageIds) { Q_UNUSED(packageIds) return false; } +/*! Starts the removal of the packages with the given \a packageIds. Use \l {Package::installedVersion()} + to find packages which are currently installed. Check \l{Package::canRemove()} to see whether a package + can be removed or not. + + A backend plugin should override this and start the removal process indicating success in + the return value. Once the removal procedure has started, it should emit + \l {updateRunningChanged()} and \l {updateRunning()} should return true. + */ bool PlatformUpdateController::removePackages(const QStringList &packageIds) { Q_UNUSED(packageIds) return false; } +/*! Enables or disables the given \l{Repository} in the system. The return value indicates whether + the request has been started successfully or not. Upon successful completion of the request, + \l{repositoryChanged()} signals should be emitted. + + A backend plugin should override this if multiple install repositories are supported (e.g. if + \l{repositories()} returns a non-empty list) and perform the requested operation. If enabling/disabling + a repository implies the immediate upgrade/downgrade of packages, \l{updateRunning()} should be + marked accordingly. + */ bool PlatformUpdateController::enableRepository(const QString &repositoryId, bool enabled) { Q_UNUSED(repositoryId) diff --git a/libnymea/platform/platformupdatecontroller.h b/libnymea/platform/platformupdatecontroller.h index 8dc5fdc5..d63a1622 100644 --- a/libnymea/platform/platformupdatecontroller.h +++ b/libnymea/platform/platformupdatecontroller.h @@ -35,8 +35,10 @@ public: explicit PlatformUpdateController(QObject *parent = nullptr); virtual ~PlatformUpdateController() = default; - virtual bool updateManagementAvailable(); + virtual bool updateManagementAvailable() const; + virtual bool checkForUpdates(); + virtual bool busy() const; virtual bool updateRunning() const; virtual QList packages() const; @@ -50,6 +52,7 @@ public: signals: void availableChanged(); + void busyChanged(); void updateRunningChanged(); void packageAdded(const Package &pacakge); void packageChanged(const Package &package); diff --git a/tests/auto/api.json b/tests/auto/api.json index e3330909..cc69dfdc 100644 --- a/tests/auto/api.json +++ b/tests/auto/api.json @@ -867,6 +867,14 @@ "o:stateType": "$ref:StateType" } }, + "System.CheckForUpdates": { + "description": "Instruct the system to poll the server for updates. Normally the system should automatically do this in regular intervals, however, if the client wants to allow the user to manually check for new updates now, this can be called. Returns true if the operation has been started successfully and the update manager will become busy. In order to know whether there are updates available, clients should walk through the list of packages retrieved from GetPackages and check whether there are packages with the updateAvailable flag set to true.", + "params": { + }, + "returns": { + "success": "Bool" + } + }, "System.EnableRepository": { "description": "Enable or disable a repository.", "params": { @@ -887,7 +895,7 @@ } }, "System.GetPackages": { - "description": "Get the list of packages currently available to the system. This includes installed and available but not installed packages.", + "description": "Get the list of packages currently available to the system. This might include installed available but not installed packages. Installed packages will have the installedVersion set to a non-empty value.", "params": { }, "returns": { @@ -906,6 +914,15 @@ ] } }, + "System.GetUpdateStatus": { + "description": "Get the current status of the update system. \"busy\" indicates that the system is current busy with an operation regarding updates. This does not necessarily mean an actual update is running. When this is true, update related functions on the client should be marked as busy and no interaction with update components shall be allowed. An example for such a state is when the system queries the server if there are updates available, typically after a call to CheckForUpdates. \"updateRunning\" on the other hand indicates an actual update process is ongoing. The user should be informed about it, the system also might restart at any point while an update is running.", + "params": { + }, + "returns": { + "busy": "Bool", + "updateRunning": "Bool" + } + }, "System.Reboot": { "description": "Initiate a reboot of the system. The return value will indicate whether the procedure has been initiated successfully.", "params": { @@ -915,7 +932,7 @@ } }, "System.RemovePackages": { - "description": "Starts removing a package. Returns true if the removal has been started successfully.", + "description": "Starts removing a package. Returns true if the removal has been started successfully. Before calling this method, clients should check whether the package can be removed (canRemove set to true).", "params": { "packageIds": [ "String" @@ -926,7 +943,7 @@ } }, "System.RollbackPackages": { - "description": "Starts a rollback. Returns true if the rollback has been started successfully.", + "description": "Starts a rollback. Returns true if the rollback has been started successfully. Before calling this method, clients should check whether the package can be rolled back (canRollback set to true).", "params": { "packageIds": [ "String" @@ -945,7 +962,7 @@ } }, "System.UpdatePackages": { - "description": "Starts updating/installing packages with the given ids. Returns true if the upgrade has been started successfully. Note that it might still fail later.", + "description": "Starts updating/installing packages with the given ids. Returns true if the upgrade has been started successfully. Note that it might still fail later. Before calling this method, clients should check the packages whether they are in a state where they can either be installed (no installedVersion set) or upgraded (updateAvailable set to true).", "params": { "o:packageIds": [ "String" @@ -1261,6 +1278,7 @@ "System.UpdateStatusChanged": { "description": "Emitted whenever the update status changes.", "params": { + "busy": "Bool", "updateRunning": "Bool" } }, @@ -1543,6 +1561,7 @@ "id": "String", "installedVersion": "String", "rollbackAvailable": "Bool", + "summary": "String", "updateAvailable": "Bool" }, "Param": { From 11efbdd1a8dcb17efdeb3a1e5e6dceefe451ed0c Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Wed, 22 May 2019 00:35:35 +0200 Subject: [PATCH 17/17] fix repositoryRemoved notification --- libnymea-core/jsonrpc/systemhandler.cpp | 2 +- tests/auto/api.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libnymea-core/jsonrpc/systemhandler.cpp b/libnymea-core/jsonrpc/systemhandler.cpp index 40c7e280..3b16c84a 100644 --- a/libnymea-core/jsonrpc/systemhandler.cpp +++ b/libnymea-core/jsonrpc/systemhandler.cpp @@ -170,7 +170,7 @@ SystemHandler::SystemHandler(Platform *platform, QObject *parent): params.clear(); setDescription("RepositoryRemoved", "Emitted whenever a repository is removed from the list of repositories."); - params.insert("repository", JsonTypes::basicTypeToString(JsonTypes::String)); + params.insert("repositoryId", JsonTypes::basicTypeToString(JsonTypes::String)); setParams("RepositoryRemoved", params); diff --git a/tests/auto/api.json b/tests/auto/api.json index cc69dfdc..1a8639c6 100644 --- a/tests/auto/api.json +++ b/tests/auto/api.json @@ -1272,7 +1272,7 @@ "System.RepositoryRemoved": { "description": "Emitted whenever a repository is removed from the list of repositories.", "params": { - "repository": "String" + "repositoryId": "String" } }, "System.UpdateStatusChanged": {