Browse Source

Several bugs fixed

Now detects permission problems and notify it.
Added option to pass config file as argument.
Óscar García Amor 4 years ago
parent
commit
7459e5bcf9

+ 14 - 8
sysdweb/config.py

@@ -9,18 +9,24 @@
 import configparser
 import os
 
-def checkConfig():
+def checkConfig(file=None):
     """
     Parse config and discards errors
     """
-    config_files = [ './sysdweb.conf',
-            os.path.join(os.path.expanduser('~'), '.config/sysdweb/sysdweb.conf'),
-            '/etc/sysdweb.conf' ]
+    if file != None:
+        if os.access(file, os.R_OK):
+            config_file = [file]
+        else:
+            raise SystemExit('Cannot read config file \'{}\'.'.format(file))
+    else:
+        config_files = [ './sysdweb.conf',
+                os.path.join(os.path.expanduser('~'), '.config/sysdweb/sysdweb.conf'),
+                '/etc/sysdweb.conf' ]
+        # Try to load one of config locations
+        config_file = [file for file in config_files if os.access(file, os.R_OK)]
+        if config_file == []:
+            raise SystemExit('No config file found.')
 
-    # Try to load one of config locations
-    config_file = [file for file in config_files if os.access(file, os.R_OK)]
-    if config_file == []:
-        raise SystemExit('No config file found.')
     config = configparser.ConfigParser()
     try:
         config.read(config_file[0])

+ 5 - 4
sysdweb/main.py

@@ -6,14 +6,15 @@
 #
 # Distributed under terms of the GNU GPLv3 license.
 
-from sysdweb.server import run
+from sysdweb.server import start
 
 import argparse
 
 def main():
     parser = argparse.ArgumentParser()
-    parser.add_argument('-l', '--listen', metavar='host or ip', default='127.0.0.1', help='listen address, default: 127.0.0.1')
-    parser.add_argument('-p', '--port', metavar='port', default='10080', help='listen port, default: 10080')
+    parser.add_argument('-c', '--config', metavar='value', default=None, help='Custom configuration file path')
+    parser.add_argument('-l', '--listen', metavar='value', default='127.0.0.1', help='listen address (host or ip), default: 127.0.0.1')
+    parser.add_argument('-p', '--port', metavar='value', default='10080', help='listen port, default: 10080')
     args = parser.parse_args()
 
-    run(host=args.listen, port=args.port)
+    start (args.config, args.listen, args.port)

+ 17 - 15
sysdweb/server.py

@@ -23,38 +23,32 @@ if template_path == []:
 TEMPLATE_PATH.insert(0, os.path.join(template_path[0], 'views'))
 static_path = os.path.join(template_path[0], 'static')
 
-# Check config
-config = checkConfig()
-
 @route('/api/v1/<service>/<action>')
 def get_service_action(service, action):
     if service in config.sections():
         sdbus = systemdBus(True) if config.get('DEFAULT', 'scope', fallback='system') == 'user' else systemdBus()
         unit = config.get(service, 'unit')
         if action == 'start':
-            sdbus.start_unit(unit)
-            return {action: 'OK'}
+            return {action: 'OK'} if sdbus.start_unit(unit) else {action: 'Fail'}
         elif action == 'stop':
-            sdbus.stop_unit(unit)
-            return {action: 'OK'}
+            return {action: 'OK'} if sdbus.stop_unit(unit) else {action: 'Fail'}
         elif action == 'restart':
-            sdbus.restart_unit(unit)
-            return {action: 'OK'}
+            return {action: 'OK'} if sdbus.restart_unit(unit) else {action: 'Fail'}
         elif action == 'reload':
-            sdbus.reload_unit(unit)
-            return {action: 'OK'}
+            return {action: 'OK'} if sdbus.reload_unit(unit) else {action: 'Fail'}
         elif action == 'reloadorrestart':
-            sdbus.reload_or_restart_unit(unit)
-            return {action: 'OK'}
+            return {action: 'OK'} if sdbus.reload_or_restart_unit(unit) else {action: 'Fail'}
         elif action == 'status':
             if sdbus.get_unit_load_state(unit) != 'not-found':
                 return {action: str(sdbus.get_unit_active_state(unit))}
             else:
                 return {action: 'not-found'}
         else:
-            abort(404, 'Sorry, but cannot perform \'{}\' action.'.format(service))
+            response.status = 400
+            return {'msg': 'Sorry, but cannot perform \'{}\' action.'.format(action)}
     else:
