Browse Source

Embedded : Add systemd settings

This allows to add Settings to enable / disable systemd settings for LIRC, SAMBA and SSH services.
All of these are disabled by default since LE 8.2 :
- LIRC : kernel should now handle most remotes, just need to enable it if remote is not supported by kernel
- SAMBA and SSH : they are disable by default for security reasons, so we need settings to enable them.
LongChair 7 years ago
parent
commit
db3690e616

+ 19 - 3
resources/settings/settings_description.json

@@ -491,12 +491,28 @@
     "values": []
   },
   {
-    "section": "openelec",
-    "hidden": true,
+    "section": "system",
     "values": [
         {
           "value": "systemname",
-          "default": "PlexMediaPlayer"
+          "default": "PlexMediaPlayer",
+          "hidden": true,
+          "platforms": [ "oe" ]
+        },
+        {
+          "value": "lircd_enabled",
+          "default": false,
+          "platforms": [ "oe" ]
+        },
+        {
+          "value": "smbd_enabled",
+          "default": false,
+          "platforms": [ "oe" ]
+        },
+        {
+          "value": "sshd_enabled",
+          "default": false,
+          "platforms": [ "oe" ]
         }
     ]
   },

+ 1 - 1
src/settings/SettingsComponent.h

@@ -9,13 +9,13 @@
 #define SETTINGS_SECTION_AUDIO "audio"
 #define SETTINGS_SECTION_VIDEO "video"
 #define SETTINGS_SECTION_MAIN "main"
+#define SETTINGS_SECTION_SYSTEM "system"
 #define SETTINGS_SECTION_STATE "state"
 #define SETTINGS_SECTION_PATH "path"
 #define SETTINGS_SECTION_WEBCLIENT "webclient"
 #define SETTINGS_SECTION_SUBTITLES "subtitles"
 #define SETTINGS_SECTION_OVERRIDES "overrides"
 #define SETTINGS_SECTION_CEC "cec"
-#define SETTINGS_SECTION_OPENELEC "openelec"
 #define SETTINGS_SECTION_APPLEREMOTE "appleremote"
 
 #define AUDIO_DEVICE_TYPE_BASIC "basic"

+ 34 - 1
src/system/openelec/OESystemComponent.cpp

@@ -1,9 +1,17 @@
 #include "settings/SettingsComponent.h"
+#include "settings/SettingsSection.h"
 #include "OESystemComponent.h"
+#include "SystemdManager.h"
 #include "QsLog.h"
 #include <unistd.h>
 #include <QFile>
 
+QMap<QString, SystemdService> services = {
+     { "samba" , SystemdService("smbd", "samba") },
+     { "lirc" ,  SystemdService("lircd", "lircd") },
+     { "ssh" ,  SystemdService("sshd", "sshd") }
+};
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 OESystemComponent::OESystemComponent(QObject *parent) : ComponentBase(parent)
 {
@@ -13,11 +21,36 @@ OESystemComponent::OESystemComponent(QObject *parent) : ComponentBase(parent)
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 bool OESystemComponent::componentInitialize()
 {
-  setHostName(SettingsComponent::Get().value(SETTINGS_SECTION_OPENELEC, "systemname").toString());
 
+  connect(SettingsComponent::Get().getSection(SETTINGS_SECTION_SYSTEM), &SettingsSection::valuesUpdated,
+            this, &OESystemComponent::updateSectionSettings);
+
+  setHostName(SettingsComponent::Get().value(SETTINGS_SECTION_SYSTEM, "systemname").toString());
+
+  foreach(QString service, services.keys())
+  {
+    bool Enabled = SystemdManager::isEnabled(services[service]);
+    QLOG_ERROR() << "Service " << services[service].Name << " enabled :" << Enabled;
+    SettingsComponent::Get().setValue(SETTINGS_SECTION_SYSTEM,
+                                      services[service].Name + "_enabled",
+                                      Enabled);
+  }
   return true;
 }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+void OESystemComponent::updateSectionSettings(const QVariantMap& values)
+{
+    foreach(QString service, services.keys())
+    {
+        QString keyName = services[service].Name + "_enabled";
+        if (values.contains(keyName))
+        {
+            SystemdManager::enable(services[service], values[keyName].toBool());
+        }
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 bool OESystemComponent::setHostName(QString name)
 {

+ 1 - 0
src/system/openelec/OESystemComponent.h

@@ -17,6 +17,7 @@ public:
   virtual const char* componentName() { return "oesystem"; }
   virtual bool componentInitialize();
 
+  void updateSectionSettings(const QVariantMap& values);
   bool setHostName(QString name);
 };
 

+ 63 - 0
src/system/openelec/SystemdManager.cpp

@@ -0,0 +1,63 @@
+#include <QProcess>
+
+#include "QsLog.h"
+#include "SystemdManager.h"
+
+#define CACHE_DIR "/storage/.cache/services/"
+#define TEMPLATE_DIR "/usr/share/services/"
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+bool SystemdManager::isEnabled(SystemdService &Service)
+{
+    return QFile::exists(CACHE_DIR + Service.ConfigFile + ".conf");
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+bool SystemdManager::enable(SystemdService &Service, bool enable)
+{
+    QFile onFile(CACHE_DIR + Service.ConfigFile + ".conf");
+    QFile offFile(CACHE_DIR + Service.ConfigFile + ".disabled");
+    QFile templateFile(TEMPLATE_DIR + Service.ConfigFile + ".conf");
+
+    QLOG_INFO() << "Setting service" << Service.Name << "to enable state :" << enable;
+
+    if (!onFile.exists() && !offFile.exists())
+    {
+        // we take the template file and copy it over
+        if(!templateFile.copy(enable ? onFile.fileName() : offFile.fileName()))
+        {
+            QLOG_ERROR() << "Failed to copy template file for service " << Service.Name;
+            return false;
+        }
+    }
+
+    bool rename = false;
+    if (onFile.exists() && !enable)
+    {
+       rename = onFile.rename(offFile.fileName());
+    }
+
+    if (offFile.exists() && enable)
+    {
+       rename = offFile.rename(onFile.fileName());
+    }
+
+    if (rename)
+    {
+        QProcess p;
+        p.start("systemctl", QStringList() << "restart" << Service.Name);
+
+        if (p.waitForFinished(1000))
+        {
+            return true;
+        }
+        else
+        {
+            QLOG_ERROR() << "Failed to restart service " << Service.Name;
+            return false;
+        }
+    }
+
+    return false;
+}
+

+ 26 - 0
src/system/openelec/SystemdManager.h

@@ -0,0 +1,26 @@
+#ifndef SYSTEMDMANAGER_H
+#define SYSTEMDMANAGER_H
+#include <QObject>
+
+class SystemdService
+{
+  public:
+    SystemdService() {};
+    SystemdService(QString name, QString configfile) : Name(name), ConfigFile(configfile) {};
+    QString Name;
+    QString ConfigFile;
+
+};
+
+class SystemdManager : public QObject
+{
+  Q_OBJECT
+public:
+    explicit SystemdManager(QObject *parent = nullptr) {};
+    ~SystemdManager() override {};
+
+    static bool isEnabled(SystemdService &Service);
+    static bool enable(SystemdService &Service, bool enable);
+
+};
+#endif // SYSTEMDMANAGER_H