1.1 --- a/docs/wiki/Administration Tue Jan 31 16:18:55 2017 +0100
1.2 +++ b/docs/wiki/Administration Sun Feb 05 22:16:24 2017 +0100
1.3 @@ -121,34 +121,12 @@
1.4 in this package by adding files to the `scheduling` directory within the
1.5 software installation.
1.6
1.7 -After adding modules, a tool must be run to register the new modules:
1.8 -
1.9 -{{{
1.10 -tools/update_scheduling_modules.py
1.11 -}}}
1.12 -
1.13 -It is envisaged that the installation of additional scheduling modules and the
1.14 -use of this tool will be performed by the packaging system provided by an
1.15 -operating system distribution. The `tools/install.sh` script runs the above
1.16 -tool as part of the installation process.
1.17 -
1.18 == Adding Storage Modules ==
1.19
1.20 Storage modules reside in the `imiptools.stores` package. Extra modules can be
1.21 -installed in this package by adding files or directories to the `stores`
1.22 +installed in this package by adding files or directories to the `stores`
1.23 directory within the software installation.
1.24
1.25 -After adding modules, a tool must be run to register the new modules:
1.26 -
1.27 -{{{
1.28 -tools/update_storage_modules.py
1.29 -}}}
1.30 -
1.31 -It is envisaged that the installation of additional storage modules and the
1.32 -use of this tool will be performed by the packaging system provided by an
1.33 -operating system distribution. The `tools/install.sh` script runs the above
1.34 -tool as part of the installation process.
1.35 -
1.36 == Copying Stores and Changing Store Types ==
1.37
1.38 A rudimentary tool is provided that can copy data between stores, even those of
2.1 --- a/imiptools/handlers/scheduling/manifest.py Tue Jan 31 16:18:55 2017 +0100
2.2 +++ b/imiptools/handlers/scheduling/manifest.py Sun Feb 05 22:16:24 2017 +0100
2.3 @@ -1,45 +1,52 @@
2.4 +#!/usr/bin/env python
2.5 +
2.6 +"""
2.7 +Scheduling functions manifest.
2.8 +
2.9 +Copyright (C) 2017 Paul Boddie <paul@boddie.org.uk>
2.10 +
2.11 +This program is free software; you can redistribute it and/or modify it under
2.12 +the terms of the GNU General Public License as published by the Free Software
2.13 +Foundation; either version 3 of the License, or (at your option) any later
2.14 +version.
2.15 +
2.16 +This program is distributed in the hope that it will be useful, but WITHOUT
2.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
2.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
2.19 +details.
2.20 +
2.21 +You should have received a copy of the GNU General Public License along with
2.22 +this program. If not, see <http://www.gnu.org/licenses/>.
2.23 +"""
2.24 +
2.25 +from imiptools.imports import get_extensions
2.26 +from os.path import split
2.27 +
2.28 +reserved = ["__init__", "common", "manifest"]
2.29 +
2.30 +# Obtain details of this module's package.
2.31 +
2.32 +dirname = split(__file__)[0]
2.33 +package = __name__.rsplit(".", 1)[0]
2.34 +
2.35 +# Define an attribute mapping names to modules.
2.36 +
2.37 +modules = {}
2.38 +get_extensions(dirname, package, modules, reserved)
2.39 +
2.40 +# Define attributes mapping names to functions.
2.41 +
2.42 confirmation_functions = {}
2.43 locking_functions = {}
2.44 retraction_functions = {}
2.45 scheduling_functions = {}
2.46 unlocking_functions = {}
2.47
2.48 -from imiptools.handlers.scheduling.access import (
2.49 - confirmation_functions as c,
2.50 - locking_functions as l,
2.51 - retraction_functions as r,
2.52 - scheduling_functions as s,
2.53 - unlocking_functions as u)
2.54 -
2.55 -confirmation_functions.update(c)
2.56 -locking_functions.update(l)
2.57 -retraction_functions.update(r)
2.58 -scheduling_functions.update(s)
2.59 -unlocking_functions.update(u)
2.60 -
2.61 -from imiptools.handlers.scheduling.freebusy import (
2.62 - confirmation_functions as c,
2.63 - locking_functions as l,
2.64 - retraction_functions as r,
2.65 - scheduling_functions as s,
2.66 - unlocking_functions as u)
2.67 +for module in modules.values():
2.68 + confirmation_functions.update(module.confirmation_functions)
2.69 + locking_functions.update(module.locking_functions)
2.70 + retraction_functions.update(module.retraction_functions)
2.71 + scheduling_functions.update(module.scheduling_functions)
2.72 + unlocking_functions.update(module.unlocking_functions)
2.73
2.74 -confirmation_functions.update(c)
2.75 -locking_functions.update(l)
2.76 -retraction_functions.update(r)
2.77 -scheduling_functions.update(s)
2.78 -unlocking_functions.update(u)
2.79 -
2.80 -from imiptools.handlers.scheduling.quota import (
2.81 - confirmation_functions as c,
2.82 - locking_functions as l,
2.83 - retraction_functions as r,
2.84 - scheduling_functions as s,
2.85 - unlocking_functions as u)
2.86 -
2.87 -confirmation_functions.update(c)
2.88 -locking_functions.update(l)
2.89 -retraction_functions.update(r)
2.90 -scheduling_functions.update(s)
2.91 -unlocking_functions.update(u)
2.92 -
2.93 +# vim: tabstop=4 expandtab shiftwidth=4
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/imiptools/imports.py Sun Feb 05 22:16:24 2017 +0100
3.3 @@ -0,0 +1,47 @@
3.4 +#!/usr/bin/env python
3.5 +
3.6 +"""
3.7 +Import utilities.
3.8 +
3.9 +Copyright (C) 2017 Paul Boddie <paul@boddie.org.uk>
3.10 +
3.11 +This program is free software; you can redistribute it and/or modify it under
3.12 +the terms of the GNU General Public License as published by the Free Software
3.13 +Foundation; either version 3 of the License, or (at your option) any later
3.14 +version.
3.15 +
3.16 +This program is distributed in the hope that it will be useful, but WITHOUT
3.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
3.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
3.19 +details.
3.20 +
3.21 +You should have received a copy of the GNU General Public License along with
3.22 +this program. If not, see <http://www.gnu.org/licenses/>.
3.23 +"""
3.24 +
3.25 +from os.path import isdir, join, splitext
3.26 +from os import listdir
3.27 +from importlib import import_module
3.28 +
3.29 +def get_extensions(dirname, modname, stores, reserved):
3.30 +
3.31 + "Import extensions inside 'dirname'."
3.32 +
3.33 + for filename in listdir(dirname):
3.34 + pathname = join(dirname, filename)
3.35 +
3.36 + # Descend into directories.
3.37 +
3.38 + if isdir(pathname):
3.39 + get_extensions(pathname, "%s.%s" % (modname, filename),
3.40 + stores, reserved)
3.41 + continue
3.42 +
3.43 + # Identify modules and import them.
3.44 +
3.45 + leafname, ext = splitext(filename)
3.46 +
3.47 + if ext == ".py" and leafname not in reserved:
3.48 + stores[leafname] = import_module("%s.%s" % (modname, leafname))
3.49 +
3.50 +# vim: tabstop=4 expandtab shiftwidth=4
4.1 --- a/imiptools/stores/manifest.py Tue Jan 31 16:18:55 2017 +0100
4.2 +++ b/imiptools/stores/manifest.py Sun Feb 05 22:16:24 2017 +0100
4.3 @@ -1,8 +1,37 @@
4.4 -stores = {}
4.5 +#!/usr/bin/env python
4.6 +
4.7 +"""
4.8 +Store manifest.
4.9 +
4.10 +Copyright (C) 2017 Paul Boddie <paul@boddie.org.uk>
4.11 +
4.12 +This program is free software; you can redistribute it and/or modify it under
4.13 +the terms of the GNU General Public License as published by the Free Software
4.14 +Foundation; either version 3 of the License, or (at your option) any later
4.15 +version.
4.16 +
4.17 +This program is distributed in the hope that it will be useful, but WITHOUT
4.18 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
4.19 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
4.20 +details.
4.21
4.22 -from imiptools.stores import file
4.23 -stores['file'] = file
4.24 +You should have received a copy of the GNU General Public License along with
4.25 +this program. If not, see <http://www.gnu.org/licenses/>.
4.26 +"""
4.27 +
4.28 +from imiptools.imports import get_extensions
4.29 +from os.path import split
4.30 +
4.31 +reserved = ["__init__", "common", "manifest"]
4.32
4.33 -from imiptools.stores.database import postgresql
4.34 -stores['postgresql'] = postgresql
4.35 +# Obtain details of this module's package.
4.36 +
4.37 +dirname = split(__file__)[0]
4.38 +package = __name__.rsplit(".", 1)[0]
4.39
4.40 +# Define an attribute mapping names to modules.
4.41 +
4.42 +stores = {}
4.43 +get_extensions(dirname, package, stores, reserved)
4.44 +
4.45 +# vim: tabstop=4 expandtab shiftwidth=4
5.1 --- a/tools/install.sh Tue Jan 31 16:18:55 2017 +0100
5.2 +++ b/tools/install.sh Sun Feb 05 22:16:24 2017 +0100
5.3 @@ -44,6 +44,8 @@
5.4 cp $AGENTS "$INSTALL_DIR"
5.5 cp $MODULES "$INSTALL_DIR"
5.6
5.7 +# Package modules.
5.8 +
5.9 for DIR in "$INSTALL_DIR/imiptools" \
5.10 "$INSTALL_DIR/imiptools/stores" \
5.11 "$INSTALL_DIR/imiptools/stores/database" \
5.12 @@ -54,7 +56,8 @@
5.13 fi
5.14 done
5.15
5.16 -# Remove any symbolic link to the config module.
5.17 +# Remove any symbolic link to the config module. This linking is no longer
5.18 +# supported, anyway.
5.19
5.20 if [ -h "$INSTALL_DIR/imiptools/config.py" ]; then
5.21 rm "$INSTALL_DIR/imiptools/config.py"
5.22 @@ -138,8 +141,9 @@
5.23 # Tools
5.24
5.25 TOOLS="copy_store.py fix.sh init.sh init_user.sh make_freebusy.py set_delegates.py "\
5.26 -"set_quota_groups.py set_quota_limits.py update_quotas.py update_scheduling_modules.py "\
5.27 -"update_storage_modules.py"
5.28 +"set_quota_groups.py set_quota_limits.py update_quotas.py"
5.29 +
5.30 +OLD_TOOLS="update_scheduling_modules.py update_storage_modules.py"
5.31
5.32 if [ ! -e "$INSTALL_DIR/tools" ]; then
5.33 mkdir -p "$INSTALL_DIR/tools"
5.34 @@ -149,6 +153,12 @@
5.35 cp "tools/$TOOL" "$INSTALL_DIR/tools/"
5.36 done
5.37
5.38 +for TOOL in $OLD_TOOLS; do
5.39 + if [ -e "$INSTALL_DIR/tools/$TOOL" ]; then
5.40 + rm "$INSTALL_DIR/tools/$TOOL"
5.41 + fi
5.42 +done
5.43 +
5.44 # Web manager interface.
5.45
5.46 if [ ! -e "$WEB_INSTALL_DIR" ]; then
5.47 @@ -183,11 +193,3 @@
5.48 done
5.49 fi
5.50 fi
5.51 -
5.52 -# Run the scheduling module update tool to regenerate the manifest module.
5.53 -
5.54 -PYTHONPATH="$INSTALL_DIR" "$INSTALL_DIR/tools/update_scheduling_modules.py"
5.55 -
5.56 -# Run the storage module update tool to regenerate the manifest module.
5.57 -
5.58 -PYTHONPATH="$INSTALL_DIR" "$INSTALL_DIR/tools/update_storage_modules.py"
6.1 --- a/tools/update_scheduling_modules.py Tue Jan 31 16:18:55 2017 +0100
6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
6.3 @@ -1,80 +0,0 @@
6.4 -#!/usr/bin/env python
6.5 -
6.6 -"""
6.7 -Update the scheduling modules import manifest.
6.8 -
6.9 -Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
6.10 -
6.11 -This program is free software; you can redistribute it and/or modify it under
6.12 -the terms of the GNU General Public License as published by the Free Software
6.13 -Foundation; either version 3 of the License, or (at your option) any later
6.14 -version.
6.15 -
6.16 -This program is distributed in the hope that it will be useful, but WITHOUT
6.17 -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
6.18 -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
6.19 -details.
6.20 -
6.21 -You should have received a copy of the GNU General Public License along with
6.22 -this program. If not, see <http://www.gnu.org/licenses/>.
6.23 -"""
6.24 -
6.25 -from glob import glob
6.26 -from os.path import join, split, splitext
6.27 -import imp
6.28 -
6.29 -reserved = ["__init__.py", "common.py", "manifest.py"]
6.30 -
6.31 -# The main program generating a new version of the manifest module.
6.32 -
6.33 -if __name__ == "__main__":
6.34 - _f, dirname, _d = imp.find_module("imiptools/handlers")
6.35 - dirname = join(dirname, "scheduling")
6.36 -
6.37 - # Get all Python files in the scheduling directory, filtering out the
6.38 - # reserved files that do not provide scheduling functions.
6.39 -
6.40 - filenames = []
6.41 - found = glob(join(dirname, "*.py"))
6.42 - found.sort()
6.43 -
6.44 - for filename in found:
6.45 - filename = split(filename)[-1]
6.46 - if filename not in reserved:
6.47 - filenames.append(filename)
6.48 -
6.49 - # Open the manifest module and write code to import and combine the
6.50 - # functions from each module.
6.51 -
6.52 - f = open(join(dirname, "manifest.py"), "w")
6.53 - try:
6.54 - print >>f, """\
6.55 -confirmation_functions = {}
6.56 -locking_functions = {}
6.57 -retraction_functions = {}
6.58 -scheduling_functions = {}
6.59 -unlocking_functions = {}
6.60 -"""
6.61 -
6.62 - for filename in filenames:
6.63 - module = splitext(filename)[0]
6.64 -
6.65 - print >>f, """\
6.66 -from imiptools.handlers.scheduling.%s import (
6.67 - confirmation_functions as c,
6.68 - locking_functions as l,
6.69 - retraction_functions as r,
6.70 - scheduling_functions as s,
6.71 - unlocking_functions as u)
6.72 -
6.73 -confirmation_functions.update(c)
6.74 -locking_functions.update(l)
6.75 -retraction_functions.update(r)
6.76 -scheduling_functions.update(s)
6.77 -unlocking_functions.update(u)
6.78 -""" % module
6.79 -
6.80 - finally:
6.81 - f.close()
6.82 -
6.83 -# vim: tabstop=4 expandtab shiftwidth=4
7.1 --- a/tools/update_storage_modules.py Tue Jan 31 16:18:55 2017 +0100
7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
7.3 @@ -1,94 +0,0 @@
7.4 -#!/usr/bin/env python
7.5 -
7.6 -"""
7.7 -Update the storage modules import manifest.
7.8 -
7.9 -Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
7.10 -
7.11 -This program is free software; you can redistribute it and/or modify it under
7.12 -the terms of the GNU General Public License as published by the Free Software
7.13 -Foundation; either version 3 of the License, or (at your option) any later
7.14 -version.
7.15 -
7.16 -This program is distributed in the hope that it will be useful, but WITHOUT
7.17 -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
7.18 -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
7.19 -details.
7.20 -
7.21 -You should have received a copy of the GNU General Public License along with
7.22 -this program. If not, see <http://www.gnu.org/licenses/>.
7.23 -"""
7.24 -
7.25 -from glob import glob
7.26 -from os import listdir
7.27 -from os.path import commonprefix, isdir, join, split, splitext
7.28 -import imp
7.29 -
7.30 -reserved = ["__init__.py", "common.py", "manifest.py"]
7.31 -
7.32 -def get_extensions(dirname):
7.33 - filenames = []
7.34 - found = glob(join(dirname, "*.py"))
7.35 - found.sort()
7.36 -
7.37 - for filename in found:
7.38 - leafname = split(filename)[-1]
7.39 - if leafname not in reserved:
7.40 - filenames.append(filename)
7.41 -
7.42 - return filenames
7.43 -
7.44 -# The main program generating a new version of the manifest module.
7.45 -
7.46 -if __name__ == "__main__":
7.47 - _f, dirname, _d = imp.find_module("imiptools/stores")
7.48 - dirname = join(dirname, "")
7.49 - manifest = join(dirname, "manifest.py")
7.50 -
7.51 - # Get all Python files in the stores directory, filtering out the
7.52 - # reserved files that do not provide storage functions.
7.53 -
7.54 - filenames = get_extensions(dirname)
7.55 -
7.56 - # Get all extensions from directories in the stores directory.
7.57 -
7.58 - found = listdir(dirname)
7.59 - found.sort()
7.60 -
7.61 - for filename in found:
7.62 - filename = join(dirname, filename)
7.63 - if isdir(filename):
7.64 - filenames += get_extensions(filename)
7.65 -
7.66 - # Open the manifest module and write code to import and combine the
7.67 - # functions from each module.
7.68 -
7.69 - f = open(manifest, "w")
7.70 - try:
7.71 - print >>f, """\
7.72 -stores = {}
7.73 -"""
7.74 -
7.75 - for filename in filenames:
7.76 - relative = filename[len(commonprefix([filename, dirname])):]
7.77 -
7.78 - # NOTE: Converting POSIX paths to module paths.
7.79 -
7.80 - module = splitext(relative)[0].replace("/", ".")
7.81 - module_parts = module.rsplit(".", 1)
7.82 -
7.83 - # Get subpackage location and module.
7.84 -
7.85 - module_parents = len(module_parts) > 1 and module_parts[0]
7.86 - module_name = module_parts[-1]
7.87 -
7.88 - print >>f, """\
7.89 -from imiptools.stores%s import %s
7.90 -stores[%r] = %s
7.91 -""" % (module_parents and ".%s" % module_parents or "",
7.92 - module_name, module_name, module_name)
7.93 -
7.94 - finally:
7.95 - f.close()
7.96 -
7.97 -# vim: tabstop=4 expandtab shiftwidth=4