def __init__(self, source_dir, dist_dir, temp_dir=None): self.need_cleanup = False self.temp_dir = temp_dir self.source_dir = source_dir if self.temp_dir is None: self.need_cleanup = True self.temp_dir = tempfile.mkdtemp() self.roster = Roster( '%s/roster' % source_dir ) self.roster.read() # TODO: Load modules and ensure all files doctrine files exist #for role_name in self.roster.all_roles: # if not os.path.exists( os.path.join(self.source_dir, 'roles', role_name + '.py') ): # raise ProfigureException('Missing file "roles/%s.py" for role %s' % (role_name, role_name)) self.dist_dir = dist_dir self.build_dir = '%s/build' % self.temp_dir self.hosts_dir = '%s/build/hosts' % self.temp_dir self.roles_dir = '%s/build/roles' % self.temp_dir shell_silent('rm -rf %s' % self.temp_dir) for d in (self.dist_dir, self.build_dir): shell_silent('mkdir -p %s' % d) self._copy_and_compile() sys.path.append( self.build_dir ) self.load_modules()
class Builder (object): def __init__(self, source_dir, dist_dir, temp_dir=None): self.need_cleanup = False self.temp_dir = temp_dir self.source_dir = source_dir if self.temp_dir is None: self.need_cleanup = True self.temp_dir = tempfile.mkdtemp() self.roster = Roster( '%s/roster' % source_dir ) self.roster.read() # TODO: Load modules and ensure all files doctrine files exist #for role_name in self.roster.all_roles: # if not os.path.exists( os.path.join(self.source_dir, 'roles', role_name + '.py') ): # raise ProfigureException('Missing file "roles/%s.py" for role %s' % (role_name, role_name)) self.dist_dir = dist_dir self.build_dir = '%s/build' % self.temp_dir self.hosts_dir = '%s/build/hosts' % self.temp_dir self.roles_dir = '%s/build/roles' % self.temp_dir shell_silent('rm -rf %s' % self.temp_dir) for d in (self.dist_dir, self.build_dir): shell_silent('mkdir -p %s' % d) self._copy_and_compile() sys.path.append( self.build_dir ) self.load_modules() def __del__(self): self.cleanup() def cleanup(self): if self.need_cleanup: self.need_cleanup = False shutil.rmtree( self.temp_dir ) self.temp_dir = None def _copy_and_compile(self): # Copy content to temporary directory & cheetah compile templates shell_silent('cp -r %s/* %s' % (self.source_dir, self.build_dir)) # Rename all host/role.py files to corresponding '__init__.py' def rename_file( parent_dir, module_name ): mdir = os.path.join(parent_dir, module_name) pyfile = os.path.join(parent_dir, module_name + '.py') init = os.path.join(mdir, '__init__.py') if not os.path.exists(parent_dir): os.mkdir( parent_dir ) if not os.path.exists( mdir ): os.mkdir( mdir ) if os.path.exists( pyfile ): os.rename( pyfile, init ) else: with open( init, 'w' ) as f: f.write('from profigure import *\ndoctrine = Doctrine()\n') for r in self.roster.all_roles: rename_file( os.path.join(self.build_dir, 'roles'), r ) for h in self.roster.all_hosts: rename_file( os.path.join(self.build_dir, 'hosts'), h ) for rh in ('hosts', 'roles'): d = os.path.join(self.build_dir,rh) if not os.path.exists(d): os.mkdir(d) with open( os.path.join(d,'__init__.py'), 'w' ) as fobj: pass print shell_output( 'cd %s; cheetah compile -R' % self.build_dir ) # TODO: Ensure all templates compiled successfully #--------------------------------------------------------------------------- # Module load & doctrine verification # def check_doctrine(self, module_name, dirpath): module = sys.modules[ module_name ] have_dir = os.path.exists( dirpath ) kind = 'hosts' if module_name.startswith('hosts') else 'roles' base_name = module_name[ module_name.rfind('.')+1: ] src_file = os.path.join(self.source_dir, kind, base_name) + '.py' mod_dir = os.path.join(self.build_dir, kind, base_name) doc = getattr( module, 'doctrine', None ) if not isinstance(doc, Doctrine): raise ProfigureException('Error: %s "define_doctrine()" function did not return a Doctrine object!' % src_file) for cfg in doc.iter_config_files(): if not cfg.file_name.startswith('/') or cfg.file_name.endswith(' '): raise ProfigureException('Invalid configuration file path "%s". All paths must be absolute and contain no leading or trailing spaces.' % cfg.file_name) if cfg.template_name.endswith('.tmpl'): mod = '%s.%s' % (module_name, cfg.template_name[:-5]) fn = os.path.join(mod_dir, cfg.template_name[:-5] + '.py') err_file = mod.replace('.','/') + '.tmpl' if not os.path.exists(fn): raise ProfigureException('Missing Cheetah compiled .py file for template: %s' % err_file) try: __import__( mod ) except ImportError, e: raise ProfigureException('Python module import failed in %s: %s' % (err_file, str(e))) else: fn = os.path.join(mod_dir, cfg.template_name) if not os.path.exists( fn ): k = 'host' if kind == 'hosts' else 'role' raise ProfigureException('Missing static file "%s" for %s "%s"' % (cfg.template_name, k, module_name[ module_name.find('.')+1: ]))