Commit 4ccb649b authored by Rene Hadler's avatar Rene Hadler

Add pve6-usb-automount

parent 2a7ef4cc
pve6-usb-automount (0.4-1) precise; urgency=low
* Initial version for PVE6
-- Rene Hadler <rene.hadler@iteas.at> Tue, 25 Feb 2020 9:07:07 +0100
\ No newline at end of file
Source: pve6-usb-automount
Section: utils
Priority: optional
Maintainer: Rene Hadler <rene.hadler@iteas.at>
Build-Depends: debhelper (>= 8.0.0)
Package: pve6-usb-automount
Architecture: all
Depends: python3-pyinotify, python3-pyqt5, python3-pyudev
Conflicts: pve5-usb-automount
Replaces: pve5-usb-automount
Provides: pve6-usb-automount
Description: Adds USB-Automount feature to PVE6
Copyright 2020 Rene Hadler
This program 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; either version 3 of the License, or
(at your option) any later version.
This program 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:
http://www.gnu.org/copyleft/gpl.html or
/usr/share/common-licenses/GPL-3 on Debian(-like)-systems.
#!/bin/bash
# postinst script
#
# see: dh_installdeb(1)
#_manupdate() {
# mandb -f /usr/share/man/man1/hello.1.gz
#}
set -e
# summary of how this script can be called:
# * <postinst> `configure' <most-recently-configured-version>
# * <old-postinst> `abort-upgrade' <new version>
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
# <new-version>
# * <postinst> `abort-remove'
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
# <failed-install-package> <version> `removing'
# <conflicting-package> <version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
configure)
echo "postinst script called with " $*
systemctl enable pve6-usb-automount.service || true
systemctl restart pve6-usb-automount.service || true
# _manupdate
;;
abort-upgrade|abort-remove|abort-deconfigure)
echo "postinst script called with " $*
# _manupdate
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0
#!/usr/bin/make -f
%:
dh $@
override_dh_auto_install:
mkdir -p debian/pve6-usb-automount/etc/pve-usb-automount
mkdir -p debian/pve6-usb-automount/usr/bin
mkdir -p debian/pve6-usb-automount/etc/systemd/system
cp ../../etc/pve-usb-automount/main.conf debian/pve6-usb-automount/etc/pve-usb-automount/.
cp -a systemd/pve6-usb-automount.service debian/pve6-usb-automount/etc/systemd/system/.
cp pve6_usb_automount.py debian/pve6-usb-automount/usr/bin/.
override_dh_usrlocal:
\ No newline at end of file
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
import re
import signal
import pyudev
import time
import configparser
import syslog
import subprocess
import json
from os.path import exists
from pyudev.version import __version_info__
from PyQt5.QtCore import *
config = configparser.ConfigParser()
config.read('/etc/pve-usb-automount/main.conf')
MAX_FILES = config.get("MAIN", "MAX_FILES", fallback=3)
signal.signal(signal.SIGINT, signal.SIG_DFL)
syslog.openlog(ident="pve6-usb-automount")
class USBAutomount:
def __init__(self):
self.app = QCoreApplication(sys.argv)
print("Starting PVE6-USB-Automount")
# Starte UDEV-observer Thread
self.udev_thread = QThread()
self.udev_worker = udevObserver()
self.udev_worker.moveToThread(self.udev_thread)
self.udev_thread.started.connect(self.udev_worker.process)
self.udev_worker.finished.connect(self.udev_thread.quit)
self.udev_thread.start()
sys.exit(self.app.exec_())
class udevObserver(QObject):
finished = pyqtSignal()
keeprunning = True
def process(self):
print("Starting thread UDEV-Observer")
context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by('block')
observer = pyudev.MonitorObserver(monitor, self.udev_event)
observer.start()
while self.keeprunning:
time.sleep(0.3)
observer.stop()
self.finished.emit()
print("Exiting observer finished")
def quit(self):
print("Exiting observer")
self.keeprunning = False
def udev_event(self, action, device):
syslog.syslog("UDEV event for action::" + action + " and device::" + device.sys_name + " device_path::" + device.device_path)
devattr = device.attributes.available_attributes if __version_info__[1] >= 21 else device.attributes
if action == "add":
syslog.syslog("Add event for " + device.sys_name)
if device.device_type in ["disk", "partition"] and device.subsystem in ["block"]:
devinfo = self.getDeviceInfo(device.sys_name)
if devinfo != -1:
self.mountDevice(devinfo)
else:
syslog.syslog("No device info found for %s" % device.sys_name)
if action == "remove":
syslog.syslog("Remove event for " + device.sys_name)
if device.device_type in ["disk", "partition"] and device.subsystem in ["block"]:
self.umountDevice(device.sys_name)
def getDeviceInfo(self, device):
p = subprocess.Popen("lsblk -J -d -o KNAME,LABEL,FSTYPE /dev/%s" % device, stdout=subprocess.PIPE, shell=True)
p.wait(timeout=10)
if p.returncode == 0:
rawout = p.stdout.read().decode('UTF-8')
out = json.loads(rawout)
return out['blockdevices'][0]
else:
return -1
def mountDevice(self, device):
if device["fstype"] == None or device["fstype"] == "iso9660":
syslog.syslog("Blockdevice has no fs-type")
return
if "label" in device and device["label"] != None:
device["label"] = device["label"].replace(" ", "_")
#mountpath = "/media/%s" % device["label"] if "label" in device and device["label"] != None else "/media/%s" % device["kname"]
mountpath = "/media/%s" % device["kname"]
syslog.syslog("Create mount dir <%s>" % mountpath)
if not exists(mountpath):
p = subprocess.Popen("mkdir -p '%s'" % mountpath, stdout=subprocess.PIPE, shell=True)
p.wait(timeout=10)
if p.returncode != 0:
syslog.syslog("Mount dir could not be created")
return
p = subprocess.Popen("mount -o sync /dev/%s '%s'" % (device["kname"], mountpath), stdout=subprocess.PIPE, shell=True)
p.wait(timeout=10)
if p.returncode == 0:
syslog.syslog("Device %s was mounted on %s" % (device["kname"], mountpath))
subprocess.Popen("pvesm add dir 'usb-%s' -path '%s' -maxfiles %s -content vztmpl,iso,backup -is_mountpoint 1" % (device["kname"], mountpath, MAX_FILES), stdout=subprocess.PIPE, shell=True)
else:
syslog.syslog("Device %s was NOT mounted %s" % (device["kname"], mountpath))
def umountDevice(self, device):
mountpath = self.getMountPathForDevice(device)
if mountpath == "":
syslog.syslog("Mount dir for device %s was not found" % device)
return
p = subprocess.Popen("umount '%s'" % mountpath, stdout=subprocess.PIPE, shell=True)
p.wait(timeout=10)
if p.returncode == 0:
syslog.syslog("Device %s was unmounted" % (device))
subprocess.Popen("pvesm remove 'usb-%s'" % (device), stdout=subprocess.PIPE, shell=True)
if exists(mountpath):
subprocess.Popen("rmdir '%s'" % mountpath, stdout=subprocess.PIPE, shell=True)
else:
syslog.syslog("Device %s was NOT unmounted" % (device))
def getMountPathForDevice(self, device):
p = subprocess.Popen("mount", stdout=subprocess.PIPE, shell=True)
p.wait(timeout=10)
if p.returncode == 0:
rawout = p.stdout.read().decode('UTF-8')
for line in rawout.split("\n"):
m = re.search("^/dev/%s on (.*?) type" % device, line)
if m != None:
return m.group(1)
else:
return ""
return ""
if __name__ == '__main__':
USBAutomount()
\ No newline at end of file
[Unit]
Description=PVE6 automount service
After=systemd-udevd.service
Requires=systemd-udevd.service
DefaultDependencies=no
[Service]
ExecStart=/usr/bin/pve6_usb_automount.py
Restart=always
[Install]
WantedBy=multi-user.target
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment