[sysadmin-bin] py-install-module: initial and incomplete version of install-module ported to Python
- From: Olav Vitters <ovitters src gnome org>
- To: gnome-sysadmin gnome org,commits-list gnome org
- Subject: [sysadmin-bin] py-install-module: initial and incomplete version of install-module ported to Python
- Date: Fri, 4 Mar 2011 11:57:37 +0000 (UTC)
commit 93c4fd32c15ac2f73bab86ebd4c41bd58c9d3b0d
Author: Olav Vitters <olav vitters nl>
Date: Fri Mar 4 12:57:31 2011 +0100
py-install-module: initial and incomplete version of install-module ported to Python
py-install-module | 222 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 222 insertions(+), 0 deletions(-)
---
diff --git a/py-install-module b/py-install-module
new file mode 100755
index 0000000..ed7e8d7
--- /dev/null
+++ b/py-install-module
@@ -0,0 +1,222 @@
+#!/usr/bin/python
+
+import sys
+import os
+import os.path
+import grp
+import pwd
+import ldap
+import ldap.filter
+import re
+import tempfile
+import tarfile
+from optparse import OptionParser
+
+
+GROUP='ftpadmin'
+LDAP_BASE='ou=modules,dc=gnome,dc=org'
+re_file = re.compile(r'^(?P<module>.*)[_-](?P<version>([0-9]+[\.\-])*[0-9]+)?\.(?P<format>tar.*)$')
+re_version = re.compile(r'^([0-9]+\.[0-9]+).*')
+
+usage = "usage: %prog [options] TARBALL"
+description = """Install new tarball to GNOME FTP master and mirrors.
+
+Example: install-module -u metacity-2.4.1.tar.gz
+
+Report bugs to gnome-sysadmin gnome org"""
+
+parser = OptionParser(usage=usage, description=description)
+parser.add_option("-f", "--force", action="store_true", dest="clobber",
+ help="Overwrite the original tarball")
+parser.add_option("-u", "--unattended", action="store_true",
+ help="do not prompt for confirmation.\n\nNOTE: An unattended install " +
+ "will not provide any extra information to help you avoid an invalid " +
+ "(and potentially messy) installation. It is recommended that you do not " +
+ "use this unless you are *very* sure.")
+
+parser.set_defaults(clobber=False, unattended=False)
+
+# COPY/PASTE from releng/convert-to-tarballs.py
+def _bigger_version(a, b):
+ a_nums = a.split('.')
+ b_nums = b.split('.')
+ num_fields = min(len(a_nums), len(b_nums))
+ for i in range(0,num_fields):
+ if int(a_nums[i]) > int(b_nums[i]):
+ return a
+ elif int(a_nums[i]) < int(b_nums[i]):
+ return b
+ if len(a_nums) > len(b_nums):
+ return a
+ else:
+ return b
+
+# This is nearly the same as _bigger_version, except that
+# - It returns a boolean value
+# - If max_version is None, it just returns False
+# - It treats 2.13 as == 2.13.0 instead of 2.13 as < 2.13.0
+# The second property is particularly important with directory hierarchies
+def _version_greater_or_equal_to_max(a, max_version):
+ if not max_version:
+ return False
+ a_nums = a.split('.')
+ b_nums = max_version.split('.')
+ num_fields = min(len(a_nums), len(b_nums))
+ for i in range(0,num_fields):
+ if int(a_nums[i]) > int(b_nums[i]):
+ return True
+ elif int(a_nums[i]) < int(b_nums[i]):
+ return False
+ return True
+
+def get_latest_version(versions, max_version):
+ biggest = versions[0]
+ for version in versions[1:]:
+ if (version == _bigger_version(biggest, version) and \
+ not _version_greater_or_equal_to_max(version, max_version)):
+ biggest = version
+ return biggest
+# END COPY/PASTE
+
+
+class InstallModule(object):
+ FTPROOT='/ftp/pub/test'
+ URLROOT='http://download.gnome.org'
+
+ FORMATS = ('tar.gz', 'tar.bz2')
+
+ def __init__(self, file):
+ self.file = file
+
+ self.uid = os.getuid()
+ self.pw = pwd.getpwuid(self.uid)
+
+ self.dirname, self.basename = os.path.split(file)
+ r = re_file.match(self.basename)
+ if r:
+ fileinfo = r.groupdict()
+
+ self.module = fileinfo['module']
+ self.version = fileinfo['version']
+ self.format = fileinfo['format']
+ self.majmin = re_version.sub(r'\1', fileinfo['version'])
+ self.destination = '%s/sources/%s/%s' % (self.FTPROOT, fileinfo['module'], self.majmin)
+ else:
+ self.module = None
+
+ # Determine maintainers
+ self.maintainers = None
+ if self.module:
+ data = get_module_info(self.module)
+ if len(data):
+ self.maintainers = data[0][1]['maintainerUid']
+
+
+ def confirm_install(self):
+ print """ Module: %s
+ Version: %s
+ Maj.Min: %s
+ Destination: %s/""" % (self.module, self.version, self.majmin, self.destination)
+
+ # Check if the module directory already exists. If not, the module name might contain a typo
+ if not os.path.isdir('%s/sources/%s' % (self.FTPROOT, self.module)):
+ print """
+WARNING: %s is not present in the archive!
+ Are you sure that it is new and/or the correct module name?""" % self.module
+
+ print """
+Install %s? [Y/n]""" % self.module,
+ response = raw_input()
+
+ if response != '' and response[0] != 'y' and response[0] != 'Y':
+ print """Module installation cancelled. Please report any problems with this
+script to gnome-sysadmin gnome org Thanks."""
+
+ return False
+
+ # install the module
+ return True
+
+ def validate(self):
+ if self.module is None:
+ print 'ERROR: Unrecognized module/version/file format. Make sure to follow a sane naming scheme (MAJOR.MINOR.MICRO)'
+ return False
+
+ # Don't allow an existing tarball to be overwritten
+ if os.path.exists(os.path.join(self.destination, self.basename)):
+ print """
+ERROR: %s already exists in the archive!""" % self.basename
+ return False
+
+ # CHECK FOR CONSISTENCY
+ tar = tarfile.open(self.file)
+
+ # CHECK 1: Make sure tarball contains a directory called $MODULE-$VERSION
+ dir = None
+ try:
+ dir = tar.getmember('%s-%s' % (self.module, self.version))
+ except KeyError:
+ pass
+ if dir and not dir.isdir():
+ dir = None
+ if dir is None:
+ print 'ERROR: Cannot find expected directory within tarball, aborting!'
+ return False
+
+ # Valid file
+ return True
+
+ def install(self, unattended=False):
+ # Validate the file
+ if not self.validate():
+ return False
+
+ # XXX - verify if tarball is being installed by a maintainer
+
+ # Ask user if tarball should be installed
+ if not unattended:
+ if not self.confirm_install():
+ return False
+
+
+ for k, v in self.__dict__.iteritems():
+ print k, v
+
+# if not os.path.isdir(self.destination):
+# os.makedirs(self.destination, 042775) # drwxrwsr-x
+ # XXX - install the tarball
+ # XXX - change ownership of the tarball
+
+l = None
+def get_module_info(module):
+ global l # evil
+
+ if l is None:
+ l = ldap.open('ldap-back')
+ l.protocol_version = ldap.VERSION3
+
+ filter = ldap.filter.filter_format("(cn=%s)", (module, ))
+ data = l.search_s (LDAP_BASE, ldap.SCOPE_SUBTREE, filter, None)
+
+ return data
+
+
+
+if __name__ == "__main__":
+ (options, args) = parser.parse_args()
+ tarballs = [file for file in args if os.path.exists(file)]
+
+ if not len(tarballs):
+ parser.print_usage()
+ sys.exit(2)
+
+ old_mask = os.umask(0002)
+ groupid = grp.getgrnam(GROUP)[2]
+ if groupid not in os.getgroups():
+ print 'ERROR: Script requires membership of the %s group' % GROUP
+ sys.exit(1)
+
+
+ for file in tarballs:
+ handler = InstallModule(file)
+ handler.install(unattended=options.unattended)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]