#!/usr/bin/python import sys import getopt import os import commands import re class Instance: def __init__(self, root): self.root = root steps = root.replace('/', ' ').split() self.package = steps[-1] self.symlinks = {} self._walk(self.root) self.rootdirs = [] self._checkRootDirCandidate(self.root) for s in self.symlinks: self._checkRootDirCandidate(self.symlinks[s]) self.rootdirs = set(self.rootdirs) def _walk(self, dirpath): status, output = commands.getstatusoutput('find %s -type l -exec ls -lQ \{\} \;' % dirpath) if status != 0: print output sys.exit(status) for source, dest in re.findall('"(.*)" -> "(.*)"', output, re.M): self.symlinks[source] = dest def _checkRootDirCandidate(self, dir): i = dir.find(self.package) if i == -1: print "Package name (%s) not found in directory or file name %s" % (self.package, dir) sys.exit(1) self.rootdirs.append(dir[:i]) def _targetName(self, sourceName, name): i = sourceName.find(self.package) if i == -1: print "Package name (%s) not found in directory or file name %s" % (self.package, sourceName) sys.exit(1) return sourceName[:i] + 'adminstance/' + self.package + '/' + name + sourceName[i + len(self.package) :] def _createSymlinks(self, name): for s in self.symlinks: i = s.find(self.package) linksource = self._targetName(s, name) linkdest = self._targetName(self.symlinks[s], name) print "Creating a symlink from %s to %s" % (linkdest, linksource) status, output = commands.getstatusoutput('rm %s' % linksource) status, output = commands.getstatusoutput('ln -s %s %s' % (linkdest, linksource)) if status != 0: print output sys.exit(status) def install(self, name): for d in self.rootdirs: source = d + self.package dest = d + 'adminstance/' + self.package + '/' + name print "Copying %s to %s" % (source, dest) status, output = commands.getstatusoutput('mkdir -p %s' % dest) status, output = commands.getstatusoutput('rsync -a --delete %s/ %s/' % (source, dest)) print output if status != 0: sys.exit(status) self._createSymlinks(name) def show(self): for d in self.rootdirs: if self.root.find(d) == 0: files = os.listdir(d+ 'adminstance/' + self.package) print "List of instances for the package %s:" % self.package for f in files: print "\t%s" % f return def update(self, name): for d in self.rootdirs: if d.find('/usr/') == 0: source = d + self.package dest = d + 'adminstance/' + self.package + '/' + name print "Synchronizing %s to %s" % (source, dest) cmd = 'rsync -a --delete %s/ %s/' % (source, dest) print cmd status, output = commands.getstatusoutput(cmd) print output if status != 0: sys.exit(status) self._createSymlinks(name) def remove(self, name, purge): for d in self.rootdirs: if d.find('/usr/') == 0 or purge: dest = d + 'adminstance/' + self.package + '/' + name print "Deleting %s" % dest cmd = 'rm -r %s' % dest print cmd status, output = commands.getstatusoutput(cmd) def usage(): print ''' Usages: adminstance -h|--help print this message adminstance -l|--list lists the installed instances for this directory adminstance -i|--install [-f|--force] installs an instance for a root directory adminstance -u|--update [-f|--force] updates an instance for a root directory adminstance -r|--remove [-f|--force] [-p|--purge] removes an instance for a root directory Options: -i, --install : action = installation -f, --force : when action = install, update or remove, install without prompting the user for a confirmation -h, --help : prints this message -l, --list : action = list -p, --purge : when action = remove, remove also files and directories under /var and /etc (by default, these are preserved) -r, --remove : action = remove -u, --update : action = update ''' def main(argv): action = "list" force = False purge = False try: opts, args = getopt.getopt(argv, "hiurplf", ["help", "install", "update", "remove", "purge", "list", "force"]) except getopt.GetoptError, err: # print help information and exit: print str(err) # will print something like "option -a not recognized" usage() sys.exit(2) for o, a in opts: if o in ("-l", "--list"): action = "list" elif o in ("-h", "--help"): usage() sys.exit() elif o in ("-i", "--install"): action = "install" elif o in ("-u", "--update"): action = "update" elif o in ("-r", "--remove"): action = "remove" elif o in ("-p", "--purge"): purge = True elif o in ("-f", "--force"): force = True else: assert False, "unhandled option" if len(args) < 1: usage() sys.exit(2) root = args[0] if (action != 'list'): if len(args) < 2: usage() sys.exit(2) name = args[1] if not force: proceed = raw_input(action + ' an instance of ' + root + ' named ' + name + '? (y|N) ') if proceed != 'y' and proceed != 'Y': print "Action cancelled by user." sys.exit(2) instance = Instance(root) if (action == 'install'): instance.install(name) elif action == 'list': instance.show() elif action == 'update': instance.update(name) elif action == 'remove': instance.remove(name, purge) if __name__ == '__main__': main(sys.argv[1:])