From ab299ffd53dec966c1c7fac70f8db16597a63264 Mon Sep 17 00:00:00 2001
From: dobli <dobler.alex@gmail.com>
Date: Fri, 1 Mar 2019 15:16:46 +0100
Subject: [PATCH] Added menu entries to manage usb devices

---
 building_manager.py                           | 45 +++++++++++++++++++
 install-usb-support.sh                        | 15 +++++++
 template_configs/devices/docker-devices.rules |  4 ++
 template_configs/devices/enable-swarm-device  | 18 ++++++++
 template_configs/devices/swarm-device-watcher |  5 +++
 .../devices/swarm-device@.service             | 10 +++++
 6 files changed, 97 insertions(+)
 create mode 100755 install-usb-support.sh
 create mode 100644 template_configs/devices/docker-devices.rules
 create mode 100755 template_configs/devices/enable-swarm-device
 create mode 100755 template_configs/devices/swarm-device-watcher
 create mode 100755 template_configs/devices/swarm-device@.service

diff --git a/building_manager.py b/building_manager.py
index 4b64f31..355ae83 100755
--- a/building_manager.py
+++ b/building_manager.py
@@ -1119,6 +1119,8 @@ def load_main_entires(base_dir):
                         'value': service_menu})
         entries.append({'name': 'Manage Users',
                         'value': user_menu})
+        entries.append({'name': 'Manage Devices',
+                        'value': device_menu})
         entries.append({'name': 'Execute a command in a service container',
                         'value': exec_menu})
 
@@ -1396,6 +1398,49 @@ def service_modify_menu(base_dir):
         delete_service(base_dir, service)
 
 
+# *** Device Menu Functions ***
+def device_menu(args):
+    """Menu to manage devices
+
+    :args: Arguments form commandline
+    """
+    print("Adding device")
+    # Base directory for configs
+    base_dir = args.base_dir
+
+    if base_dir is None:
+        base_dir = os.getcwd()
+
+    # Check if device scripts are installed
+    bin_path = 'usr/bin/enable-swarm-device'
+
+    choices = ['Install device scripts']
+    if not os.path.exists(bin_path):
+        choices.append('Link device to service')
+
+    choices.append('Exit')
+
+    # Ask for action
+    choice = qust.select("What do you want to do?", choices=choices,
+                         style=st).ask()
+    if "Install" in choice:
+        print("Installing device scripts (need root)")
+        device_install_menu(base_dir)
+    elif "Link" in choice:
+        print("Linking device with service")
+
+
+def device_install_menu(base_dir):
+    """Install scripts to link devices
+
+    :base_dir: Base directory of configuration files
+    """
+    install_script = f"{base_dir}/install-usb-support.sh"
+    print(install_script)
+    # execute mosquitto passwd
+    run([f'sudo {install_script}'], shell=True)
+
+
 # *** Menu Helper Functions ***
 def generate_cb_choices(list, checked=False):
     """Generates checkbox entries for lists of strings
diff --git a/install-usb-support.sh b/install-usb-support.sh
new file mode 100755
index 0000000..0ad0bcb
--- /dev/null
+++ b/install-usb-support.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+echo "Copy swarm device enabler"
+cp ./template_configs/devices/enable-swarm-device /usr/bin/enable-swarm-device
+
+echo "Copy swarm device service watcher"
+cp ./template_configs/devices/swarm-device-watcher /usr/bin/swarm-device-watcher
+
+echo "Copy swam device rules"
+cp ./template_configs/devices/docker-devices.rules /etc/udev/rules.d/99-docker-devices.rules
+
+echo "Copy swarm device service file"
+cp ./template_configs/devices/swarm-device@.service /etc/systemd/system/swarm-device@.service
+
+echo "Reload udev rules"
+udevadm control --reload-rules
diff --git a/template_configs/devices/docker-devices.rules b/template_configs/devices/docker-devices.rules
new file mode 100644
index 0000000..5afb924
--- /dev/null
+++ b/template_configs/devices/docker-devices.rules
@@ -0,0 +1,4 @@
+# IDs of USB devices may be found with lsusb
+ 
+# Aeotec Z-Stick Gen5
+SUBSYSTEMS=="usb", ATTRS{idVendor}=="0658", ATTRS{idProduct}=="0200", GROUP="dialout", MODE="0666", SYMLINK+="zwave_stick"
diff --git a/template_configs/devices/enable-swarm-device b/template_configs/devices/enable-swarm-device
new file mode 100755
index 0000000..1e04a05
--- /dev/null
+++ b/template_configs/devices/enable-swarm-device
@@ -0,0 +1,18 @@
+#!/bin/bash
+USBDEV=$(readlink -f /dev/$1)
+CONTAINER_NAME=$2
+minor=$(stat -c '%T' $USBDEV)
+major=$(stat -c '%t' $USBDEV)
+if [[ -z $minor || -z $major ]]; then
+    echo "Error setting permissions for container: Device $1 not found"
+    exit
+fi
+dminor=$((0x${minor}))
+dmajor=$((0x${major}))
+CID=$(docker ps --no-trunc -q --filter name=$CONTAINER_NAME | head -1)
+if [[ -z $CID ]]; then
+    echo "Error setting permissions for container: Container $2 not found"
+    exit
+fi
+echo "Setting permissions to access $1 for container $2"
+echo "c $dmajor:$dminor rwm" > /sys/fs/cgroup/devices/docker/$CID/devices.allow
diff --git a/template_configs/devices/swarm-device-watcher b/template_configs/devices/swarm-device-watcher
new file mode 100755
index 0000000..ba8a966
--- /dev/null
+++ b/template_configs/devices/swarm-device-watcher
@@ -0,0 +1,5 @@
+#!/bin/bash
+docker events --filter 'event=start'| \
+while read line; do
+    /usr/bin/enable-swarm-device $1 $2
+done
diff --git a/template_configs/devices/swarm-device@.service b/template_configs/devices/swarm-device@.service
new file mode 100755
index 0000000..d748faa
--- /dev/null
+++ b/template_configs/devices/swarm-device@.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Service to monitor docker containers and mount devices
+
+[Service]
+Type=simple
+Environment="SCRIPT_ARGS=%I"
+ExecStart=/usr/bin/swarm-device-watcher $SCRIPT_ARGS
+
+[Install]
+WantedBy=multi-user.target
-- 
GitLab