From 337f45b8789715e1cd946914c22e87d86c7d61b9 Mon Sep 17 00:00:00 2001 From: Roy Liu Date: Wed, 28 Nov 2012 23:23:49 -0500 Subject: [PATCH 01/44] Formalize Debian packaging files --- debian/changelog | 6 +++++ debian/compat | 2 +- debian/control | 11 ++++---- debian/ebsmount.config | 11 ++++++++ debian/ebsmount.lintian-overrides | 4 +++ debian/ebsmount.postinst | 44 +++++++++++++++++++++++++++++++ debian/ebsmount.templates | 7 +++++ debian/gbp.conf | 5 ++++ debian/po/POTFILES.in | 1 + debian/po/templates.pot | 33 +++++++++++++++++++++++ debian/rules | 26 +++++++++++++++--- debian/source.lintian-overrides | 1 + debian/source/format | 1 + debian/watch | 1 + 14 files changed, 143 insertions(+), 10 deletions(-) create mode 100644 debian/changelog create mode 100644 debian/ebsmount.config create mode 100644 debian/ebsmount.lintian-overrides create mode 100644 debian/ebsmount.postinst create mode 100644 debian/ebsmount.templates create mode 100644 debian/gbp.conf create mode 100644 debian/po/POTFILES.in create mode 100644 debian/po/templates.pot create mode 100644 debian/source.lintian-overrides create mode 100644 debian/source/format create mode 100644 debian/watch diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..2c0ca13 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,6 @@ +ebsmount (0.94+3-0ubuntu1) precise; urgency=low + + * Import the work of Ubuntu maintainers Scott Moser (smoser@ubuntu.com) and + Logan Rosen (logatronico@gmail.com). + + -- Roy Liu Wed, 28 Nov 2012 00:00:00 -0500 diff --git a/debian/compat b/debian/compat index 7ed6ff8..7f8f011 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -5 +7 diff --git a/debian/control b/debian/control index 475e898..2f7a1ce 100644 --- a/debian/control +++ b/debian/control @@ -1,16 +1,15 @@ Source: ebsmount Section: misc Priority: optional -Maintainer: Alon Swartz -Build-Depends: debhelper (>> 4.2.0) -Standards-Version: 3.6.1 +Maintainer: Roy Liu +Build-Depends: debhelper, po-debconf +Standards-Version: 3.9.3 +Homepage: https://github.com/turnkeylinux/ebsmount Package: ebsmount Architecture: all -Depends: python (>= 2.4), udev, turnkey-pylib -Section: misc +Depends: python, udev, ${misc:Depends} Description: Automatically mount EC2/Eucalyptus EBS devices Automatically mounts EBS (Elastic Block Storage) devices when they are attached, supports formatted devices as well as partitions, uniquely identifiable mount points, and hooking scripts execution upon mount. - diff --git a/debian/ebsmount.config b/debian/ebsmount.config new file mode 100644 index 0000000..6028c79 --- /dev/null +++ b/debian/ebsmount.config @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +source -- /usr/share/debconf/confmodule + +if ( [[ "$1" == "configure" ]] && [[ -z "$2" ]] ) || [[ "$1" == "reconfigure" ]]; then + + db_input medium ebsmount/enable_hooks || true + db_go +fi diff --git a/debian/ebsmount.lintian-overrides b/debian/ebsmount.lintian-overrides new file mode 100644 index 0000000..20db0fc --- /dev/null +++ b/debian/ebsmount.lintian-overrides @@ -0,0 +1,4 @@ +config-does-not-load-confmodule +executable-not-elf-or-script +hyphen-used-as-minus-sign +postinst-does-not-load-confmodule diff --git a/debian/ebsmount.postinst b/debian/ebsmount.postinst new file mode 100644 index 0000000..f1d8a4f --- /dev/null +++ b/debian/ebsmount.postinst @@ -0,0 +1,44 @@ +#!/bin/bash + +set -e + +source -- /usr/share/debconf/confmodule + +case "$1" in + + configure|reconfigure) + db_get ebsmount/enable_hooks + + case "$RET" in + + true) + runhooks="True" + ;; + + false) + runhooks="False" + ;; + + *) + echo "Invalid configuration value." >&2 + exit -- 1 + ;; + esac + + sed -i -E "s/^RUNHOOKS=.*\$/RUNHOOKS=${runhooks}/g" -- /etc/ebsmount.conf + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + ;; + + *) + echo "postinst called with unknown argument \`${1}'." >&2 + exit -- 1 + ;; +esac + +#DEBHELPER# + +db_stop + +exit -- 0 diff --git a/debian/ebsmount.templates b/debian/ebsmount.templates new file mode 100644 index 0000000..e80c47c --- /dev/null +++ b/debian/ebsmount.templates @@ -0,0 +1,7 @@ +Template: ebsmount/enable_hooks +Type: boolean +Default: false +_Description: Enable hooks? Doing so may pose a security risk. + Hooks are the ebsmount package's way of having mounted volumes configure + themselves (see + `https://raw.github.com/turnkeylinux/ebsmount/master/docs/README'). diff --git a/debian/gbp.conf b/debian/gbp.conf new file mode 100644 index 0000000..0269396 --- /dev/null +++ b/debian/gbp.conf @@ -0,0 +1,5 @@ +[git-buildpackage] +builder = pdebuild --pbuilder cowbuilder --debbuildopts "-sa" -- --debbuildopts "" +debian-branch = master +upstream-branch = upstream +upstream-tree = branch diff --git a/debian/po/POTFILES.in b/debian/po/POTFILES.in new file mode 100644 index 0000000..05d8c8a --- /dev/null +++ b/debian/po/POTFILES.in @@ -0,0 +1 @@ +[type: gettext/rfc822deb] ebsmount.templates diff --git a/debian/po/templates.pot b/debian/po/templates.pot new file mode 100644 index 0000000..2af9f0a --- /dev/null +++ b/debian/po/templates.pot @@ -0,0 +1,33 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: ebsmount\n" +"Report-Msgid-Bugs-To: ebsmount@packages.debian.org\n" +"POT-Creation-Date: 2012-11-28 00:00-0500\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: boolean +#. Description +#: ../ebsmount.templates:1001 +msgid "Enable hooks? Doing so may pose a security risk." +msgstr "" + +#. Type: boolean +#. Description +#: ../ebsmount.templates:1001 +msgid "" +"Hooks are the ebsmount package's way of having mounted volumes configure " +"themselves (see `https://raw.github.com/turnkeylinux/ebsmount/master/docs/" +"README')." +msgstr "" diff --git a/debian/rules b/debian/rules index 348eab2..e3b3961 100755 --- a/debian/rules +++ b/debian/rules @@ -5,14 +5,32 @@ buildroot=debian/$(progname) prefix=$(buildroot)/usr clean: + + rm -f -- build-indep-stamp build-arch-stamp + $(MAKE) -- clean + dh_clean -build: +build: build-indep build-arch mkdir -p $(prefix) +build-indep: build-indep-stamp +build-indep-stamp: + + dh_testdir + + touch -- $@ + +build-arch: build-arch-stamp +build-arch-stamp: + + dh_testdir + + touch -- $@ + install: dh_testroot - dh_clean -k + dh_clean dh_testdir dh_installdirs dh_install @@ -22,9 +40,11 @@ install: binary-indep: install dh_testdir dh_testroot + dh_installdebconf dh_installdocs docs/ dh_installman man/ebsmount-manual.1 man/ebsmount-udev.8 dh_installchangelogs + dh_lintian dh_compress dh_installdeb dh_gencontrol @@ -34,4 +54,4 @@ binary-indep: install binary-arch: install binary: binary-indep binary-arch -.PHONY: clean binary-indep binary-arch binary install +.PHONY: clean build build-indep build-arch binary-indep binary-arch binary install diff --git a/debian/source.lintian-overrides b/debian/source.lintian-overrides new file mode 100644 index 0000000..ea1a461 --- /dev/null +++ b/debian/source.lintian-overrides @@ -0,0 +1 @@ +no-complete-debconf-translation diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/debian/watch b/debian/watch new file mode 100644 index 0000000..9e7c0da --- /dev/null +++ b/debian/watch @@ -0,0 +1 @@ +version=3 From fefd287e4853eec9fe35f9ca12146dd2d542865b Mon Sep 17 00:00:00 2001 From: Roy Liu Date: Thu, 29 Nov 2012 21:25:41 +0000 Subject: [PATCH 02/44] Add patches --- ...ey-pylib-dependency-by-adding-the-re.patch | 219 ++++++++++++++++++ ...ated-85-ebsmount.rules-file-in-the-M.patch | 19 ++ ...ile-to-use-install-in-the-place-of-c.patch | 26 +++ debian/patches/series | 3 + 4 files changed, 267 insertions(+) create mode 100644 debian/patches/0001-Remove-the-turnkey-pylib-dependency-by-adding-the-re.patch create mode 100644 debian/patches/0002-Remove-the-generated-85-ebsmount.rules-file-in-the-M.patch create mode 100644 debian/patches/0003-Change-the-Makefile-to-use-install-in-the-place-of-c.patch create mode 100644 debian/patches/series diff --git a/debian/patches/0001-Remove-the-turnkey-pylib-dependency-by-adding-the-re.patch b/debian/patches/0001-Remove-the-turnkey-pylib-dependency-by-adding-the-re.patch new file mode 100644 index 0000000..d40dbe6 --- /dev/null +++ b/debian/patches/0001-Remove-the-turnkey-pylib-dependency-by-adding-the-re.patch @@ -0,0 +1,219 @@ +From: Roy Liu +Date: Wed, 28 Nov 2012 23:24:42 -0500 +Subject: Remove the turnkey-pylib dependency by adding the requisite Python + imports + +--- + conffile.py | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + executil.py | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 194 insertions(+) + create mode 100644 conffile.py + create mode 100644 executil.py + +diff --git a/conffile.py b/conffile.py +new file mode 100644 +index 0000000..6272634 +--- /dev/null ++++ b/conffile.py +@@ -0,0 +1,98 @@ ++# Copyright (c) 2010 Alon Swartz ++# ++# This file is part of turnkey-pylib. ++# ++# turnkey-pylib is open source 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. ++ ++import os ++ ++class ConfFileError(Exception): ++ pass ++ ++class ConfFile(dict): ++ """Configuration file class (targeted at simple shell type configs) ++ ++ Usage: ++ ++ class foo(ConfFile): ++ CONF_FILE = /path/to/conf ++ REQUIRED = ['arg1' ,'arg2'] ++ ++ conf = foo() ++ print conf.arg1 # display ARG1 value from /path/to/conf ++ conf.arg2 = value # set ARG2 value ++ conf.write() # write new/update config to /path/to/conf ++ ++ Format: ++ ++ # comments are ignored ++ NAME=alon ++ AGE=29 ++ ++ """ ++ CONF_FILE = None ++ REQUIRED = [] ++ SET_ENVIRON = False ++ ++ def __init__(self): ++ self.read() ++ self.validate_required() ++ if self.SET_ENVIRON: ++ self.set_environ() ++ ++ def validate_required(self, required=[]): ++ """raise exception if required arguments are not set ++ REQUIRED validated by default, but can be optionally extended ++ """ ++ self.REQUIRED.extend(required) ++ for attr in self.REQUIRED: ++ if not self.has_key(attr): ++ error = "%s not specified in %s" % (attr.upper(), self.CONF_FILE) ++ raise ConfFileError(error) ++ ++ def set_environ(self): ++ """set environment (run on initialization if SET_ENVIRON)""" ++ for key, val in self.items(): ++ os.environ[key.upper()] = val ++ ++ def read(self): ++ if not self.CONF_FILE or not os.path.exists(self.CONF_FILE): ++ return ++ ++ for line in file(self.CONF_FILE).readlines(): ++ line = line.rstrip() ++ ++ if not line or line.startswith("#"): ++ continue ++ ++ key, val = line.split("=") ++ self[key.strip().lower()] = val.strip() ++ ++ def write(self): ++ fh = file(self.CONF_FILE, "w") ++ items = self.items() ++ items.sort() ++ for key, val in items: ++ print >> fh, "%s=%s" % (key.upper(), val) ++ ++ fh.close() ++ ++ def items(self): ++ items = [] ++ for key in self: ++ items.append((key, self[key])) ++ ++ return items ++ ++ def __getattr__(self, key): ++ try: ++ return self[key] ++ except KeyError, e: ++ raise AttributeError(e) ++ ++ def __setattr__(self, key, val): ++ self[key] = val ++ +diff --git a/executil.py b/executil.py +new file mode 100644 +index 0000000..e879a60 +--- /dev/null ++++ b/executil.py +@@ -0,0 +1,96 @@ ++# Copyright (c) 2010 Liraz Siri ++# ++# This file is part of turnkey-pylib. ++# ++# turnkey-pylib is open source 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 module contains high-level convenience functions for safe ++command execution that properly escape arguments and raise an ++ExecError exception on error ++""" ++import os ++import sys ++import commands ++ ++from subprocess import Popen, PIPE ++ ++mkarg = commands.mkarg ++ ++class ExecError(Exception): ++ """Accessible attributes: ++ command executed command ++ exitcode non-zero exitcode returned by command ++ output error output returned by command ++ """ ++ def __init__(self, command, exitcode, output=None): ++ Exception.__init__(self, command, exitcode, output) ++ ++ self.command = command ++ self.exitcode = exitcode ++ self.output = output ++ ++ def __str__(self): ++ str = "non-zero exitcode (%d) for command: %s" % (self.exitcode, ++ self.command) ++ if self.output: ++ str += "\n" + self.output ++ return str ++ ++def fmt_command(command, *args): ++ return command + " ".join([mkarg(arg) for arg in args]) ++ ++def system(command, *args): ++ """Executes with <*args> -> None ++ If command returns non-zero exitcode raises ExecError""" ++ ++ sys.stdout.flush() ++ sys.stderr.flush() ++ ++ command = fmt_command(command, *args) ++ error = os.system(command) ++ if error: ++ exitcode = os.WEXITSTATUS(error) ++ raise ExecError(command, exitcode) ++ ++def getoutput(command, *args): ++ """Executes with <*args> -> output ++ If command returns non-zero exitcode raises ExecError""" ++ ++ command = fmt_command(command, *args) ++ error, output = commands.getstatusoutput(command) ++ if error: ++ exitcode = os.WEXITSTATUS(error) ++ raise ExecError(command, exitcode, output) ++ ++ return output ++ ++def getoutput_popen(command, input=None): ++ """Uses subprocess.Popen to execute , piping into stdin. ++ If command returns non-zero exitcode raise ExecError. ++ ++ Return command output. ++ """ ++ ++ shell=False ++ if isinstance(command, str): ++ shell=True ++ ++ child = Popen(command, shell=shell, stdin=PIPE, stdout=PIPE, stderr=PIPE) ++ ++ errstr = None ++ try: ++ outstr, errstr = child.communicate(input) ++ except OSError: ++ pass ++ ++ errno = child.wait() ++ if errstr is None: ++ errstr = child.stderr.read() ++ ++ if errno != 0: ++ raise ExecError(command, errno, errstr) ++ ++ return outstr +-- diff --git a/debian/patches/0002-Remove-the-generated-85-ebsmount.rules-file-in-the-M.patch b/debian/patches/0002-Remove-the-generated-85-ebsmount.rules-file-in-the-M.patch new file mode 100644 index 0000000..b85b0eb --- /dev/null +++ b/debian/patches/0002-Remove-the-generated-85-ebsmount.rules-file-in-the-M.patch @@ -0,0 +1,19 @@ +From: Roy Liu +Date: Wed, 28 Nov 2012 23:24:47 -0500 +Subject: Remove the generated 85-ebsmount.rules file in the Makefile clean + target + +--- + Makefile | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Makefile b/Makefile +index ae1166c..0b62581 100644 +--- a/Makefile ++++ b/Makefile +@@ -77,3 +77,4 @@ uninstall: + # target: clean + clean: + rm -f *.pyc *.pyo *.rules _$(progname) ++ rm -f -- 85-ebsmount.rules +-- diff --git a/debian/patches/0003-Change-the-Makefile-to-use-install-in-the-place-of-c.patch b/debian/patches/0003-Change-the-Makefile-to-use-install-in-the-place-of-c.patch new file mode 100644 index 0000000..c272321 --- /dev/null +++ b/debian/patches/0003-Change-the-Makefile-to-use-install-in-the-place-of-c.patch @@ -0,0 +1,26 @@ +From: Roy Liu +Date: Thu, 29 Nov 2012 16:30:23 -0500 +Subject: Change the Makefile to use "install" in the place of "cp" + +--- + Makefile | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/Makefile b/Makefile +index 0b62581..bc40e88 100644 +--- a/Makefile ++++ b/Makefile +@@ -56,9 +56,9 @@ install: 85-ebsmount.rules + @echo + + install -d $(PATH_BIN) $(PATH_ETC) $(PATH_INSTALL_LIB) $(PATH_UDEV_RULES) +- cp *.conf $(PATH_ETC) +- cp *.py $(PATH_INSTALL_LIB) +- cp *.rules $(PATH_UDEV_RULES) ++ install -t $(PATH_ETC) -- *.conf ++ install -t $(PATH_INSTALL_LIB) -- *.py ++ install -t $(PATH_UDEV_RULES) -- *.rules + + $(call with-py-executables, \ + ln -fs $(call libpath, $$module) $(PATH_BIN)/$(progname), \ +-- diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..be30dbb --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,3 @@ +0001-Remove-the-turnkey-pylib-dependency-by-adding-the-re.patch +0002-Remove-the-generated-85-ebsmount.rules-file-in-the-M.patch +0003-Change-the-Makefile-to-use-install-in-the-place-of-c.patch From a3be98034ef845c0a179a57fe2ec39f0508876f3 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 2 Jan 2013 15:16:15 -0500 Subject: [PATCH 03/44] Add the patch 0004: Change the range of virtual block devices detected by udev from xv[f-p]] to xv[a-z] --- debian/changelog | 4 ++- ...-of-virtual-block-devices-detected-b.patch | 25 +++++++++++++++++++ debian/patches/series | 1 + 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 debian/patches/0004-Change-the-range-of-virtual-block-devices-detected-b.patch diff --git a/debian/changelog b/debian/changelog index 2c0ca13..be7073b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,7 @@ -ebsmount (0.94+3-0ubuntu1) precise; urgency=low +ebsmount (0.94+3-0ubuntu4) precise; urgency=low + * Add the patch 0004: Change the range of virtual block devices detected by + udev from xv[f-p] to xv[a-z]. * Import the work of Ubuntu maintainers Scott Moser (smoser@ubuntu.com) and Logan Rosen (logatronico@gmail.com). diff --git a/debian/patches/0004-Change-the-range-of-virtual-block-devices-detected-b.patch b/debian/patches/0004-Change-the-range-of-virtual-block-devices-detected-b.patch new file mode 100644 index 0000000..2aa29f4 --- /dev/null +++ b/debian/patches/0004-Change-the-range-of-virtual-block-devices-detected-b.patch @@ -0,0 +1,25 @@ +From: Ubuntu +Date: Wed, 2 Jan 2013 14:57:32 -0500 +Subject: Change the range of virtual block devices detected by udev from + xv[f-p] to xv[a-z] + +--- + 85-ebsmount.rules.in | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/85-ebsmount.rules.in b/85-ebsmount.rules.in +index 24faa66..cb596d9 100644 +--- a/85-ebsmount.rules.in ++++ b/85-ebsmount.rules.in +@@ -1,8 +1,8 @@ + # udev rules to trigger ebsmount-udev on ebs attach|detach + + # Amazon EC2 +-KERNEL=="xvd[f-p]", SUBSYSTEM=="block", ATTRS{devtype}=="vbd", ACTION=="add", RUN+="@PATH_BIN@/ebsmount-udev add" +-KERNEL=="xvd[f-p]", SUBSYSTEM=="block", ACTION=="remove", RUN+="@PATH_BIN@/ebsmount-udev remove" ++KERNEL=="xvd[a-z]", SUBSYSTEM=="block", ATTRS{devtype}=="vbd", ACTION=="add", RUN+="@PATH_BIN@/ebsmount-udev add" ++KERNEL=="xvd[a-z]", SUBSYSTEM=="block", ACTION=="remove", RUN+="@PATH_BIN@/ebsmount-udev remove" + + # Eucalyptus / OpenStack + KERNEL=="vd[a-z]*", SUBSYSTEM=="block", ACTION=="add", RUN+="@PATH_BIN@/ebsmount-udev add" +-- diff --git a/debian/patches/series b/debian/patches/series index be30dbb..1e6fadb 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,3 +1,4 @@ 0001-Remove-the-turnkey-pylib-dependency-by-adding-the-re.patch 0002-Remove-the-generated-85-ebsmount.rules-file-in-the-M.patch 0003-Change-the-Makefile-to-use-install-in-the-place-of-c.patch +0004-Change-the-range-of-virtual-block-devices-detected-b.patch From 4b9b64362730644dfd41e85ef3470894bb4888fa Mon Sep 17 00:00:00 2001 From: Roy Liu Date: Wed, 15 Mar 2017 21:00:23 -0400 Subject: [PATCH 04/44] Consolidate patches into the upstream source --- 85-ebsmount.rules.in | 4 +- Makefile | 7 +- conffile.py | 98 ++++++++ ...ey-pylib-dependency-by-adding-the-re.patch | 219 ------------------ ...ated-85-ebsmount.rules-file-in-the-M.patch | 19 -- ...ile-to-use-install-in-the-place-of-c.patch | 26 --- ...-of-virtual-block-devices-detected-b.patch | 25 -- debian/patches/series | 4 - executil.py | 96 ++++++++ 9 files changed, 200 insertions(+), 298 deletions(-) create mode 100644 conffile.py delete mode 100644 debian/patches/0001-Remove-the-turnkey-pylib-dependency-by-adding-the-re.patch delete mode 100644 debian/patches/0002-Remove-the-generated-85-ebsmount.rules-file-in-the-M.patch delete mode 100644 debian/patches/0003-Change-the-Makefile-to-use-install-in-the-place-of-c.patch delete mode 100644 debian/patches/0004-Change-the-range-of-virtual-block-devices-detected-b.patch delete mode 100644 debian/patches/series create mode 100644 executil.py diff --git a/85-ebsmount.rules.in b/85-ebsmount.rules.in index 24faa66..1423e13 100644 --- a/85-ebsmount.rules.in +++ b/85-ebsmount.rules.in @@ -1,8 +1,8 @@ # udev rules to trigger ebsmount-udev on ebs attach|detach # Amazon EC2 -KERNEL=="xvd[f-p]", SUBSYSTEM=="block", ATTRS{devtype}=="vbd", ACTION=="add", RUN+="@PATH_BIN@/ebsmount-udev add" -KERNEL=="xvd[f-p]", SUBSYSTEM=="block", ACTION=="remove", RUN+="@PATH_BIN@/ebsmount-udev remove" +KERNEL=="xvd[a-z]", SUBSYSTEM=="block", ATTRS{devtype}=="vbd", ACTION=="add", RUN+="@PATH_BIN@/ebsmount-udev add" +KERNEL=="xvd[a-z]", SUBSYSTEM=="block", ACTION=="remove", RUN+="@PATH_BIN@/ebsmount-udev remove" # Eucalyptus / OpenStack KERNEL=="vd[a-z]*", SUBSYSTEM=="block", ACTION=="add", RUN+="@PATH_BIN@/ebsmount-udev add" diff --git a/Makefile b/Makefile index ae1166c..bc40e88 100644 --- a/Makefile +++ b/Makefile @@ -56,9 +56,9 @@ install: 85-ebsmount.rules @echo install -d $(PATH_BIN) $(PATH_ETC) $(PATH_INSTALL_LIB) $(PATH_UDEV_RULES) - cp *.conf $(PATH_ETC) - cp *.py $(PATH_INSTALL_LIB) - cp *.rules $(PATH_UDEV_RULES) + install -t $(PATH_ETC) -- *.conf + install -t $(PATH_INSTALL_LIB) -- *.py + install -t $(PATH_UDEV_RULES) -- *.rules $(call with-py-executables, \ ln -fs $(call libpath, $$module) $(PATH_BIN)/$(progname), \ @@ -77,3 +77,4 @@ uninstall: # target: clean clean: rm -f *.pyc *.pyo *.rules _$(progname) + rm -f -- 85-ebsmount.rules diff --git a/conffile.py b/conffile.py new file mode 100644 index 0000000..6272634 --- /dev/null +++ b/conffile.py @@ -0,0 +1,98 @@ +# Copyright (c) 2010 Alon Swartz +# +# This file is part of turnkey-pylib. +# +# turnkey-pylib is open source 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. + +import os + +class ConfFileError(Exception): + pass + +class ConfFile(dict): + """Configuration file class (targeted at simple shell type configs) + + Usage: + + class foo(ConfFile): + CONF_FILE = /path/to/conf + REQUIRED = ['arg1' ,'arg2'] + + conf = foo() + print conf.arg1 # display ARG1 value from /path/to/conf + conf.arg2 = value # set ARG2 value + conf.write() # write new/update config to /path/to/conf + + Format: + + # comments are ignored + NAME=alon + AGE=29 + + """ + CONF_FILE = None + REQUIRED = [] + SET_ENVIRON = False + + def __init__(self): + self.read() + self.validate_required() + if self.SET_ENVIRON: + self.set_environ() + + def validate_required(self, required=[]): + """raise exception if required arguments are not set + REQUIRED validated by default, but can be optionally extended + """ + self.REQUIRED.extend(required) + for attr in self.REQUIRED: + if not self.has_key(attr): + error = "%s not specified in %s" % (attr.upper(), self.CONF_FILE) + raise ConfFileError(error) + + def set_environ(self): + """set environment (run on initialization if SET_ENVIRON)""" + for key, val in self.items(): + os.environ[key.upper()] = val + + def read(self): + if not self.CONF_FILE or not os.path.exists(self.CONF_FILE): + return + + for line in file(self.CONF_FILE).readlines(): + line = line.rstrip() + + if not line or line.startswith("#"): + continue + + key, val = line.split("=") + self[key.strip().lower()] = val.strip() + + def write(self): + fh = file(self.CONF_FILE, "w") + items = self.items() + items.sort() + for key, val in items: + print >> fh, "%s=%s" % (key.upper(), val) + + fh.close() + + def items(self): + items = [] + for key in self: + items.append((key, self[key])) + + return items + + def __getattr__(self, key): + try: + return self[key] + except KeyError, e: + raise AttributeError(e) + + def __setattr__(self, key, val): + self[key] = val + diff --git a/debian/patches/0001-Remove-the-turnkey-pylib-dependency-by-adding-the-re.patch b/debian/patches/0001-Remove-the-turnkey-pylib-dependency-by-adding-the-re.patch deleted file mode 100644 index d40dbe6..0000000 --- a/debian/patches/0001-Remove-the-turnkey-pylib-dependency-by-adding-the-re.patch +++ /dev/null @@ -1,219 +0,0 @@ -From: Roy Liu -Date: Wed, 28 Nov 2012 23:24:42 -0500 -Subject: Remove the turnkey-pylib dependency by adding the requisite Python - imports - ---- - conffile.py | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - executil.py | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 194 insertions(+) - create mode 100644 conffile.py - create mode 100644 executil.py - -diff --git a/conffile.py b/conffile.py -new file mode 100644 -index 0000000..6272634 ---- /dev/null -+++ b/conffile.py -@@ -0,0 +1,98 @@ -+# Copyright (c) 2010 Alon Swartz -+# -+# This file is part of turnkey-pylib. -+# -+# turnkey-pylib is open source 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. -+ -+import os -+ -+class ConfFileError(Exception): -+ pass -+ -+class ConfFile(dict): -+ """Configuration file class (targeted at simple shell type configs) -+ -+ Usage: -+ -+ class foo(ConfFile): -+ CONF_FILE = /path/to/conf -+ REQUIRED = ['arg1' ,'arg2'] -+ -+ conf = foo() -+ print conf.arg1 # display ARG1 value from /path/to/conf -+ conf.arg2 = value # set ARG2 value -+ conf.write() # write new/update config to /path/to/conf -+ -+ Format: -+ -+ # comments are ignored -+ NAME=alon -+ AGE=29 -+ -+ """ -+ CONF_FILE = None -+ REQUIRED = [] -+ SET_ENVIRON = False -+ -+ def __init__(self): -+ self.read() -+ self.validate_required() -+ if self.SET_ENVIRON: -+ self.set_environ() -+ -+ def validate_required(self, required=[]): -+ """raise exception if required arguments are not set -+ REQUIRED validated by default, but can be optionally extended -+ """ -+ self.REQUIRED.extend(required) -+ for attr in self.REQUIRED: -+ if not self.has_key(attr): -+ error = "%s not specified in %s" % (attr.upper(), self.CONF_FILE) -+ raise ConfFileError(error) -+ -+ def set_environ(self): -+ """set environment (run on initialization if SET_ENVIRON)""" -+ for key, val in self.items(): -+ os.environ[key.upper()] = val -+ -+ def read(self): -+ if not self.CONF_FILE or not os.path.exists(self.CONF_FILE): -+ return -+ -+ for line in file(self.CONF_FILE).readlines(): -+ line = line.rstrip() -+ -+ if not line or line.startswith("#"): -+ continue -+ -+ key, val = line.split("=") -+ self[key.strip().lower()] = val.strip() -+ -+ def write(self): -+ fh = file(self.CONF_FILE, "w") -+ items = self.items() -+ items.sort() -+ for key, val in items: -+ print >> fh, "%s=%s" % (key.upper(), val) -+ -+ fh.close() -+ -+ def items(self): -+ items = [] -+ for key in self: -+ items.append((key, self[key])) -+ -+ return items -+ -+ def __getattr__(self, key): -+ try: -+ return self[key] -+ except KeyError, e: -+ raise AttributeError(e) -+ -+ def __setattr__(self, key, val): -+ self[key] = val -+ -diff --git a/executil.py b/executil.py -new file mode 100644 -index 0000000..e879a60 ---- /dev/null -+++ b/executil.py -@@ -0,0 +1,96 @@ -+# Copyright (c) 2010 Liraz Siri -+# -+# This file is part of turnkey-pylib. -+# -+# turnkey-pylib is open source 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 module contains high-level convenience functions for safe -+command execution that properly escape arguments and raise an -+ExecError exception on error -+""" -+import os -+import sys -+import commands -+ -+from subprocess import Popen, PIPE -+ -+mkarg = commands.mkarg -+ -+class ExecError(Exception): -+ """Accessible attributes: -+ command executed command -+ exitcode non-zero exitcode returned by command -+ output error output returned by command -+ """ -+ def __init__(self, command, exitcode, output=None): -+ Exception.__init__(self, command, exitcode, output) -+ -+ self.command = command -+ self.exitcode = exitcode -+ self.output = output -+ -+ def __str__(self): -+ str = "non-zero exitcode (%d) for command: %s" % (self.exitcode, -+ self.command) -+ if self.output: -+ str += "\n" + self.output -+ return str -+ -+def fmt_command(command, *args): -+ return command + " ".join([mkarg(arg) for arg in args]) -+ -+def system(command, *args): -+ """Executes with <*args> -> None -+ If command returns non-zero exitcode raises ExecError""" -+ -+ sys.stdout.flush() -+ sys.stderr.flush() -+ -+ command = fmt_command(command, *args) -+ error = os.system(command) -+ if error: -+ exitcode = os.WEXITSTATUS(error) -+ raise ExecError(command, exitcode) -+ -+def getoutput(command, *args): -+ """Executes with <*args> -> output -+ If command returns non-zero exitcode raises ExecError""" -+ -+ command = fmt_command(command, *args) -+ error, output = commands.getstatusoutput(command) -+ if error: -+ exitcode = os.WEXITSTATUS(error) -+ raise ExecError(command, exitcode, output) -+ -+ return output -+ -+def getoutput_popen(command, input=None): -+ """Uses subprocess.Popen to execute , piping into stdin. -+ If command returns non-zero exitcode raise ExecError. -+ -+ Return command output. -+ """ -+ -+ shell=False -+ if isinstance(command, str): -+ shell=True -+ -+ child = Popen(command, shell=shell, stdin=PIPE, stdout=PIPE, stderr=PIPE) -+ -+ errstr = None -+ try: -+ outstr, errstr = child.communicate(input) -+ except OSError: -+ pass -+ -+ errno = child.wait() -+ if errstr is None: -+ errstr = child.stderr.read() -+ -+ if errno != 0: -+ raise ExecError(command, errno, errstr) -+ -+ return outstr --- diff --git a/debian/patches/0002-Remove-the-generated-85-ebsmount.rules-file-in-the-M.patch b/debian/patches/0002-Remove-the-generated-85-ebsmount.rules-file-in-the-M.patch deleted file mode 100644 index b85b0eb..0000000 --- a/debian/patches/0002-Remove-the-generated-85-ebsmount.rules-file-in-the-M.patch +++ /dev/null @@ -1,19 +0,0 @@ -From: Roy Liu -Date: Wed, 28 Nov 2012 23:24:47 -0500 -Subject: Remove the generated 85-ebsmount.rules file in the Makefile clean - target - ---- - Makefile | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Makefile b/Makefile -index ae1166c..0b62581 100644 ---- a/Makefile -+++ b/Makefile -@@ -77,3 +77,4 @@ uninstall: - # target: clean - clean: - rm -f *.pyc *.pyo *.rules _$(progname) -+ rm -f -- 85-ebsmount.rules --- diff --git a/debian/patches/0003-Change-the-Makefile-to-use-install-in-the-place-of-c.patch b/debian/patches/0003-Change-the-Makefile-to-use-install-in-the-place-of-c.patch deleted file mode 100644 index c272321..0000000 --- a/debian/patches/0003-Change-the-Makefile-to-use-install-in-the-place-of-c.patch +++ /dev/null @@ -1,26 +0,0 @@ -From: Roy Liu -Date: Thu, 29 Nov 2012 16:30:23 -0500 -Subject: Change the Makefile to use "install" in the place of "cp" - ---- - Makefile | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/Makefile b/Makefile -index 0b62581..bc40e88 100644 ---- a/Makefile -+++ b/Makefile -@@ -56,9 +56,9 @@ install: 85-ebsmount.rules - @echo - - install -d $(PATH_BIN) $(PATH_ETC) $(PATH_INSTALL_LIB) $(PATH_UDEV_RULES) -- cp *.conf $(PATH_ETC) -- cp *.py $(PATH_INSTALL_LIB) -- cp *.rules $(PATH_UDEV_RULES) -+ install -t $(PATH_ETC) -- *.conf -+ install -t $(PATH_INSTALL_LIB) -- *.py -+ install -t $(PATH_UDEV_RULES) -- *.rules - - $(call with-py-executables, \ - ln -fs $(call libpath, $$module) $(PATH_BIN)/$(progname), \ --- diff --git a/debian/patches/0004-Change-the-range-of-virtual-block-devices-detected-b.patch b/debian/patches/0004-Change-the-range-of-virtual-block-devices-detected-b.patch deleted file mode 100644 index 2aa29f4..0000000 --- a/debian/patches/0004-Change-the-range-of-virtual-block-devices-detected-b.patch +++ /dev/null @@ -1,25 +0,0 @@ -From: Ubuntu -Date: Wed, 2 Jan 2013 14:57:32 -0500 -Subject: Change the range of virtual block devices detected by udev from - xv[f-p] to xv[a-z] - ---- - 85-ebsmount.rules.in | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/85-ebsmount.rules.in b/85-ebsmount.rules.in -index 24faa66..cb596d9 100644 ---- a/85-ebsmount.rules.in -+++ b/85-ebsmount.rules.in -@@ -1,8 +1,8 @@ - # udev rules to trigger ebsmount-udev on ebs attach|detach - - # Amazon EC2 --KERNEL=="xvd[f-p]", SUBSYSTEM=="block", ATTRS{devtype}=="vbd", ACTION=="add", RUN+="@PATH_BIN@/ebsmount-udev add" --KERNEL=="xvd[f-p]", SUBSYSTEM=="block", ACTION=="remove", RUN+="@PATH_BIN@/ebsmount-udev remove" -+KERNEL=="xvd[a-z]", SUBSYSTEM=="block", ATTRS{devtype}=="vbd", ACTION=="add", RUN+="@PATH_BIN@/ebsmount-udev add" -+KERNEL=="xvd[a-z]", SUBSYSTEM=="block", ACTION=="remove", RUN+="@PATH_BIN@/ebsmount-udev remove" - - # Eucalyptus / OpenStack - KERNEL=="vd[a-z]*", SUBSYSTEM=="block", ACTION=="add", RUN+="@PATH_BIN@/ebsmount-udev add" --- diff --git a/debian/patches/series b/debian/patches/series deleted file mode 100644 index 1e6fadb..0000000 --- a/debian/patches/series +++ /dev/null @@ -1,4 +0,0 @@ -0001-Remove-the-turnkey-pylib-dependency-by-adding-the-re.patch -0002-Remove-the-generated-85-ebsmount.rules-file-in-the-M.patch -0003-Change-the-Makefile-to-use-install-in-the-place-of-c.patch -0004-Change-the-range-of-virtual-block-devices-detected-b.patch diff --git a/executil.py b/executil.py new file mode 100644 index 0000000..e879a60 --- /dev/null +++ b/executil.py @@ -0,0 +1,96 @@ +# Copyright (c) 2010 Liraz Siri +# +# This file is part of turnkey-pylib. +# +# turnkey-pylib is open source 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 module contains high-level convenience functions for safe +command execution that properly escape arguments and raise an +ExecError exception on error +""" +import os +import sys +import commands + +from subprocess import Popen, PIPE + +mkarg = commands.mkarg + +class ExecError(Exception): + """Accessible attributes: + command executed command + exitcode non-zero exitcode returned by command + output error output returned by command + """ + def __init__(self, command, exitcode, output=None): + Exception.__init__(self, command, exitcode, output) + + self.command = command + self.exitcode = exitcode + self.output = output + + def __str__(self): + str = "non-zero exitcode (%d) for command: %s" % (self.exitcode, + self.command) + if self.output: + str += "\n" + self.output + return str + +def fmt_command(command, *args): + return command + " ".join([mkarg(arg) for arg in args]) + +def system(command, *args): + """Executes with <*args> -> None + If command returns non-zero exitcode raises ExecError""" + + sys.stdout.flush() + sys.stderr.flush() + + command = fmt_command(command, *args) + error = os.system(command) + if error: + exitcode = os.WEXITSTATUS(error) + raise ExecError(command, exitcode) + +def getoutput(command, *args): + """Executes with <*args> -> output + If command returns non-zero exitcode raises ExecError""" + + command = fmt_command(command, *args) + error, output = commands.getstatusoutput(command) + if error: + exitcode = os.WEXITSTATUS(error) + raise ExecError(command, exitcode, output) + + return output + +def getoutput_popen(command, input=None): + """Uses subprocess.Popen to execute , piping into stdin. + If command returns non-zero exitcode raise ExecError. + + Return command output. + """ + + shell=False + if isinstance(command, str): + shell=True + + child = Popen(command, shell=shell, stdin=PIPE, stdout=PIPE, stderr=PIPE) + + errstr = None + try: + outstr, errstr = child.communicate(input) + except OSError: + pass + + errno = child.wait() + if errstr is None: + errstr = child.stderr.read() + + if errno != 0: + raise ExecError(command, errno, errstr) + + return outstr From f1c88aabbeae205a5562528537c861b63fe22dd0 Mon Sep 17 00:00:00 2001 From: Roy Liu Date: Wed, 15 Mar 2017 22:28:14 -0400 Subject: [PATCH 05/44] Update the `ebsmount-udev` script to work with systemd mount namespaces --- 85-ebsmount.rules.in | 6 +++--- Makefile | 21 ++++++++++++++------- cmd_udev.py | 16 ---------------- debian/changelog | 7 +++++++ debian/control | 2 +- debian/ebsmount.links | 1 + debian/gbp.conf | 4 ++-- debian/source/format | 2 +- ebsmount@.service.in | 10 ++++++++++ 9 files changed, 39 insertions(+), 30 deletions(-) create mode 100644 debian/ebsmount.links create mode 100644 ebsmount@.service.in diff --git a/85-ebsmount.rules.in b/85-ebsmount.rules.in index 1423e13..bd3886e 100644 --- a/85-ebsmount.rules.in +++ b/85-ebsmount.rules.in @@ -1,8 +1,8 @@ -# udev rules to trigger ebsmount-udev on ebs attach|detach +# udev rules to trigger the ebsmount systemd service. # Amazon EC2 -KERNEL=="xvd[a-z]", SUBSYSTEM=="block", ATTRS{devtype}=="vbd", ACTION=="add", RUN+="@PATH_BIN@/ebsmount-udev add" -KERNEL=="xvd[a-z]", SUBSYSTEM=="block", ACTION=="remove", RUN+="@PATH_BIN@/ebsmount-udev remove" +KERNEL=="xvd[a-z]", SUBSYSTEM=="block", ATTRS{devtype}=="vbd", ACTION=="add", RUN+="/usr/sbin/service ebsmount@%k start" +KERNEL=="xvd[a-z]", SUBSYSTEM=="block", ACTION=="remove", RUN+="/usr/sbin/service ebsmount@%k stop" # Eucalyptus / OpenStack KERNEL=="vd[a-z]*", SUBSYSTEM=="block", ACTION=="add", RUN+="@PATH_BIN@/ebsmount-udev add" diff --git a/Makefile b/Makefile index bc40e88..8b10c52 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ PATH_BIN = $(prefix)/bin PATH_ETC = $(destdir)/etc PATH_INSTALL_LIB = $(prefix)/lib/$(progname) PATH_UDEV_RULES = $(destdir)/lib/udev/rules.d +PATH_SYSTEMD_SERVICE = $(destdir)/lib/systemd/system all: help @@ -45,20 +46,25 @@ define with-py-executables fi; endef -# set path bin in udev rules +# Set the bin path in various templates. + %.rules: %.rules.in sed "s|@PATH_BIN@|$(call truepath,$(PATH_BIN))|g" $< > $@ +%.service: %.service.in + sed "s|@PATH_BIN@|$(call truepath,$(PATH_BIN))|g" $< > $@ + # target: install -install: 85-ebsmount.rules +install: 85-ebsmount.rules ebsmount@.service @echo @echo \*\* CONFIG: prefix = $(prefix) \*\* @echo - install -d $(PATH_BIN) $(PATH_ETC) $(PATH_INSTALL_LIB) $(PATH_UDEV_RULES) - install -t $(PATH_ETC) -- *.conf - install -t $(PATH_INSTALL_LIB) -- *.py - install -t $(PATH_UDEV_RULES) -- *.rules + install -d $(PATH_BIN) $(PATH_ETC) $(PATH_INSTALL_LIB) $(PATH_UDEV_RULES) $(PATH_SYSTEMD_SERVICE) + install -m 0644 -t $(PATH_ETC) -- *.conf + install -m 0755 -t $(PATH_INSTALL_LIB) -- *.py + install -m 0644 -t $(PATH_UDEV_RULES) -- *.rules + install -m 0644 -t $(PATH_SYSTEMD_SERVICE) -- *.service $(call with-py-executables, \ ln -fs $(call libpath, $$module) $(PATH_BIN)/$(progname), \ @@ -69,6 +75,7 @@ uninstall: rm -rf $(PATH_INSTALL_LIB) rm -f $(PATH_ETC)/ebsmount.conf rm -f $(PATH_UDEV_RULES)/85-ebsmount.rules + rm -f $(PATH_SYSTEMD_SERVICE)/ebsmount@.service $(call with-py-executables, \ rm -f $(PATH_BIN)/$(progname), \ @@ -77,4 +84,4 @@ uninstall: # target: clean clean: rm -f *.pyc *.pyo *.rules _$(progname) - rm -f -- 85-ebsmount.rules + rm -f -- 85-ebsmount.rules ebsmount@.service diff --git a/cmd_udev.py b/cmd_udev.py index 3680b03..a61cdb7 100755 --- a/cmd_udev.py +++ b/cmd_udev.py @@ -23,12 +23,10 @@ Environment variables (Amazon EC2): DEVNAME (required: e.g., /dev/xvdf) - PHYSDEVPATH (required: e.g., /devices/xen/vbd-2160) Environment variables (Eucalyptus): DEVNAME (required: e.g., /dev/vda) - DEVPATH (required: e.g., /devices/virtio-pci/virtio0/block/vda) """ @@ -51,13 +49,6 @@ def fatal(s): print >> sys.stderr, "error: " + str(s) sys.exit(1) -def _expected_devpath(devpath, devpaths): - for pattern in devpaths: - if re.search(pattern, devpath): - return True - - return False - def main(): if not len(sys.argv) == 2: usage() @@ -67,7 +58,6 @@ def main(): action = sys.argv[1] devname = os.getenv('DEVNAME', None) - devpath = os.getenv('PHYSDEVPATH', os.getenv('DEVPATH', None)) if not action in ('add', 'remove'): usage('action must be one of: add, remove') @@ -75,12 +65,6 @@ def main(): if not devname: usage('DEVNAME is required') - if not devpath: - usage('PHYSDEVPATH or DEVPATH is required') - - if not _expected_devpath(devpath, config.devpaths.split()): - usage('PHYSDEVPATH/DEVPATH is not of the expected structure') - # log trigger log(devname, "received %s trigger" % action) diff --git a/debian/changelog b/debian/changelog index be7073b..65f0f28 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +ebsmount (0.95) yakkety; urgency=low + + * Update the `ebsmount-udev` script to work with systemd mount namespaces. + * Upgrade to Ubuntu Yakkety. + + -- Roy Liu Tue, 14 Mar 2017 00:00:00 -0400 + ebsmount (0.94+3-0ubuntu4) precise; urgency=low * Add the patch 0004: Change the range of virtual block devices detected by diff --git a/debian/control b/debian/control index 2f7a1ce..e35e465 100644 --- a/debian/control +++ b/debian/control @@ -3,7 +3,7 @@ Section: misc Priority: optional Maintainer: Roy Liu Build-Depends: debhelper, po-debconf -Standards-Version: 3.9.3 +Standards-Version: 3.9.8 Homepage: https://github.com/turnkeylinux/ebsmount Package: ebsmount diff --git a/debian/ebsmount.links b/debian/ebsmount.links new file mode 100644 index 0000000..b66f083 --- /dev/null +++ b/debian/ebsmount.links @@ -0,0 +1 @@ +lib/systemd/system/ebsmount@.service etc/systemd/system/ebsmount@.service diff --git a/debian/gbp.conf b/debian/gbp.conf index 0269396..3e31ec7 100644 --- a/debian/gbp.conf +++ b/debian/gbp.conf @@ -1,5 +1,5 @@ -[git-buildpackage] +[buildpackage] builder = pdebuild --pbuilder cowbuilder --debbuildopts "-sa" -- --debbuildopts "" debian-branch = master -upstream-branch = upstream +upstream-branch = master upstream-tree = branch diff --git a/debian/source/format b/debian/source/format index 163aaf8..89ae9db 100644 --- a/debian/source/format +++ b/debian/source/format @@ -1 +1 @@ -3.0 (quilt) +3.0 (native) diff --git a/ebsmount@.service.in b/ebsmount@.service.in new file mode 100644 index 0000000..f847604 --- /dev/null +++ b/ebsmount@.service.in @@ -0,0 +1,10 @@ +[Unit] +Description=ebsmount for %i +[Service] +Type=oneshot +RemainAfterExit=true +Environment="DEVNAME=%i" +ExecStart=@PATH_BIN@/ebsmount-udev add +ExecStop=@PATH_BIN@/ebsmount-udev remove +# Very important: Expose mounted volumes to other processes. +MountFlags=shared From 7f58bfd49e12c54d74166b08ba00354323c636eb Mon Sep 17 00:00:00 2001 From: Roy Liu Date: Sat, 10 Feb 2018 23:12:12 -0500 Subject: [PATCH 06/44] Change the device name detection pattern in `85-ebsmount.rules.in` to `KERNEL=="xvd[a-z]|nvme[0-26]n[0-26]"` --- 85-ebsmount.rules.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/85-ebsmount.rules.in b/85-ebsmount.rules.in index bd3886e..89d9fc8 100644 --- a/85-ebsmount.rules.in +++ b/85-ebsmount.rules.in @@ -1,8 +1,8 @@ # udev rules to trigger the ebsmount systemd service. # Amazon EC2 -KERNEL=="xvd[a-z]", SUBSYSTEM=="block", ATTRS{devtype}=="vbd", ACTION=="add", RUN+="/usr/sbin/service ebsmount@%k start" -KERNEL=="xvd[a-z]", SUBSYSTEM=="block", ACTION=="remove", RUN+="/usr/sbin/service ebsmount@%k stop" +KERNEL=="xvd[a-z]|nvme[0-26]n[0-26]", SUBSYSTEM=="block", ACTION=="add", RUN+="/usr/sbin/service ebsmount@%k start" +KERNEL=="xvd[a-z]|nvme[0-26]n[0-26]", SUBSYSTEM=="block", ACTION=="remove", RUN+="/usr/sbin/service ebsmount@%k stop" # Eucalyptus / OpenStack KERNEL=="vd[a-z]*", SUBSYSTEM=="block", ACTION=="add", RUN+="@PATH_BIN@/ebsmount-udev add" From 2f54bb26da5ff6f85feddb0e5ed991836e92413f Mon Sep 17 00:00:00 2001 From: Roy Liu Date: Sat, 10 Feb 2018 23:38:08 -0500 Subject: [PATCH 07/44] Update to version 0.96 --- debian/changelog | 7 +++++++ debian/compat | 2 +- debian/control | 2 +- debian/watch | 1 - 4 files changed, 9 insertions(+), 3 deletions(-) delete mode 100644 debian/watch diff --git a/debian/changelog b/debian/changelog index 65f0f28..d231762 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +ebsmount (0.96) artful; urgency=low + + * Change the device name detection pattern in `85-ebsmount.rules.in` to `KERNEL=="xvd[a-z]|nvme[0-26]n[0-26]"`. + * Upgrade to Ubuntu Artful. + + -- Roy Liu Sat, 10 Feb 2018 00:00:00 -0400 + ebsmount (0.95) yakkety; urgency=low * Update the `ebsmount-udev` script to work with systemd mount namespaces. diff --git a/debian/compat b/debian/compat index 7f8f011..ec63514 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -7 +9 diff --git a/debian/control b/debian/control index e35e465..247164b 100644 --- a/debian/control +++ b/debian/control @@ -3,7 +3,7 @@ Section: misc Priority: optional Maintainer: Roy Liu Build-Depends: debhelper, po-debconf -Standards-Version: 3.9.8 +Standards-Version: 4.1.1 Homepage: https://github.com/turnkeylinux/ebsmount Package: ebsmount diff --git a/debian/watch b/debian/watch deleted file mode 100644 index 9e7c0da..0000000 --- a/debian/watch +++ /dev/null @@ -1 +0,0 @@ -version=3 From af8bfd474d8f49b6aa75a896c77d2e0e60aef368 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Thu, 3 Feb 2022 05:50:10 +0000 Subject: [PATCH 08/44] Initial start - 2to3 on python files and initial refactoring of Debian pkging. --- 85-ebsmount.rules.in => 85-ebsmount.rules | 0 Makefile | 79 ----------------------- cmd_manual.py | 10 +-- cmd_udev.py | 8 +-- debian/control | 10 ++- debian/ebsmount.install | 2 + udevdb.py | 14 ++-- utils.py | 4 +- 8 files changed, 24 insertions(+), 103 deletions(-) rename 85-ebsmount.rules.in => 85-ebsmount.rules (100%) delete mode 100644 Makefile create mode 100644 debian/ebsmount.install diff --git a/85-ebsmount.rules.in b/85-ebsmount.rules similarity index 100% rename from 85-ebsmount.rules.in rename to 85-ebsmount.rules diff --git a/Makefile b/Makefile deleted file mode 100644 index ae1166c..0000000 --- a/Makefile +++ /dev/null @@ -1,79 +0,0 @@ -# standard Python project Makefile -progname = $(shell awk '/^Source/ {print $$2}' debian/control) -name= - -prefix = /usr/local -PATH_BIN = $(prefix)/bin -PATH_ETC = $(destdir)/etc -PATH_INSTALL_LIB = $(prefix)/lib/$(progname) -PATH_UDEV_RULES = $(destdir)/lib/udev/rules.d - -all: help - -debug: - $(foreach v, $V, $(warning $v = $($v))) - @true - -### Extendable targets - -# target: help -help: - @echo '=== Targets:' - @echo 'install [ prefix=path/to/usr ] # default: prefix=$(value prefix)' - @echo 'uninstall [ prefix=path/to/usr ]' - @echo - @echo 'clean' - -# DRY macros -truepath = $(shell echo $1 | sed -e 's/^debian\/$(progname)//') -libpath = $(call truepath,$(PATH_INSTALL_LIB))/$$(basename $1) -subcommand = $(progname)-$$(echo $1 | sed 's|.*/||; s/^cmd_//; s/_/-/g; s/.py$$//') -echo-do = echo $1; $1 - -# first argument: code we execute if there is just one executable module -# second argument: code we execute if there is more than on executable module -define with-py-executables - @modules=$$(find -maxdepth 1 -type f -name '*.py' -perm -100); \ - modules_len=$$(echo $$modules | wc -w); \ - if [ $$modules_len = 1 ]; then \ - module=$$modules; \ - $(call echo-do, $1); \ - elif [ $$modules_len -gt 1 ]; then \ - for module in $$modules; do \ - $(call echo-do, $2); \ - done; \ - fi; -endef - -# set path bin in udev rules -%.rules: %.rules.in - sed "s|@PATH_BIN@|$(call truepath,$(PATH_BIN))|g" $< > $@ - -# target: install -install: 85-ebsmount.rules - @echo - @echo \*\* CONFIG: prefix = $(prefix) \*\* - @echo - - install -d $(PATH_BIN) $(PATH_ETC) $(PATH_INSTALL_LIB) $(PATH_UDEV_RULES) - cp *.conf $(PATH_ETC) - cp *.py $(PATH_INSTALL_LIB) - cp *.rules $(PATH_UDEV_RULES) - - $(call with-py-executables, \ - ln -fs $(call libpath, $$module) $(PATH_BIN)/$(progname), \ - ln -fs $(call libpath, $$module) $(PATH_BIN)/$(call subcommand, $$module)) - -# target: uninstall -uninstall: - rm -rf $(PATH_INSTALL_LIB) - rm -f $(PATH_ETC)/ebsmount.conf - rm -f $(PATH_UDEV_RULES)/85-ebsmount.rules - - $(call with-py-executables, \ - rm -f $(PATH_BIN)/$(progname), \ - rm -f $(PATH_BIN)/$(call subcommand, $$module)) - -# target: clean -clean: - rm -f *.pyc *.pyo *.rules _$(progname) diff --git a/cmd_manual.py b/cmd_manual.py index 47b9a36..9d8f3df 100755 --- a/cmd_manual.py +++ b/cmd_manual.py @@ -36,14 +36,14 @@ def usage(e=None): if e: - print >> sys.stderr, "error: " + str(e) + print("error: " + str(e), file=sys.stderr) - print >> sys.stderr, "Syntax: %s [-opts] " % sys.argv[0] - print >> sys.stderr, __doc__.strip() + print("Syntax: %s [-opts] " % sys.argv[0], file=sys.stderr) + print(__doc__.strip(), file=sys.stderr) sys.exit(1) def fatal(s): - print >> sys.stderr, "error: " + str(s) + print("error: " + str(s), file=sys.stderr) sys.exit(1) def _expected_devpath(devname, devpaths): @@ -64,7 +64,7 @@ def _expected_devpath(devname, devpaths): def main(): try: opts, args = getopt.gnu_getopt(sys.argv[1:], 'h', ['format=']) - except getopt.GetoptError, e: + except getopt.GetoptError as e: usage(e) filesystem = None diff --git a/cmd_udev.py b/cmd_udev.py index 3680b03..24bfd1a 100755 --- a/cmd_udev.py +++ b/cmd_udev.py @@ -41,14 +41,14 @@ def usage(e=None): if e: - print >> sys.stderr, "error: " + str(e) + print("error: " + str(e), file=sys.stderr) - print >> sys.stderr, "Syntax: %s " % sys.argv[0] - print >> sys.stderr, __doc__.strip() + print("Syntax: %s " % sys.argv[0], file=sys.stderr) + print(__doc__.strip(), file=sys.stderr) sys.exit(1) def fatal(s): - print >> sys.stderr, "error: " + str(s) + print("error: " + str(s), file=sys.stderr) sys.exit(1) def _expected_devpath(devpath, devpaths): diff --git a/debian/control b/debian/control index fd20984..2902995 100644 --- a/debian/control +++ b/debian/control @@ -1,20 +1,18 @@ Source: ebsmount Section: misc Priority: optional -Maintainer: Alon Swartz +Maintainer: Jeremy Davis Build-Depends: debhelper (>= 10), - python-all (>= 2.6.6-3~), + python3-all (>= 3.6~), + dh-python Standards-Version: 4.0.0 -X-Python-Version: >= 2.6 Package: ebsmount Architecture: any Depends: - dh-python, ${misc:Depends}, - ${python:Depends}, - turnkey-pylib, + ${python3:Depends}, udev, Description: Automatically mount EC2/Eucalyptus EBS devices Automatically mounts EBS (Elastic Block Storage) devices when they are diff --git a/debian/ebsmount.install b/debian/ebsmount.install new file mode 100644 index 0000000..e967865 --- /dev/null +++ b/debian/ebsmount.install @@ -0,0 +1,2 @@ +85-ebsmount.rules usr/lib/udev/rules.d/ +ebsmount.conf etc/ebsmount.conf diff --git a/udevdb.py b/udevdb.py index 987a670..adca4cc 100644 --- a/udevdb.py +++ b/udevdb.py @@ -50,7 +50,7 @@ def _parse_raw_data(self, s): self.env[name] = val.lstrip("=") def _get_volinfo(self): - if self.env.has_key('DEVTYPE') and self.env['DEVTYPE'] == 'disk': + if 'DEVTYPE' in self.env and self.env['DEVTYPE'] == 'disk': try: volume_info = getoutput('vol_id /dev/%s' % self.name) except ExecError: @@ -58,7 +58,7 @@ def _get_volinfo(self): for value in volume_info.splitlines(): name, val = value.split("=") - if self.env.has_key(name): + if name in self.env: continue if not val: @@ -87,16 +87,16 @@ def _disk_devices(): """debug/test method to print disk devices""" devices = query() for dev in devices: - if dev.env.has_key('DEVTYPE') and dev.env['DEVTYPE'] == 'disk': - print '/dev/' + dev.name + if 'DEVTYPE' in dev.env and dev.env['DEVTYPE'] == 'disk': + print('/dev/' + dev.name) - attrs = dev.env.keys() + attrs = list(dev.env.keys()) attrs.sort() column_len = max([ len(attr) + 1 for attr in attrs ]) for attr in attrs: name = attr + ":" - print " %s %s" % (name.ljust(column_len), dev.env[attr]) - print + print(" %s %s" % (name.ljust(column_len), dev.env[attr])) + print() def main(): _disk_devices() #used in debugging/testing diff --git a/utils.py b/utils.py index 8ec24c5..2bea9d2 100644 --- a/utils.py +++ b/utils.py @@ -27,9 +27,9 @@ class EBSMountConf(ConfFile): def log(devname, s): entry = "%s: %s" % (devname, s) file(config.logfile, 'a').write(entry + "\n") - print entry + print(entry) -def mkdir_parents(path, mode=0777): +def mkdir_parents(path, mode=0o777): """mkdir 'path' recursively (I.e., equivalent to mkdir -p)""" dirs = path.split("/") for i in range(2, len(dirs) + 1): From dea81980ec6298095001bfe7514e150688c9e908 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Thu, 3 Feb 2022 06:03:21 +0000 Subject: [PATCH 09/44] More work done, most of Debian packaging stuff should be good now. --- debian/ebsmount.install | 4 +++- debian/ebsmount.links | 2 ++ ebsmount.py => ebsmount_lib/__init__.py | 0 udevdb.py => ebsmount_lib/udevdb.py | 0 utils.py => ebsmount_lib/utils.py | 0 setup.py | 13 +++++++++++++ 6 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 debian/ebsmount.links rename ebsmount.py => ebsmount_lib/__init__.py (100%) rename udevdb.py => ebsmount_lib/udevdb.py (100%) rename utils.py => ebsmount_lib/utils.py (100%) create mode 100755 setup.py diff --git a/debian/ebsmount.install b/debian/ebsmount.install index e967865..6d436ee 100644 --- a/debian/ebsmount.install +++ b/debian/ebsmount.install @@ -1,2 +1,4 @@ 85-ebsmount.rules usr/lib/udev/rules.d/ -ebsmount.conf etc/ebsmount.conf +ebsmount.conf etc/ +cmd_manual.py usr/lib/ebsmount/ +cmd_udev.py usr/lib/ebsmount/ diff --git a/debian/ebsmount.links b/debian/ebsmount.links new file mode 100644 index 0000000..f7eeb9c --- /dev/null +++ b/debian/ebsmount.links @@ -0,0 +1,2 @@ +/usr/lib/ebsmount/cmd_manual.py /usr/bin/ebsmount-manual +/usr/lib/ebsmount/cmd_udev.py /usr/bin/ebsmount-udev diff --git a/ebsmount.py b/ebsmount_lib/__init__.py similarity index 100% rename from ebsmount.py rename to ebsmount_lib/__init__.py diff --git a/udevdb.py b/ebsmount_lib/udevdb.py similarity index 100% rename from udevdb.py rename to ebsmount_lib/udevdb.py diff --git a/utils.py b/ebsmount_lib/utils.py similarity index 100% rename from utils.py rename to ebsmount_lib/utils.py diff --git a/setup.py b/setup.py new file mode 100755 index 0000000..0a573d0 --- /dev/null +++ b/setup.py @@ -0,0 +1,13 @@ +#!/usr/bin/python3 + +from distutils.core import setup + +setup( + name="ebsmount", + version="0.95", + author="Jeremy Davis", + author_email="jeremy@turnkeylinux.org", + url="https://github.com/turnkeylinux/ebsmount", + packages=["ebsmount_lib"], + scripts=["cmd_manual.py", "cmd_udev.py"] +) From 0a5bf9999fe90c8feac62bdaca1085dc810028e5 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Thu, 3 Feb 2022 07:53:21 +0000 Subject: [PATCH 10/44] Updated cmd_manual.py to use argparse & subprocess. --- cmd_manual.py | 77 ++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/cmd_manual.py b/cmd_manual.py index 9d8f3df..7418698 100755 --- a/cmd_manual.py +++ b/cmd_manual.py @@ -1,5 +1,6 @@ -#!/usr/bin/python -# Copyright (c) 2010 Alon Swartz +#!/usr/bin/python3 +# Copyright (c) 2010-2021 Alon Swartz +# Copyright (c) 2022 TurnKey GNU/Linux # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -28,24 +29,19 @@ import re import os import sys -import getopt +import argparse +import subprocess +from subprocess import PIPE, STDOUT -import ebsmount -import executil -from utils import config, is_mounted +import ebsmount_lib as ebsmount +from ebsmount_lib.utils import config, is_mounted -def usage(e=None): - if e: - print("error: " + str(e), file=sys.stderr) - - print("Syntax: %s [-opts] " % sys.argv[0], file=sys.stderr) - print(__doc__.strip(), file=sys.stderr) - sys.exit(1) def fatal(s): print("error: " + str(s), file=sys.stderr) sys.exit(1) + def _expected_devpath(devname, devpaths): """ugly hack to test expected structure of devpath""" raw_output = executil.getoutput('udevadm info -a -n %s' % devname) @@ -61,41 +57,48 @@ def _expected_devpath(devname, devpaths): return False -def main(): - try: - opts, args = getopt.gnu_getopt(sys.argv[1:], 'h', ['format=']) - except getopt.GetoptError as e: - usage(e) - - filesystem = None - for opt, val in opts: - if opt == '-h': - usage() - if opt == '--format': - filesystem = val - - if not len(args) == 1: - usage() - - devname = args[0] - if not os.path.exists(devname): - fatal("%s does not exist" % devname) +def main(): + parser = argparse.ArgumentParser( + prog='ebsmount-manual', + description="manually mount EBS device (simulates udev add trigger)" + ) + parser.add_argument( + 'devname', + nargs=1, + help="EBS device to mount (e.g., /dev/xvdf, /dev/vda)" + ) + parser.add_argument( + '--format', + dest="filesystem" + nargs='?', + default=None, + choices=["ext2", "ext3", "ext4"], + const="ext4", + help="Format device prior to mount (defaults to ext4 unless specified)" + ) + args = parser.parse_args() + if not os.path.exists(args.devname): + raise argparse.ArgumentTypeError(f"{devname} does not exist") if not _expected_devpath(devname, config.devpaths.split()): - fatal("devpath not of expected structure, or failed lookup") + raise argparse.ArgumentTypeError( + "devpath not of expected structure, or failed lookup") if filesystem: if is_mounted(devname): - fatal("%s is mounted" % devname) + raise argparse.ArgumentTypeError(f"{devname} is mounted") if not filesystem in config.filesystems.split(): - fatal("%s is not supported in %s" % (filesystem, config.CONF_FILE)) + raise argparse.ArgumentTypeError( + f"{filesystem} is not supported in {config.CONF_FILE}") - executil.system("mkfs." + filesystem, "-q", devname) + format_dev = subprocess([f"mkfs.{filesystem}", "-q", devname], + stdout=PIPE, stderr=STDOUT, text=True) + if format_dev.returncode != 0: + fatal(f"formating {filesystem} failed: {format_dev.stdout}") ebsmount.ebsmount_add(devname, config.mountdir) if __name__=="__main__": main() - From 18aef38367bb3c5d7ae366720501a207a2b5ad94 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Thu, 3 Feb 2022 22:06:37 +0000 Subject: [PATCH 11/44] cmd_manual.py - bugfix and tidy code. --- cmd_manual.py | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/cmd_manual.py b/cmd_manual.py index 7418698..98baa0c 100755 --- a/cmd_manual.py +++ b/cmd_manual.py @@ -4,7 +4,7 @@ # # 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 2 of +# published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, @@ -15,16 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -"""EBS Mount - manually mount EBS device (simulates udev add trigger) - -Arguments: - - device EBS device to mount (e.g., /dev/xvdf, /dev/vda) - -Options: - - --format=FS Format device prior to mount (e.g., --format=ext3) -""" +"""EBS Mount - manually mount EBS device (simulates udev add trigger)""" import re import os @@ -61,7 +52,8 @@ def _expected_devpath(devname, devpaths): def main(): parser = argparse.ArgumentParser( prog='ebsmount-manual', - description="manually mount EBS device (simulates udev add trigger)" + description=("EBS Mount - manually mount EBS device" + " (simulates udev add trigger)") ) parser.add_argument( 'devname', @@ -70,7 +62,7 @@ def main(): ) parser.add_argument( '--format', - dest="filesystem" + dest="filesystem", nargs='?', default=None, choices=["ext2", "ext3", "ext4"], @@ -89,7 +81,7 @@ def main(): if is_mounted(devname): raise argparse.ArgumentTypeError(f"{devname} is mounted") - if not filesystem in config.filesystems.split(): + if filesystem not in config.filesystems.split(): raise argparse.ArgumentTypeError( f"{filesystem} is not supported in {config.CONF_FILE}") @@ -100,5 +92,6 @@ def main(): ebsmount.ebsmount_add(devname, config.mountdir) -if __name__=="__main__": + +if __name__ == "__main__": main() From 9094cf9bca3f03804e70200566c0e1a27247b599 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 4 Feb 2022 00:00:19 +0000 Subject: [PATCH 12/44] Replace all mentions of 'Eucalyptus' with 'OpenStack' (Eucalyptus is dead). --- 85-ebsmount.rules | 2 +- cmd_udev.py | 2 +- debian/control | 2 +- docs/README | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/85-ebsmount.rules b/85-ebsmount.rules index 24faa66..b857f37 100644 --- a/85-ebsmount.rules +++ b/85-ebsmount.rules @@ -4,6 +4,6 @@ KERNEL=="xvd[f-p]", SUBSYSTEM=="block", ATTRS{devtype}=="vbd", ACTION=="add", RUN+="@PATH_BIN@/ebsmount-udev add" KERNEL=="xvd[f-p]", SUBSYSTEM=="block", ACTION=="remove", RUN+="@PATH_BIN@/ebsmount-udev remove" -# Eucalyptus / OpenStack +# OpenStack KERNEL=="vd[a-z]*", SUBSYSTEM=="block", ACTION=="add", RUN+="@PATH_BIN@/ebsmount-udev add" KERNEL=="vd[a-z]*", SUBSYSTEM=="block", ACTION=="remove", RUN+="@PATH_BIN@/ebsmount-udev remove" diff --git a/cmd_udev.py b/cmd_udev.py index 24bfd1a..85f9a66 100755 --- a/cmd_udev.py +++ b/cmd_udev.py @@ -25,7 +25,7 @@ DEVNAME (required: e.g., /dev/xvdf) PHYSDEVPATH (required: e.g., /devices/xen/vbd-2160) -Environment variables (Eucalyptus): +Environment variables (OpenStack): DEVNAME (required: e.g., /dev/vda) DEVPATH (required: e.g., /devices/virtio-pci/virtio0/block/vda) diff --git a/debian/control b/debian/control index 2902995..bac9bd6 100644 --- a/debian/control +++ b/debian/control @@ -14,7 +14,7 @@ Depends: ${misc:Depends}, ${python3:Depends}, udev, -Description: Automatically mount EC2/Eucalyptus EBS devices +Description: Automatically mount EC2/OpenStack EBS devices Automatically mounts EBS (Elastic Block Storage) devices when they are attached, supports formatted devices as well as partitions, uniquely identifiable mount points, and hooking scripts execution upon mount. diff --git a/docs/README b/docs/README index f5b2ea7..e872244 100644 --- a/docs/README +++ b/docs/README @@ -1,4 +1,4 @@ -EBSmount: Automatically mount EC2/Eucalyptus EBS devices +EBSmount: Automatically mount EC2/OpenStack EBS devices ======================================================== EBSmount has 2 commands: @@ -8,7 +8,7 @@ EBSmount has 2 commands: Features: - - Supports Amazon EC2 and Eucalyptus EBS devices + - Supports Amazon EC2 and OpenStack EBS devices - Automatically mounts EBS devices when they are attached (via udev) - Supports formatted devices, as well as partitions - Ignores unformatted devices and unsupported filesystems From 16bbd252463ae20c3374c42c98f46ca63c5ef3ae Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 4 Feb 2022 05:56:05 +0000 Subject: [PATCH 13/44] Updated cmd_udev.py to use argparse - I suspect still needs work. --- cmd_udev.py | 85 +++++++++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/cmd_udev.py b/cmd_udev.py index 85f9a66..4d5825f 100755 --- a/cmd_udev.py +++ b/cmd_udev.py @@ -1,9 +1,10 @@ -#!/usr/bin/python -# Copyright (c) 2010 Alon Swartz +#!/usr/bin/python3 +# Copyright (c) 2010-2021 Alon Swartz +# Copyright (c) 2022 TurnKey GNU/Linux # # 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 2 of +# published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, @@ -14,43 +15,34 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -"""EBS Mount - triggered by udev on EBS attach and detach - -Arguments: - - action action trigger (add | remove) - -Environment variables (Amazon EC2): - - DEVNAME (required: e.g., /dev/xvdf) - PHYSDEVPATH (required: e.g., /devices/xen/vbd-2160) - -Environment variables (OpenStack): - - DEVNAME (required: e.g., /dev/vda) - DEVPATH (required: e.g., /devices/virtio-pci/virtio0/block/vda) - -""" +"""EBS Mount - triggered by udev on EBS attach and detach""" import re import os import sys +import argparse -import ebsmount -from utils import log, config +import ebsmount_lib as ebsmount +from ebsmount_lib.utils import log, config -def usage(e=None): - if e: - print("error: " + str(e), file=sys.stderr) +ENVVARS = """ +environment variables (required): + +platfrom env var example value +-------- ------- ------------- +AWS EC2 DEVNAME /dev/xvdf + PHYSDEVPATH /devices/vbd-51792/block/xvdf + +OpenStack DEVNAME /dev/vda + DEVPATH /devices/virtio-pci/virtio0/block/vda +""" - print("Syntax: %s " % sys.argv[0], file=sys.stderr) - print(__doc__.strip(), file=sys.stderr) - sys.exit(1) def fatal(s): print("error: " + str(s), file=sys.stderr) sys.exit(1) + def _expected_devpath(devpath, devpaths): for pattern in devpaths: if re.search(pattern, devpath): @@ -58,35 +50,44 @@ def _expected_devpath(devpath, devpaths): return False + def main(): - if not len(sys.argv) == 2: - usage() + parser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, + prog='ebsmount-udev', + description="EBS Mount - triggered by udev on EBS attach and detach", + epilog=ENVVARS + ) + parser.add_argument( + 'action', + nargs=1, + choices=["add", "remove"], + help="action trigger" + ) + args = parser.parse_args() if not config.enabled.lower() == "true": - fatal('ebsmount is not enabled (%s)' % config.CONF_FILE) + fatal(f'ebsmount is not enabled ({config.CONF_FILE})') - action = sys.argv[1] devname = os.getenv('DEVNAME', None) devpath = os.getenv('PHYSDEVPATH', os.getenv('DEVPATH', None)) - if not action in ('add', 'remove'): - usage('action must be one of: add, remove') - if not devname: - usage('DEVNAME is required') + raise argparse.ArgumentTypeError('DEVNAME is required') if not devpath: - usage('PHYSDEVPATH or DEVPATH is required') + raise argparse.ArgumentTypeError('PHYSDEVPATH or DEVPATH is required') if not _expected_devpath(devpath, config.devpaths.split()): - usage('PHYSDEVPATH/DEVPATH is not of the expected structure') + raise argparse.ArgumentTypeError( + 'PHYSDEVPATH/DEVPATH is not of the expected structure') # log trigger - log(devname, "received %s trigger" % action) + log(devname, f"received {args.action} trigger") - func = getattr(ebsmount, 'ebsmount_' + action) + func = getattr(ebsmount, 'ebsmount_' + args.action) func(devname, config.mountdir) -if __name__=="__main__": - main() +if __name__ == "__main__": + main() From b794ed534f644fa1a2705b4514d6205841fb0e56 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 4 Feb 2022 06:55:17 +0000 Subject: [PATCH 14/44] Should be mostly done - although may need some more polishing... --- ebsmount_lib/__init__.py | 45 +++++++++++++++++++++++----------------- ebsmount_lib/udevdb.py | 39 +++++++++++++++++----------------- ebsmount_lib/utils.py | 28 ++++++++++++++++--------- 3 files changed, 63 insertions(+), 49 deletions(-) diff --git a/ebsmount_lib/__init__.py b/ebsmount_lib/__init__.py index 6f19fa4..4707f24 100644 --- a/ebsmount_lib/__init__.py +++ b/ebsmount_lib/__init__.py @@ -1,8 +1,9 @@ -# Copyright (c) 2010 Alon Swartz +# Copyright (c) 2010-2021 Alon Swartz +# Copyright (c) 2022 TurnKey GNU/Linux # # 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 2 of +# published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, @@ -14,43 +15,46 @@ # along with this program. If not, see . import os -from os.path import * +# XXX TODO may need additional imports below (moving from importing *) +from os.path import join import pwd -import udevdb -from executil import system -from utils import config, log, is_mounted, mount +from .udevdb import query +from .utils import config, log, is_mounted, mount + def ebsmount_add(devname, mountdir): """ebs device attached""" matching_devices = [] - for device in udevdb.query(): + for device in query(): if device.name.startswith(basename(devname)): matching_devices.append(device) for device in matching_devices: devpath = join('/dev', device.name) - mountpath = join(mountdir, device.env.get('ID_FS_UUID', devpath[-1])[:6]) - mountoptions = ",".join(config.mountoptions.split()) + mountpath = join(mountdir, device.env.get( + 'ID_FS_UUID', devpath[-1])[:6]) + mountoptions = mountoptions.split() hookspath = join(mountpath, ".ebsmount") filesystem = device.env.get('ID_FS_TYPE', None) if not filesystem: - log(devname, "could not identify filesystem: %s" % devpath) + log(devname, f"could not identify filesystem: {devpath}") continue - if not filesystem in config.filesystems.split(): - log(devname, "filesystem (%s) not supported: %s" % (filesystem,devpath)) + if filesystem not in config.filesystems.split(): + log(devname, + f"filesystem ({filesystem}) not supported: {devpath}") continue if is_mounted(devpath): - log(devname, "already mounted: %s" % devpath) + log(devname, f"already mounted: {devpath}") continue mount(devpath, mountpath, mountoptions) - log(devname, "mounted %s %s (%s)" % (devpath, mountpath, mountoptions)) + log(devname, f"mounted {devpath} {mountpath} ({mountoptions})") if exists(hookspath): hooks = os.listdir(hookspath) @@ -63,18 +67,22 @@ def ebsmount_add(devname, mountdir): for file in hooks: fpath = join(hookspath, file) if not os.access(fpath, os.X_OK): - log(devname, "skipping hook: '%s', not executable" % file) + log(devname, f"skipping hook: '{file}', not executable") continue - if not os.stat(fpath).st_uid == 0 or not os.stat(fpath).st_gid == 0: - log(devname, "skipping hook: '%s', not owned root:root" % file) + if (not os.stat(fpath).st_uid == 0 or + not os.stat(fpath).st_gid == 0): + log(devname, + f"skipping hook: '{file}', not owned root:root") continue - log(devname, "executing hook: %s" % file) + log(devname, f"executing hook: {file}") os.environ['HOME'] = pwd.getpwuid(os.getuid()).pw_dir os.environ['MOUNTPOINT'] = mountpath + # XXX TODO - this command needs porting to subprocess! system("/bin/bash --login -c '%s' 2>&1 | tee -a %s" % (fpath, config.logfile)) + def ebsmount_remove(devname, mountdir): """ebs device detached""" @@ -89,4 +97,3 @@ def ebsmount_remove(devname, mountdir): if not mounted: os.rmdir(mountdir) - diff --git a/ebsmount_lib/udevdb.py b/ebsmount_lib/udevdb.py index adca4cc..ce7c121 100644 --- a/ebsmount_lib/udevdb.py +++ b/ebsmount_lib/udevdb.py @@ -1,8 +1,9 @@ -# Copyright (c) 2010 Alon Swartz +# Copyright (c) 2010-2021 Alon Swartz +# Copyright (c) 2022 TurnKey GNU/Linux # # 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 2 of +# published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, @@ -13,7 +14,9 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from executil import ExecError, getoutput +import subprocess +from subprocess import PIPE, STDOUT + class Device: """class to hold device information enumerated from udev database""" @@ -51,10 +54,11 @@ def _parse_raw_data(self, s): def _get_volinfo(self): if 'DEVTYPE' in self.env and self.env['DEVTYPE'] == 'disk': - try: - volume_info = getoutput('vol_id /dev/%s' % self.name) - except ExecError: + proc = subprocess(["vol_id", f"/dev/{self.name}"], + capture_output=True, text=True) + if proc.returncode != 0: return + volume_info = proc.stdout for value in volume_info.splitlines(): name, val = value.split("=") @@ -66,23 +70,25 @@ def _get_volinfo(self): self.env[name] = val + def query(device=None, volinfo=True): """query udev database and return device(s) information if no device is specified, all devices will be returned optionally query volume info (vol_id) on disk devices """ if device: - cmd = "udevadm info --query all --name %s" % device + cmd = ["udevadm", "info", "--query", "all", "--name", device] else: - cmd = "udevadm info --export-db" + cmd = ["udevadm", "info", "--export-db"] devices = [] - for s in getoutput(cmd + " 2>/dev/null").split('\n\n'): + output = subprocess(cmd, stdout=PIPE, stderr=STDOUT, test=True).stdout + for s in output.split('\n\n'): devices.append(Device(s, volinfo)) return devices - - + + def _disk_devices(): """debug/test method to print disk devices""" devices = query() @@ -92,15 +98,8 @@ def _disk_devices(): attrs = list(dev.env.keys()) attrs.sort() - column_len = max([ len(attr) + 1 for attr in attrs ]) + column_len = max([len(attr) + 1 for attr in attrs]) for attr in attrs: name = attr + ":" - print(" %s %s" % (name.ljust(column_len), dev.env[attr])) + print(f" {name.ljust(column_len)} {dev.env[attr}") print() - -def main(): - _disk_devices() #used in debugging/testing - -if __name__ == '__main__': - main() - diff --git a/ebsmount_lib/utils.py b/ebsmount_lib/utils.py index 2bea9d2..98658b3 100644 --- a/ebsmount_lib/utils.py +++ b/ebsmount_lib/utils.py @@ -1,8 +1,9 @@ -# Copyright (c) 2010 Alon Swartz +# Copyright (c) 2010-2021 Alon Swartz +# Copyright (c) 2022 TurnKey GNU/Linux # # 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 2 of +# published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, @@ -14,21 +15,26 @@ # along with this program. If not, see . import os -import executil +import subprocess + from conffile import ConfFile + class EBSMountConf(ConfFile): CONF_FILE = '/etc/ebsmount.conf' - REQUIRED = ['enabled', 'runhooks', 'mountdir', 'mountoptions', 'filesystems', 'logfile', 'devpaths'] + REQUIRED = ['enabled', 'runhooks', 'mountdir', 'mountoptions', + 'filesystems', 'logfile', 'devpaths'] + config = EBSMountConf() def log(devname, s): - entry = "%s: %s" % (devname, s) + entry = f"{devname}: {s}" file(config.logfile, 'a').write(entry + "\n") print(entry) + def mkdir_parents(path, mode=0o777): """mkdir 'path' recursively (I.e., equivalent to mkdir -p)""" dirs = path.split("/") @@ -39,20 +45,22 @@ def mkdir_parents(path, mode=0o777): os.mkdir(dir, mode) + def is_mounted(path): """test if path is mounted""" - mounts = file("/proc/mounts").read() + with open("/proc/mounts") as fob: + mounts = fob.read() if mounts.find(path) != -1: return True return False -def mount(devpath, mountpath, options=None): + +def mount(devpath, mountpath, options=[]): """mount devpath to mountpath with specified options (creates mountpath)""" if not os.path.exists(mountpath): mkdir_parents(mountpath) if options: - executil.system("mount", "-o", options, devpath, mountpath) + subprocess(["mount", "-o", *options, devpath, mountpath]) else: - executil.system("mount", devpath, mountpath) - + subprocess(["mount", devpath, mountpath]) From 2e9e5ec2089c25a9cd58292813c81727ddf11d0c Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 25 Mar 2022 01:41:10 +0000 Subject: [PATCH 15/44] Remove old dependencies. --- conffile.py | 98 ----------------------------------------------------- executil.py | 96 --------------------------------------------------- 2 files changed, 194 deletions(-) delete mode 100644 conffile.py delete mode 100644 executil.py diff --git a/conffile.py b/conffile.py deleted file mode 100644 index 6272634..0000000 --- a/conffile.py +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright (c) 2010 Alon Swartz -# -# This file is part of turnkey-pylib. -# -# turnkey-pylib is open source 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. - -import os - -class ConfFileError(Exception): - pass - -class ConfFile(dict): - """Configuration file class (targeted at simple shell type configs) - - Usage: - - class foo(ConfFile): - CONF_FILE = /path/to/conf - REQUIRED = ['arg1' ,'arg2'] - - conf = foo() - print conf.arg1 # display ARG1 value from /path/to/conf - conf.arg2 = value # set ARG2 value - conf.write() # write new/update config to /path/to/conf - - Format: - - # comments are ignored - NAME=alon - AGE=29 - - """ - CONF_FILE = None - REQUIRED = [] - SET_ENVIRON = False - - def __init__(self): - self.read() - self.validate_required() - if self.SET_ENVIRON: - self.set_environ() - - def validate_required(self, required=[]): - """raise exception if required arguments are not set - REQUIRED validated by default, but can be optionally extended - """ - self.REQUIRED.extend(required) - for attr in self.REQUIRED: - if not self.has_key(attr): - error = "%s not specified in %s" % (attr.upper(), self.CONF_FILE) - raise ConfFileError(error) - - def set_environ(self): - """set environment (run on initialization if SET_ENVIRON)""" - for key, val in self.items(): - os.environ[key.upper()] = val - - def read(self): - if not self.CONF_FILE or not os.path.exists(self.CONF_FILE): - return - - for line in file(self.CONF_FILE).readlines(): - line = line.rstrip() - - if not line or line.startswith("#"): - continue - - key, val = line.split("=") - self[key.strip().lower()] = val.strip() - - def write(self): - fh = file(self.CONF_FILE, "w") - items = self.items() - items.sort() - for key, val in items: - print >> fh, "%s=%s" % (key.upper(), val) - - fh.close() - - def items(self): - items = [] - for key in self: - items.append((key, self[key])) - - return items - - def __getattr__(self, key): - try: - return self[key] - except KeyError, e: - raise AttributeError(e) - - def __setattr__(self, key, val): - self[key] = val - diff --git a/executil.py b/executil.py deleted file mode 100644 index e879a60..0000000 --- a/executil.py +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright (c) 2010 Liraz Siri -# -# This file is part of turnkey-pylib. -# -# turnkey-pylib is open source 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 module contains high-level convenience functions for safe -command execution that properly escape arguments and raise an -ExecError exception on error -""" -import os -import sys -import commands - -from subprocess import Popen, PIPE - -mkarg = commands.mkarg - -class ExecError(Exception): - """Accessible attributes: - command executed command - exitcode non-zero exitcode returned by command - output error output returned by command - """ - def __init__(self, command, exitcode, output=None): - Exception.__init__(self, command, exitcode, output) - - self.command = command - self.exitcode = exitcode - self.output = output - - def __str__(self): - str = "non-zero exitcode (%d) for command: %s" % (self.exitcode, - self.command) - if self.output: - str += "\n" + self.output - return str - -def fmt_command(command, *args): - return command + " ".join([mkarg(arg) for arg in args]) - -def system(command, *args): - """Executes with <*args> -> None - If command returns non-zero exitcode raises ExecError""" - - sys.stdout.flush() - sys.stderr.flush() - - command = fmt_command(command, *args) - error = os.system(command) - if error: - exitcode = os.WEXITSTATUS(error) - raise ExecError(command, exitcode) - -def getoutput(command, *args): - """Executes with <*args> -> output - If command returns non-zero exitcode raises ExecError""" - - command = fmt_command(command, *args) - error, output = commands.getstatusoutput(command) - if error: - exitcode = os.WEXITSTATUS(error) - raise ExecError(command, exitcode, output) - - return output - -def getoutput_popen(command, input=None): - """Uses subprocess.Popen to execute , piping into stdin. - If command returns non-zero exitcode raise ExecError. - - Return command output. - """ - - shell=False - if isinstance(command, str): - shell=True - - child = Popen(command, shell=shell, stdin=PIPE, stdout=PIPE, stderr=PIPE) - - errstr = None - try: - outstr, errstr = child.communicate(input) - except OSError: - pass - - errno = child.wait() - if errstr is None: - errstr = child.stderr.read() - - if errno != 0: - raise ExecError(command, errno, errstr) - - return outstr From e8e0e766f22b23c50ed9252cd76e964e6422dc1a Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 25 Mar 2022 02:07:27 +0000 Subject: [PATCH 16/44] (Re)implment minimalist pybuild rules. --- debian/rules | 54 ++++------------------------------------------------ 1 file changed, 4 insertions(+), 50 deletions(-) diff --git a/debian/rules b/debian/rules index 40dba34..51b40e1 100755 --- a/debian/rules +++ b/debian/rules @@ -2,54 +2,8 @@ include /usr/share/dpkg/pkg-info.mk -clean: +%: + dh $@ --buildsystem=pybuild - rm -f -- build-indep-stamp build-arch-stamp - $(MAKE) -- clean - - dh_clean - -build: build-indep build-arch - mkdir -p $(prefix) - -build-indep: build-indep-stamp -build-indep-stamp: - - dh_testdir - - touch -- $@ - -build-arch: build-arch-stamp -build-arch-stamp: - - dh_testdir - - touch -- $@ - -install: - dh_testroot - dh_clean - dh_testdir - dh_installdirs - dh_install - $(MAKE) install prefix=$(prefix) destdir=$(buildroot) - dh_link - -binary-indep: install - dh_testdir - dh_testroot - dh_installdebconf - dh_installdocs docs/ - dh_installman man/ebsmount-manual.1 man/ebsmount-udev.8 - dh_installchangelogs - dh_lintian - dh_compress - dh_installdeb - dh_gencontrol - dh_md5sums - dh_builddeb - -binary-arch: install - -binary: binary-indep binary-arch -.PHONY: clean build build-indep build-arch binary-indep binary-arch binary install +override_dh_auto_install: + dh_auto_install -- prefix=debian/$(DEB_SOURCE)/usr destdir=debian/$(DEB_SOURCE) From 5b78c8288dc0b3dadd314272fe54f94e61972377 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 25 Mar 2022 02:14:04 +0000 Subject: [PATCH 17/44] Fix typo. --- ebsmount_lib/udevdb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ebsmount_lib/udevdb.py b/ebsmount_lib/udevdb.py index ce7c121..c4bd88c 100644 --- a/ebsmount_lib/udevdb.py +++ b/ebsmount_lib/udevdb.py @@ -101,5 +101,5 @@ def _disk_devices(): column_len = max([len(attr) + 1 for attr in attrs]) for attr in attrs: name = attr + ":" - print(f" {name.ljust(column_len)} {dev.env[attr}") + print(f" {name.ljust(column_len)} {dev.env[attr]}") print() From e27efe86e6764b370c8f7a5ddbbb8293321e6d3c Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 25 Mar 2022 02:20:28 +0000 Subject: [PATCH 18/44] Fix missing depends. --- debian/control | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 383155e..0faf6cc 100644 --- a/debian/control +++ b/debian/control @@ -5,7 +5,8 @@ Maintainer: Jeremy Davis Build-Depends: debhelper (>= 10), python3-all (>= 3.6~), - dh-python + dh-python, + turnkey-conffile Standards-Version: 4.1.1 Homepage: https://github.com/turnkeylinux/ebsmount @@ -15,6 +16,7 @@ Depends: ${misc:Depends}, ${python3:Depends}, udev, + turnkey-conffile Description: Automatically mount EC2/OpenStack EBS devices Automatically mounts EBS (Elastic Block Storage) devices when they are attached, supports formatted devices as well as partitions, uniquely From 0bf17178497175d0f807bb2eb4497574fc2ff71b Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 25 Mar 2022 03:06:02 +0000 Subject: [PATCH 19/44] Update gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 0d20b64..e3a9d19 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ *.pyc +__pycache__/ +.mypy_cache/ From a777c4cda6897d4da8304ba70b19faf08f33feca Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 25 Mar 2022 03:20:31 +0000 Subject: [PATCH 20/44] Adjusting conf file location in effort to fix pkg building. --- 85-ebsmount.rules => conf/85-ebsmount.rules | 0 ebsmount.conf => conf/ebsmount.conf | 0 debian/ebsmount.install | 8 ++++---- 3 files changed, 4 insertions(+), 4 deletions(-) rename 85-ebsmount.rules => conf/85-ebsmount.rules (100%) rename ebsmount.conf => conf/ebsmount.conf (100%) diff --git a/85-ebsmount.rules b/conf/85-ebsmount.rules similarity index 100% rename from 85-ebsmount.rules rename to conf/85-ebsmount.rules diff --git a/ebsmount.conf b/conf/ebsmount.conf similarity index 100% rename from ebsmount.conf rename to conf/ebsmount.conf diff --git a/debian/ebsmount.install b/debian/ebsmount.install index 6d436ee..cfffc68 100644 --- a/debian/ebsmount.install +++ b/debian/ebsmount.install @@ -1,4 +1,4 @@ -85-ebsmount.rules usr/lib/udev/rules.d/ -ebsmount.conf etc/ -cmd_manual.py usr/lib/ebsmount/ -cmd_udev.py usr/lib/ebsmount/ +conf/85-ebsmount.rules usr/lib/udev/rules.d/ +conf/*.conf etc/ +cmd_manual.py usr/lib/ebsmount/ +cmd_udev.py usr/lib/ebsmount/ From 8040be62ceae09f8181adc0a0304d08ecc57a6d3 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 25 Mar 2022 07:54:10 +0000 Subject: [PATCH 21/44] Disable tests Workaround issue with conf file not existing when importing utils. --- debian/rules | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/debian/rules b/debian/rules index 51b40e1..66883d6 100755 --- a/debian/rules +++ b/debian/rules @@ -2,8 +2,8 @@ include /usr/share/dpkg/pkg-info.mk +# disable test for now (import test fails as conf file doesn't exist) +export PYBUILD_DISABLE_python3=test + %: dh $@ --buildsystem=pybuild - -override_dh_auto_install: - dh_auto_install -- prefix=debian/$(DEB_SOURCE)/usr destdir=debian/$(DEB_SOURCE) From 424b6eacf29d004ce17fcd37e3b59a9194cdde77 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 25 Mar 2022 08:13:39 +0000 Subject: [PATCH 22/44] Move executables and refactor debian files. --- debian/ebsmount.install | 2 -- debian/ebsmount.links | 5 ++--- cmd_manual.py => ebsmount_manual.py | 0 cmd_udev.py => ebsmount_udev.py | 0 setup.py | 4 ++-- 5 files changed, 4 insertions(+), 7 deletions(-) rename cmd_manual.py => ebsmount_manual.py (100%) rename cmd_udev.py => ebsmount_udev.py (100%) diff --git a/debian/ebsmount.install b/debian/ebsmount.install index cfffc68..1eb56c9 100644 --- a/debian/ebsmount.install +++ b/debian/ebsmount.install @@ -1,4 +1,2 @@ conf/85-ebsmount.rules usr/lib/udev/rules.d/ conf/*.conf etc/ -cmd_manual.py usr/lib/ebsmount/ -cmd_udev.py usr/lib/ebsmount/ diff --git a/debian/ebsmount.links b/debian/ebsmount.links index 54d3391..a8c1da0 100644 --- a/debian/ebsmount.links +++ b/debian/ebsmount.links @@ -1,3 +1,2 @@ -lib/systemd/system/ebsmount@.service etc/systemd/system/ebsmount@.service -/usr/lib/ebsmount/cmd_manual.py /usr/bin/ebsmount-manual -/usr/lib/ebsmount/cmd_udev.py /usr/bin/ebsmount-udev +usr/bin/ebsmount_manual.py usr/bin/ebsmount-manual +usr/bin/ebsmount_udev.py usr/bin/ebsmount-udev diff --git a/cmd_manual.py b/ebsmount_manual.py similarity index 100% rename from cmd_manual.py rename to ebsmount_manual.py diff --git a/cmd_udev.py b/ebsmount_udev.py similarity index 100% rename from cmd_udev.py rename to ebsmount_udev.py diff --git a/setup.py b/setup.py index 0a573d0..f33b7ce 100755 --- a/setup.py +++ b/setup.py @@ -4,10 +4,10 @@ setup( name="ebsmount", - version="0.95", + version="0.96+", author="Jeremy Davis", author_email="jeremy@turnkeylinux.org", url="https://github.com/turnkeylinux/ebsmount", packages=["ebsmount_lib"], - scripts=["cmd_manual.py", "cmd_udev.py"] + scripts=["ebsmount_manual.py", "ebsmount_udev.py"] ) From 30434705aa5c8e8d7ad371523b4c4259fac23556 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 25 Mar 2022 08:22:03 +0000 Subject: [PATCH 23/44] Ensure service template is included. --- ebsmount@.service.in => debian/ebsmount@.service | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ebsmount@.service.in => debian/ebsmount@.service (100%) diff --git a/ebsmount@.service.in b/debian/ebsmount@.service similarity index 100% rename from ebsmount@.service.in rename to debian/ebsmount@.service From 4eb641fc07c606e59a37dff86d7e11c3acc69714 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Mon, 28 Mar 2022 04:55:21 +0000 Subject: [PATCH 24/44] Check devpath env var. --- ebsmount_udev.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ebsmount_udev.py b/ebsmount_udev.py index 59cc1bb..4d5825f 100755 --- a/ebsmount_udev.py +++ b/ebsmount_udev.py @@ -70,6 +70,7 @@ def main(): fatal(f'ebsmount is not enabled ({config.CONF_FILE})') devname = os.getenv('DEVNAME', None) + devpath = os.getenv('PHYSDEVPATH', os.getenv('DEVPATH', None)) if not devname: raise argparse.ArgumentTypeError('DEVNAME is required') From 52eb3d8d50b732387cdedadab2cb2d6d4dd0a2b4 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Mon, 28 Mar 2022 05:17:34 +0000 Subject: [PATCH 25/44] Improve error if env vars not set. --- ebsmount_udev.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ebsmount_udev.py b/ebsmount_udev.py index 4d5825f..65bf7a4 100755 --- a/ebsmount_udev.py +++ b/ebsmount_udev.py @@ -73,13 +73,13 @@ def main(): devpath = os.getenv('PHYSDEVPATH', os.getenv('DEVPATH', None)) if not devname: - raise argparse.ArgumentTypeError('DEVNAME is required') + raise parser.error('DEVNAME is required') if not devpath: - raise argparse.ArgumentTypeError('PHYSDEVPATH or DEVPATH is required') + raise parser.error('PHYSDEVPATH or DEVPATH is required') if not _expected_devpath(devpath, config.devpaths.split()): - raise argparse.ArgumentTypeError( + raise parser.error( 'PHYSDEVPATH/DEVPATH is not of the expected structure') # log trigger From 033f8dd9da722e2f56719e2117dae51449ee6860 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Mon, 28 Mar 2022 22:12:01 +0000 Subject: [PATCH 26/44] Tidy up bugs and issues. --- ebsmount_lib/udevdb.py | 6 +++--- ebsmount_manual.py | 16 ++++++++++------ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/ebsmount_lib/udevdb.py b/ebsmount_lib/udevdb.py index c4bd88c..d9d81db 100644 --- a/ebsmount_lib/udevdb.py +++ b/ebsmount_lib/udevdb.py @@ -54,8 +54,8 @@ def _parse_raw_data(self, s): def _get_volinfo(self): if 'DEVTYPE' in self.env and self.env['DEVTYPE'] == 'disk': - proc = subprocess(["vol_id", f"/dev/{self.name}"], - capture_output=True, text=True) + proc = subprocess.run(["vol_id", f"/dev/{self.name}"], + capture_output=True, text=True) if proc.returncode != 0: return volume_info = proc.stdout @@ -82,7 +82,7 @@ def query(device=None, volinfo=True): cmd = ["udevadm", "info", "--export-db"] devices = [] - output = subprocess(cmd, stdout=PIPE, stderr=STDOUT, test=True).stdout + output = subprocess.run(cmd, stdout=PIPE, stderr=STDOUT, text=True).stdout for s in output.split('\n\n'): devices.append(Device(s, volinfo)) diff --git a/ebsmount_manual.py b/ebsmount_manual.py index 98baa0c..16b8a66 100755 --- a/ebsmount_manual.py +++ b/ebsmount_manual.py @@ -35,7 +35,9 @@ def fatal(s): def _expected_devpath(devname, devpaths): """ugly hack to test expected structure of devpath""" - raw_output = executil.getoutput('udevadm info -a -n %s' % devname) + raw_output = subprocess.run(['udevadm', 'info', '-a', '-n', devname], + stderr=STDOUT, stdout=PIPE, text=True + ).stdout for line in raw_output.splitlines(): line = line.strip() @@ -70,19 +72,21 @@ def main(): help="Format device prior to mount (defaults to ext4 unless specified)" ) args = parser.parse_args() - if not os.path.exists(args.devname): - raise argparse.ArgumentTypeError(f"{devname} does not exist") + devname = args.devname[0] + filesystem = args.filesystem + if not os.path.exists(devname): + raise parser.error(f"{devname} does not exist") if not _expected_devpath(devname, config.devpaths.split()): - raise argparse.ArgumentTypeError( + raise parser.error( "devpath not of expected structure, or failed lookup") if filesystem: if is_mounted(devname): - raise argparse.ArgumentTypeError(f"{devname} is mounted") + raise parser.error(f"{devname} is mounted") if filesystem not in config.filesystems.split(): - raise argparse.ArgumentTypeError( + raise parser.error( f"{filesystem} is not supported in {config.CONF_FILE}") format_dev = subprocess([f"mkfs.{filesystem}", "-q", devname], From f1ef9cd1f8ca382b19b2da8524d784c5ac4612dc Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Mon, 28 Mar 2022 22:37:36 +0000 Subject: [PATCH 27/44] Replace 'vol_id' with 'blkid -o udev'. --- ebsmount_lib/udevdb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ebsmount_lib/udevdb.py b/ebsmount_lib/udevdb.py index d9d81db..373447f 100644 --- a/ebsmount_lib/udevdb.py +++ b/ebsmount_lib/udevdb.py @@ -54,7 +54,7 @@ def _parse_raw_data(self, s): def _get_volinfo(self): if 'DEVTYPE' in self.env and self.env['DEVTYPE'] == 'disk': - proc = subprocess.run(["vol_id", f"/dev/{self.name}"], + proc = subprocess.run(["blkid", '-o', 'udev', f"/dev/{self.name}"], capture_output=True, text=True) if proc.returncode != 0: return From 73ffb10ab31b3089495b81f87a78d0ee11cc02b2 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Tue, 29 Mar 2022 00:23:30 +0000 Subject: [PATCH 28/44] Some more bugfixing. --- ebsmount_lib/__init__.py | 4 ++-- ebsmount_lib/utils.py | 14 ++++++++++---- ebsmount_manual.py | 4 ++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/ebsmount_lib/__init__.py b/ebsmount_lib/__init__.py index 4707f24..12f838e 100644 --- a/ebsmount_lib/__init__.py +++ b/ebsmount_lib/__init__.py @@ -16,7 +16,7 @@ import os # XXX TODO may need additional imports below (moving from importing *) -from os.path import join +from os.path import join, basename, exists import pwd @@ -36,7 +36,7 @@ def ebsmount_add(devname, mountdir): devpath = join('/dev', device.name) mountpath = join(mountdir, device.env.get( 'ID_FS_UUID', devpath[-1])[:6]) - mountoptions = mountoptions.split() + mountoptions = " ".join(config.mountoptions.split()) hookspath = join(mountpath, ".ebsmount") filesystem = device.env.get('ID_FS_TYPE', None) diff --git a/ebsmount_lib/utils.py b/ebsmount_lib/utils.py index 98658b3..41e2cc8 100644 --- a/ebsmount_lib/utils.py +++ b/ebsmount_lib/utils.py @@ -16,6 +16,7 @@ import os import subprocess +from subprocess import PIPE, STDOUT from conffile import ConfFile @@ -31,7 +32,8 @@ class EBSMountConf(ConfFile): def log(devname, s): entry = f"{devname}: {s}" - file(config.logfile, 'a').write(entry + "\n") + with open(config.logfile, 'a') as fob: + fob.write(entry + "\n") print(entry) @@ -55,12 +57,16 @@ def is_mounted(path): return False -def mount(devpath, mountpath, options=[]): +def mount(devpath, mountpath, options=''): """mount devpath to mountpath with specified options (creates mountpath)""" if not os.path.exists(mountpath): mkdir_parents(mountpath) if options: - subprocess(["mount", "-o", *options, devpath, mountpath]) + proc = subprocess.run(["mount", "-o", options, devpath, mountpath], + stderr=STDOUT, stdout=PIPE, text=True) else: - subprocess(["mount", devpath, mountpath]) + proc = subprocess.run(["mount", devpath, mountpath], + stderr=STDOUT, stdout=PIPE, text=True) + if proc.returncode != 0: + print(f'An error occurred when mounting:\n{proc.stdout}') diff --git a/ebsmount_manual.py b/ebsmount_manual.py index 16b8a66..202aa31 100755 --- a/ebsmount_manual.py +++ b/ebsmount_manual.py @@ -89,8 +89,8 @@ def main(): raise parser.error( f"{filesystem} is not supported in {config.CONF_FILE}") - format_dev = subprocess([f"mkfs.{filesystem}", "-q", devname], - stdout=PIPE, stderr=STDOUT, text=True) + format_dev = subprocess.run([f"mkfs.{filesystem}", "-q", devname], + stdout=PIPE, stderr=STDOUT, text=True) if format_dev.returncode != 0: fatal(f"formating {filesystem} failed: {format_dev.stdout}") From d68031962f97dca847837d352b0608629192acf4 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Tue, 29 Mar 2022 00:34:35 +0000 Subject: [PATCH 29/44] Final subprocess replacement/update. --- ebsmount_lib/__init__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ebsmount_lib/__init__.py b/ebsmount_lib/__init__.py index 12f838e..c3a7d29 100644 --- a/ebsmount_lib/__init__.py +++ b/ebsmount_lib/__init__.py @@ -17,6 +17,8 @@ import os # XXX TODO may need additional imports below (moving from importing *) from os.path import join, basename, exists +import subprocess +from subprocess import STDOUT, PIPE import pwd @@ -79,8 +81,10 @@ def ebsmount_add(devname, mountdir): log(devname, f"executing hook: {file}") os.environ['HOME'] = pwd.getpwuid(os.getuid()).pw_dir os.environ['MOUNTPOINT'] = mountpath - # XXX TODO - this command needs porting to subprocess! - system("/bin/bash --login -c '%s' 2>&1 | tee -a %s" % (fpath, config.logfile)) + proc = subprocess.run(['/bin/bash', '--login', '-c', fpath], + stderr=STDOUT, stdout=PIPE, check=True) + subprocess.run(['tee', '-a', config.logfile], + input=proc.stdout) def ebsmount_remove(devname, mountdir): From eb5800d7c6eb9a9d421e908b4e86d6a56f4eb542 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Tue, 29 Mar 2022 01:04:32 +0000 Subject: [PATCH 30/44] Remove redundant dependency. --- debian/control | 1 - 1 file changed, 1 deletion(-) diff --git a/debian/control b/debian/control index 0faf6cc..6a08f70 100644 --- a/debian/control +++ b/debian/control @@ -14,7 +14,6 @@ Package: ebsmount Architecture: all Depends: ${misc:Depends}, - ${python3:Depends}, udev, turnkey-conffile Description: Automatically mount EC2/OpenStack EBS devices From 06f5944dc4dd1fce3a647157be748c0439cb813c Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Tue, 29 Mar 2022 02:50:56 +0000 Subject: [PATCH 31/44] nargs='1' means args.action is a list of one item. --- ebsmount_udev.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ebsmount_udev.py b/ebsmount_udev.py index 65bf7a4..48da3b5 100755 --- a/ebsmount_udev.py +++ b/ebsmount_udev.py @@ -83,9 +83,8 @@ def main(): 'PHYSDEVPATH/DEVPATH is not of the expected structure') # log trigger - log(devname, f"received {args.action} trigger") - - func = getattr(ebsmount, 'ebsmount_' + args.action) + log(devname, f"received {args.action[0]} trigger") + func = getattr(ebsmount, 'ebsmount_' + args.action[0]) func(devname, config.mountdir) From a7fbcfeea41e97cdbbcf347d6f3b0d3bbe64509d Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Tue, 29 Mar 2022 03:05:53 +0000 Subject: [PATCH 32/44] Rename executables (cleaner packaging). --- debian/ebsmount.links | 2 -- ebsmount_manual.py => ebsmount-manual | 0 ebsmount_udev.py => ebsmount-udev | 0 setup.py | 2 +- 4 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 debian/ebsmount.links rename ebsmount_manual.py => ebsmount-manual (100%) rename ebsmount_udev.py => ebsmount-udev (100%) diff --git a/debian/ebsmount.links b/debian/ebsmount.links deleted file mode 100644 index a8c1da0..0000000 --- a/debian/ebsmount.links +++ /dev/null @@ -1,2 +0,0 @@ -usr/bin/ebsmount_manual.py usr/bin/ebsmount-manual -usr/bin/ebsmount_udev.py usr/bin/ebsmount-udev diff --git a/ebsmount_manual.py b/ebsmount-manual similarity index 100% rename from ebsmount_manual.py rename to ebsmount-manual diff --git a/ebsmount_udev.py b/ebsmount-udev similarity index 100% rename from ebsmount_udev.py rename to ebsmount-udev diff --git a/setup.py b/setup.py index f33b7ce..69843d4 100755 --- a/setup.py +++ b/setup.py @@ -9,5 +9,5 @@ author_email="jeremy@turnkeylinux.org", url="https://github.com/turnkeylinux/ebsmount", packages=["ebsmount_lib"], - scripts=["ebsmount_manual.py", "ebsmount_udev.py"] + scripts=["ebsmount-manual", "ebsmount-udev"] ) From c68df53112410f287c212a505d81eb9383d2884b Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Tue, 29 Mar 2022 06:16:51 +0000 Subject: [PATCH 33/44] Use systemctl in udev .rules file (instead of service). --- conf/85-ebsmount.rules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/85-ebsmount.rules b/conf/85-ebsmount.rules index 79b57ae..44e2cfc 100644 --- a/conf/85-ebsmount.rules +++ b/conf/85-ebsmount.rules @@ -1,8 +1,8 @@ # udev rules to trigger the ebsmount systemd service. # Amazon EC2 -KERNEL=="xvd[a-z]|nvme[0-26]n[0-26]", SUBSYSTEM=="block", ACTION=="add", RUN+="/usr/sbin/service ebsmount@%k start" -KERNEL=="xvd[a-z]|nvme[0-26]n[0-26]", SUBSYSTEM=="block", ACTION=="remove", RUN+="/usr/sbin/service ebsmount@%k stop" +KERNEL=="xvd[a-z]|nvme[0-26]n[0-26]", SUBSYSTEM=="block", ACTION=="add", RUN+="/usr/bin/systemctl start ebsmount@%" +KERNEL=="xvd[a-z]|nvme[0-26]n[0-26]", SUBSYSTEM=="block", ACTION=="remove", RUN+="/usr/bin/systemctl stop ebsmount@%k" # OpenStack KERNEL=="vd[a-z]*", SUBSYSTEM=="block", ACTION=="add", RUN+="@PATH_BIN@/ebsmount-udev add" From 73adc4812ecac0e35bf0505f72d58d7967293740 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Tue, 29 Mar 2022 08:28:41 +0000 Subject: [PATCH 34/44] Comment out stuff that doesn't appear to be needed. --- ebsmount-udev | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ebsmount-udev b/ebsmount-udev index 48da3b5..59c2df4 100755 --- a/ebsmount-udev +++ b/ebsmount-udev @@ -75,12 +75,13 @@ def main(): if not devname: raise parser.error('DEVNAME is required') - if not devpath: - raise parser.error('PHYSDEVPATH or DEVPATH is required') + # it seems that these may not be needed?! + #if not devpath: + # raise parser.error('PHYSDEVPATH or DEVPATH is required') - if not _expected_devpath(devpath, config.devpaths.split()): - raise parser.error( - 'PHYSDEVPATH/DEVPATH is not of the expected structure') + #if not _expected_devpath(devpath, config.devpaths.split()): + # raise parser.error( + # 'PHYSDEVPATH/DEVPATH is not of the expected structure') # log trigger log(devname, f"received {args.action[0]} trigger") From cfd8d4e332f1b3db482c73d982c5926bee94fe49 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Tue, 29 Mar 2022 08:29:10 +0000 Subject: [PATCH 35/44] Update service template. --- debian/ebsmount@.service | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/debian/ebsmount@.service b/debian/ebsmount@.service index f847604..3d8a8c9 100644 --- a/debian/ebsmount@.service +++ b/debian/ebsmount@.service @@ -1,10 +1,14 @@ [Unit] Description=ebsmount for %i +Documentation=man:ebsmount-udev(8) +After=local-fs.target + [Service] Type=oneshot RemainAfterExit=true Environment="DEVNAME=%i" -ExecStart=@PATH_BIN@/ebsmount-udev add -ExecStop=@PATH_BIN@/ebsmount-udev remove +ExecStart=/usr/bin/ebsmount-udev add +ExecStop=/usr/bin/ebsmount-udev remove # Very important: Expose mounted volumes to other processes. +PrivateMounts=no MountFlags=shared From 45b17199701e963612e4537569059a4e80d7db65 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Tue, 29 Mar 2022 08:29:44 +0000 Subject: [PATCH 36/44] Capture exception when /media isn't as expected (e.g. missing dirs). --- ebsmount_lib/__init__.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/ebsmount_lib/__init__.py b/ebsmount_lib/__init__.py index c3a7d29..afe0cb8 100644 --- a/ebsmount_lib/__init__.py +++ b/ebsmount_lib/__init__.py @@ -91,13 +91,17 @@ def ebsmount_remove(devname, mountdir): """ebs device detached""" mounted = False - for d in os.listdir(mountdir): - path = join(mountdir, d) - if is_mounted(path): - mounted = True - continue - - os.rmdir(path) + try: + for d in os.listdir(mountdir): + path = join(mountdir, d) + print(f'checking path: {path}') + if is_mounted(path): + print(f'path mounted: {path}') + mounted = True + continue + os.rmdir(path) - if not mounted: - os.rmdir(mountdir) + if not mounted: + os.rmdir(mountdir) + except FileNotFoundError: + pass From 1e77f4b20ae9e54621cf8454a418a77b17207b19 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Tue, 29 Mar 2022 08:30:43 +0000 Subject: [PATCH 37/44] Use systemd-mount rather than mount, should mena it works... --- ebsmount_lib/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ebsmount_lib/utils.py b/ebsmount_lib/utils.py index 41e2cc8..fb6c3a9 100644 --- a/ebsmount_lib/utils.py +++ b/ebsmount_lib/utils.py @@ -63,10 +63,10 @@ def mount(devpath, mountpath, options=''): mkdir_parents(mountpath) if options: - proc = subprocess.run(["mount", "-o", options, devpath, mountpath], + proc = subprocess.run(["systemd-mount", "-o", options, devpath, mountpath], stderr=STDOUT, stdout=PIPE, text=True) else: - proc = subprocess.run(["mount", devpath, mountpath], + proc = subprocess.run(["systemd-mount", devpath, mountpath], stderr=STDOUT, stdout=PIPE, text=True) if proc.returncode != 0: print(f'An error occurred when mounting:\n{proc.stdout}') From 35ddcb99d207c5c7a84b8f7149cbf2a62b99be1d Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Tue, 29 Mar 2022 22:27:57 +0000 Subject: [PATCH 38/44] Fix typo. --- conf/85-ebsmount.rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/85-ebsmount.rules b/conf/85-ebsmount.rules index 44e2cfc..3a587d1 100644 --- a/conf/85-ebsmount.rules +++ b/conf/85-ebsmount.rules @@ -1,7 +1,7 @@ # udev rules to trigger the ebsmount systemd service. # Amazon EC2 -KERNEL=="xvd[a-z]|nvme[0-26]n[0-26]", SUBSYSTEM=="block", ACTION=="add", RUN+="/usr/bin/systemctl start ebsmount@%" +KERNEL=="xvd[a-z]|nvme[0-26]n[0-26]", SUBSYSTEM=="block", ACTION=="add", RUN+="/usr/bin/systemctl start ebsmount@%k" KERNEL=="xvd[a-z]|nvme[0-26]n[0-26]", SUBSYSTEM=="block", ACTION=="remove", RUN+="/usr/bin/systemctl stop ebsmount@%k" # OpenStack From 2505433cc31aeaa1c3988ea907c246e889772950 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 30 Mar 2022 06:21:21 +0000 Subject: [PATCH 39/44] Remove redundant carat as per review (see PR#5). --- ebsmount-manual | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ebsmount-manual b/ebsmount-manual index 202aa31..4795913 100755 --- a/ebsmount-manual +++ b/ebsmount-manual @@ -41,7 +41,7 @@ def _expected_devpath(devname, devpaths): for line in raw_output.splitlines(): line = line.strip() - m = re.match("^looking at parent device '(.*)':", line) + m = re.match("looking at parent device '(.*)':", line) if m: devpath = m.group(1) for pattern in devpaths: From b6734bf405543320fe09df6b14201c450fff0c82 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 30 Mar 2022 06:22:12 +0000 Subject: [PATCH 40/44] Remove redundant square brakets (see PR#5). --- ebsmount_lib/udevdb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ebsmount_lib/udevdb.py b/ebsmount_lib/udevdb.py index 373447f..4c4e4fa 100644 --- a/ebsmount_lib/udevdb.py +++ b/ebsmount_lib/udevdb.py @@ -98,7 +98,7 @@ def _disk_devices(): attrs = list(dev.env.keys()) attrs.sort() - column_len = max([len(attr) + 1 for attr in attrs]) + column_len = max(len(attr) + 1 for attr in attrs) for attr in attrs: name = attr + ":" print(f" {name.ljust(column_len)} {dev.env[attr]}") From d111374e058efe42ddf63da6dc166da2be8f7e40 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 30 Mar 2022 06:24:01 +0000 Subject: [PATCH 41/44] Move fatal func to utils (see PR#5). --- ebsmount-manual | 7 +------ ebsmount-udev | 7 +------ ebsmount_lib/utils.py | 5 +++++ 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/ebsmount-manual b/ebsmount-manual index 4795913..329e1ec 100755 --- a/ebsmount-manual +++ b/ebsmount-manual @@ -25,12 +25,7 @@ import subprocess from subprocess import PIPE, STDOUT import ebsmount_lib as ebsmount -from ebsmount_lib.utils import config, is_mounted - - -def fatal(s): - print("error: " + str(s), file=sys.stderr) - sys.exit(1) +from ebsmount_lib.utils import fatal, config, is_mounted def _expected_devpath(devname, devpaths): diff --git a/ebsmount-udev b/ebsmount-udev index 59c2df4..b648bd7 100755 --- a/ebsmount-udev +++ b/ebsmount-udev @@ -23,7 +23,7 @@ import sys import argparse import ebsmount_lib as ebsmount -from ebsmount_lib.utils import log, config +from ebsmount_lib.utils import fatal, log, config ENVVARS = """ environment variables (required): @@ -38,11 +38,6 @@ OpenStack DEVNAME /dev/vda """ -def fatal(s): - print("error: " + str(s), file=sys.stderr) - sys.exit(1) - - def _expected_devpath(devpath, devpaths): for pattern in devpaths: if re.search(pattern, devpath): diff --git a/ebsmount_lib/utils.py b/ebsmount_lib/utils.py index fb6c3a9..75a99b1 100644 --- a/ebsmount_lib/utils.py +++ b/ebsmount_lib/utils.py @@ -37,6 +37,11 @@ def log(devname, s): print(entry) +def fatal(s): + print("error: " + str(s), file=sys.stderr) + sys.exit(1) + + def mkdir_parents(path, mode=0o777): """mkdir 'path' recursively (I.e., equivalent to mkdir -p)""" dirs = path.split("/") From 418ad8ad77965c43ea80c1eceaae5b30980efda8 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 30 Mar 2022 06:28:51 +0000 Subject: [PATCH 42/44] Remove nargs='1' from argparsing (redundant - see PR#5). --- ebsmount-manual | 12 +++++------- ebsmount-udev | 5 ++--- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/ebsmount-manual b/ebsmount-manual index 329e1ec..cfe819a 100755 --- a/ebsmount-manual +++ b/ebsmount-manual @@ -54,7 +54,6 @@ def main(): ) parser.add_argument( 'devname', - nargs=1, help="EBS device to mount (e.g., /dev/xvdf, /dev/vda)" ) parser.add_argument( @@ -67,9 +66,8 @@ def main(): help="Format device prior to mount (defaults to ext4 unless specified)" ) args = parser.parse_args() - devname = args.devname[0] filesystem = args.filesystem - if not os.path.exists(devname): + if not os.path.exists(args.devname): raise parser.error(f"{devname} does not exist") if not _expected_devpath(devname, config.devpaths.split()): @@ -77,19 +75,19 @@ def main(): "devpath not of expected structure, or failed lookup") if filesystem: - if is_mounted(devname): - raise parser.error(f"{devname} is mounted") + if is_mounted(args.devname): + raise parser.error(f"{args.devname} is mounted") if filesystem not in config.filesystems.split(): raise parser.error( f"{filesystem} is not supported in {config.CONF_FILE}") - format_dev = subprocess.run([f"mkfs.{filesystem}", "-q", devname], + format_dev = subprocess.run([f"mkfs.{filesystem}", "-q", args.devname], stdout=PIPE, stderr=STDOUT, text=True) if format_dev.returncode != 0: fatal(f"formating {filesystem} failed: {format_dev.stdout}") - ebsmount.ebsmount_add(devname, config.mountdir) + ebsmount.ebsmount_add(args.devname, config.mountdir) if __name__ == "__main__": diff --git a/ebsmount-udev b/ebsmount-udev index b648bd7..f8c8230 100755 --- a/ebsmount-udev +++ b/ebsmount-udev @@ -55,7 +55,6 @@ def main(): ) parser.add_argument( 'action', - nargs=1, choices=["add", "remove"], help="action trigger" ) @@ -79,8 +78,8 @@ def main(): # 'PHYSDEVPATH/DEVPATH is not of the expected structure') # log trigger - log(devname, f"received {args.action[0]} trigger") - func = getattr(ebsmount, 'ebsmount_' + args.action[0]) + log(devname, f"received {args.action} trigger") + func = getattr(ebsmount, 'ebsmount_' + args.action) func(devname, config.mountdir) From 93c8182135749e461e58a7a8b3d449285b5175de Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 30 Mar 2022 06:36:55 +0000 Subject: [PATCH 43/44] Improve log message. --- ebsmount_lib/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ebsmount_lib/__init__.py b/ebsmount_lib/__init__.py index afe0cb8..b7a9661 100644 --- a/ebsmount_lib/__init__.py +++ b/ebsmount_lib/__init__.py @@ -48,7 +48,8 @@ def ebsmount_add(devname, mountdir): if filesystem not in config.filesystems.split(): log(devname, - f"filesystem ({filesystem}) not supported: {devpath}") + f"invalid filesystem: {filesystem}, encountered while" + f" adding {devpath}") continue if is_mounted(devpath): From 3b6f0d68799c2eccf75e4195121508b98958c141 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 30 Mar 2022 06:39:32 +0000 Subject: [PATCH 44/44] Add note about suboptimal error message. --- ebsmount-manual | 1 + 1 file changed, 1 insertion(+) diff --git a/ebsmount-manual b/ebsmount-manual index cfe819a..f30887a 100755 --- a/ebsmount-manual +++ b/ebsmount-manual @@ -80,6 +80,7 @@ def main(): if filesystem not in config.filesystems.split(): raise parser.error( + # XXX TODO this message could be better/clearer f"{filesystem} is not supported in {config.CONF_FILE}") format_dev = subprocess.run([f"mkfs.{filesystem}", "-q", args.devname],