def run_deployment_callbacks(self): if hasattr(self, 'deploy_script') and self.callbacks: ansi.writeout('Executing deploy-script: %s' % self.deploy_script) proc = subprocess.Popen(self.deploy_script, stdin=subprocess.PIPE) for callback in self.callbacks: action = '%s %s' % callback ansi.writeout('->%s' % action) print >> proc.stdin, action proc.stdin.close() n = proc.wait() if 0 != n: raise subprocess.CalledProcessError(n, self.deploy_script)
def main(): import optparse import posix if 'HOME' not in os.environ or os.environ['HOME'] == '' or os.environ['HOME'] == '/': os.environ['HOME'] = pwd.getpwuid(posix.getuid())[7] parser = optparse.OptionParser() parser.add_option('-q', '--quiet', action='store_true', help='Silence output') parser.add_option('-f', '--force', action='store_true', help='Force apply changes') parser.add_option('--no-reinstall-broken', action='store_false', help="Don't reinstall locally modified rpms", dest='reinstall', default=True) parser.add_option('-D', '--deploy', action='store_true', help='Deploy changes') parser.add_option('-d', '--repo-path', help='Repo path') parser.add_option('-b', '--backup', action='store_true', help='backup files') parser.add_option('--noacl', action='store_true', help='Disable ACL support') parser.add_option('--origin', help='URL for Git Repository origin') parser.add_option('--branch', default='master', help='Default: %default') parser.add_option('--diffs', action='store_true', help='Show diffs') parser.add_option('--info', metavar='MACHINE', help='Dump deployment info for a machine') parser.add_option('--assume-host', metavar='HOSTNAME', help='Assume the given hostname') parser.add_option('--holdup-diffs', action='store_true', help='Show holdup diffs') (options, args) = parser.parse_args() if options.noacl: os.environ['GITMAN_NOACL'] = '1' # import ACL in the global namespace # ACL module uses GITMAN_NOACL environment variable for conditional # compilation eval( compile( 'from acl import ACL, has_xacl', __file__, 'single'), globals(), globals()) if not options.repo_path: parser.error('-d/--repo-path required') if options.force and not options.deploy: parser.error('Cannot force without deployment') if options.info: if options.quiet or options.deploy or options.backup or options.diffs or options.holdup_diffs: parser.error('Cannot use -q/-D/-b/--diffs/--holdup-diffs with --info') if options.diffs and options.holdup_diffs: parser.error('--diffs and --holdup-diffs should not be used together') verbose = not options.quiet and not options.info gitman = GitMan( os.path.abspath(options.repo_path), options.origin, options.branch, assume_host=options.assume_host, info=options.info) if verbose: ansi.writeout('Deployed version: %s' % gitman.deployed_version()) ansi.writeout('Newest version: %s' % gitman.latest_version()) ansi.writeout(' %d revisions between deployed and latest' % gitman.undeployed_revisions()) if options.info is None: holdups, verbose_info, failures = gitman.show_deployment(options.diffs, options.holdup_diffs) if verbose: ansi.writeout('\n'.join(verbose_info)) if failures: ansi.writeout('${BRIGHT_RED}%s${RESET}' % '\n'.join(failures)) if len(holdups) > 0 and not options.force: ansi.writeout('${BRIGHT_YELLOW}Force deployment needed:${RESET}') ansi.writeout('${BRIGHT_RED}%s${RESET}' % '\n'.join(holdups)) if options.deploy: sys.exit('Deployment skipped due to holdups...') if options.deploy: if failures: sys.exit('Deployment skipped due to failures...') gitman.deploy(backup=options.backup, force=options.force, reinstall=options.reinstall) else: print 'Showing deployment info for:', gitman.config['host_file'] gitman.dump_added()
def deploy(self, force, backup, reinstall=True): self.callbacks.run_pre_script() #Delete files for file, sys_file, orig_args in reversed(self.deleted_files()): if exists(file): if backup: os.rename(file, '%s.gitman' % file) elif orig_args['isdir']: try: os.rmdir(file) except: ansi.writeout('${BRIGHT_RED}ERROR: Failed to remove directory: %s${RESET}' % file) else: os.unlink(file) #Add files for file, sys_file, new_args in self.added_files(): dir = os.path.dirname(file) if not os.path.isdir(dir): os.makedirs(dir) if new_args['dirattr']: new_args['dirattr'].applyto(dir) if new_args['isdir']: if not os.path.exists(file): os.mkdir(file) else: fs.copy(sys_file, file, backup) if not os.path.islink(file): new_args['acl'].applyto(file) #Update files for file, sys_file, orig_args, new_args in self.common_files(): dir = os.path.dirname(file) if not os.path.isdir(dir): os.makedirs(dir) if new_args['dirattr']: new_args['dirattr'].applyto(dir) if new_args['isdir']: if not os.path.exists(file): os.mkdir(file) else: fs.copy(sys_file, file, backup) if not os.path.islink(file): new_args['acl'].applyto(file) for crontab in self.deleted_crontabs(): cmd = 'crontab -r -u %s' % crontab['user'] if 0 != os.system(cmd): raise RuntimeError('Failed to run cmd: %s' % cmd) crontabs = self.added_crontabs() crontabs.extend(self.modified_crontabs()) for crontab in crontabs: cmd = 'crontab -u %s %s' % (crontab['user'], crontab['crontab'].name) if 0 != os.system(cmd): raise RuntimeError('Failed to run cmd: %s' % cmd) self.rpmdb.run(test=False, reinstall=reinstall) self.callbacks.run_deployment_callbacks() self.callbacks.run_post_script() with open(os.path.join(self.path, self.deploy_file), 'w') as f: f.write(self.latest_version())
def run_post_script(self): if hasattr(self, 'pre_script'): ansi.writeout('Executing post-script: %s' % self.post_script) subprocess.check_call(self.post_script)