aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'overlord/overlays/source.py')
-rw-r--r--overlord/overlays/source.py161
1 files changed, 161 insertions, 0 deletions
diff --git a/overlord/overlays/source.py b/overlord/overlays/source.py
new file mode 100644
index 0000000..c645fa8
--- /dev/null
+++ b/overlord/overlays/source.py
@@ -0,0 +1,161 @@
+# -*- coding: utf-8 -*-
+#################################################################################
+# overlord OVERLAY SOURCE BASE CLASS
+#################################################################################
+# File: source.py
+#
+# Base class for the different overlay types.
+#
+# Copyright:
+# (c) 2010 Sebastian Pipping
+# Distributed under the terms of the GNU General Public License v2
+#
+# Author(s):
+# Sebastian Pipping <sebastian@pipping.org>
+
+import os
+import copy
+import sys
+import shutil
+import subprocess
+#from overlord.debug import OUT
+from overlord.utils import path
+
+
+def _resolve_command(command):
+ if os.path.isabs(command):
+ if not os.path.exists(command):
+ raise Exception('Program "%s" not found' % command)
+ return ('File', command)
+ else:
+ kind = 'Command'
+ env_path = os.environ['PATH']
+ for d in env_path.split(os.pathsep):
+ f = os.path.join(d, command)
+ if os.path.exists(f):
+ return ('Command', f)
+ raise Exception('Cound not resolve command "%s" based on PATH "%s"' % (command, env_path))
+
+
+def require_supported(binaries):
+ for command, mtype, package in binaries:
+ found = False
+ kind, path = _resolve_command(command)
+ if not path:
+ raise Exception(kind + ' ' + command + ' seems to be missing!'
+ ' Overlay type "' + mtype + '" not support'
+ 'ed. Did you emerge ' + package + '?')
+ return True
+
+
+class OverlaySource(object):
+
+ type_key = None
+
+ def __init__(self, parent, xml, config, _location, ignore = 0, quiet = False):
+ self.parent = parent
+ self.src = _location
+ self.config = config
+ self.ignore = ignore
+ self.quiet = quiet
+ self.output = config['output']
+
+ def __eq__(self, other):
+ return self.src == other.src
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+ def add(self, base, quiet = False):
+ '''Add the overlay.'''
+
+ mdir = path([base, self.parent.name])
+
+ if os.path.exists(mdir):
+ raise Exception('Directory ' + mdir + ' already exists. Will not ov'
+ 'erwrite its contents!')
+
+ os.makedirs(mdir)
+
+ def sync(self, base, quiet = False):
+ '''Sync the overlay.'''
+ pass
+
+ def delete(self, base):
+ '''Delete the overlay.'''
+ mdir = path([base, self.parent.name])
+
+ if not os.path.exists(mdir):
+ self.output.warn('Directory ' + mdir + ' did not exist, no files deleted.')
+ return
+
+ self.output.info('Deleting directory "%s"' % mdir, 2)
+ shutil.rmtree(mdir)
+
+ def supported(self):
+ '''Is the overlay type supported?'''
+ return True
+
+ def is_supported(self):
+ '''Is the overlay type supported?'''
+
+ try:
+ self.supported()
+ return True
+ except:
+ return False
+
+ def command(self):
+ return self.config['%s_command' % self.__class__.type_key]
+
+ def run_command(self, *args, **kwargs):
+ file_to_run = _resolve_command(self.command())[1]
+ args = (file_to_run, ) + args
+ assert('pwd' not in kwargs) # Bug detector
+
+ cwd = kwargs.get('cwd', None)
+ env = None
+ env_updates = None
+ if 'env' in kwargs:
+ # Build actual env from surrounding plus updates
+ env_updates = kwargs['env']
+ env = copy.copy(os.environ)
+ env.update(env_updates)
+
+ command_repr = ' '.join(args)
+ if env_updates:
+ command_repr = '%s %s' % (' '.join('%s=%s' % (k, v) for (k, v) in sorted(env_updates.items())), command_repr)
+ if cwd:
+ command_repr = '( cd %s && %s )' % (cwd, command_repr)
+
+ self.output.info('Running... # %s' % command_repr, 2)
+
+ if self.quiet:
+ input_source = subprocess.PIPE
+ output_target = open('/dev/null', 'w')
+ else:
+ # Re-use parent file descriptors
+ input_source = self.config['stdin']
+ output_target = self.config['stdout']
+
+ proc = subprocess.Popen(args,
+ stdin=input_source,
+ stdout=output_target,
+ stderr=self.config['stderr'],
+ cwd=cwd,
+ env=env)
+
+ if self.quiet:
+ # Make child non-interactive
+ proc.stdin.close()
+
+ result = proc.wait()
+
+ if self.quiet:
+ output_target.close()
+
+ return result
+
+
+ def to_xml_hook(self, repo_elem):
+ pass