-        abort(404, 'Sorry, but \'{}\' is not defined in config.'.format(service))
+        response.status = 400
+        return {'msg': 'Sorry, but \'{}\' is not defined in config.'.format(service)}
 
 @route('/')
 def get_main():
@@ -100,3 +94,11 @@ def get_img(file):
 @route('/js/<file>')
 def get_js(file):
     return static_file(file, root=os.path.join(static_path, 'js'))
+
+def start(config_file, host, port):
+    # Check config
+    global config
+    config = checkConfig(config_file)
+
+    # Run webserver
+    run(host=host, port=port)

+ 26 - 6
sysdweb/systemd.py

@@ -6,7 +6,7 @@
 #
 # Distributed under terms of the GNU GPLv3 license.
 
-from dbus import SystemBus, SessionBus, Interface
+from dbus import SystemBus, SessionBus, Interface, exceptions
 
 DBUS_INTERFACE = 'org.freedesktop.DBus.Properties'
 SYSTEMD_BUSNAME = 'org.freedesktop.systemd1'
@@ -33,16 +33,36 @@ class systemdBus(object):
         return unit_properties.Get(SYSTEMD_UNIT_INTERFACE, 'LoadState')
 
     def start_unit(self, unit):
-        self.manager.StartUnit(unit, 'replace')
+        try:
+            self.manager.StartUnit(unit, 'replace')
+            return True
+        except exceptions.DBusException:
+            return False
 
     def stop_unit(self, unit):
-        self.manager.StopUnit(unit, 'replace')
+        try:
+            self.manager.StopUnit(unit, 'replace')
+            return True
+        except exceptions.DBusException:
+            return False
 
     def restart_unit(self, unit):
-        self.manager.RestartUnit(unit, 'replace')
+        try:
+            self.manager.RestartUnit(unit, 'replace')
+            return True
+        except exceptions.DBusException:
+            return False
 
     def reload_unit(self, unit):
-        self.manager.ReloadUnit(unit, 'replace')
+        try:
+            self.manager.ReloadUnit(unit, 'replace')
+            return True
+        except exceptions.DBusException:
+            return False
 
     def reload_or_restart_unit(self, unit):
-        self.manager.ReloadOrRestartUnit(unit, 'replace')
+        try:
+            self.manager.ReloadOrRestartUnit(unit, 'replace')
+            return True
+        except exceptions.DBusException:
+            return False

+ 12 - 8
sysdweb/templates/static/js/sysdweb.js

@@ -12,14 +12,18 @@ $(document).ready(function(){
 function unit(service, action) {
   var url = '/api/v1/' + service + '/' + action;
 
-  $.get( url, function( data ) {
-    $('#services').load(document.URL + ' #services');
-    var timerId = setInterval(function(){
-      $('#services').load(document.URL + ' #services');
-    }, 1000);
-    setTimeout(function(){
-      clearInterval(timerId);
-    }, 10000);
+  $.getJSON( url, function( data ) {
+    $.each( data, function( key, val ) {
+      if (val == 'OK') {
+        $('#services').load(document.URL + ' #services');
+        var timerId = setInterval(function(){
+          $('#services').load(document.URL + ' #services');
+        }, 1000);
+        setTimeout(function(){clearInterval(timerId);}, 10000);
+      } else {
+          $('#warningModal').modal('show')
+      }
+    });
   });
 }
 

+ 23 - 0
sysdweb/templates/views/index.tpl

@@ -68,6 +68,29 @@
       </div>
     </div>
 
+    <!-- Modal -->
+    <div class="modal fade" id="warningModal" tabindex="-1" role="dialog"
+      aria-labelledby="warningModal">
+      <div class="modal-dialog" role="document">
+        <div class="modal-content">
+          <div class="modal-header">
+            <button type="button" class="close" data-dismiss="modal"
+              aria-label="Close"><span
+              aria-hidden="true">&times;</span></button>
+            <h4 class="modal-title" id="warningModal">Attention</h4>
+          </div>
+          <div class="modal-body">
+            The performed action cannot be done. Maybe you have
+            a permissions problem.
+          </div>
+          <div class="modal-footer">
+            <button type="button" class="btn btn-default"
+              data-dismiss="modal">Close</button>
+          </div>
+        </div>
+      </div>
+    </div>
+
     <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
     <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
     <!-- Include all compiled plugins (below), or include individual files as needed -->