def pub_deploy(hosts, profiles=[], identities=[], settings={}): """ Setup a machine with a specified set of profiles. """ remote_paths = [] for host_path in hosts: parts = host_path.split(':') remote_paths += [parts[1]] if len(parts) > 1 else [DEFAULT_REMOTE_PATH] hosts = [host_path.split(':')[0] for host_path in hosts] host_ips = CLOUD_BACKEND.network_ip(hosts) for host, ipaddr in six.iteritems(host_ips): if not ipaddr: logging.error('cannot find IP for %s', host) fab.env.hosts = list(host_ips.values()) for host, remote_path in zip(fab.env.hosts, remote_paths): fab.env.host_string = host if identities: rsync, prefix = find_rsync(host, relative=True, admin=True, username=fab.env.user, key=fab.env.key_filename) for src_path in identities: cmdline = rsync + [src_path + '/./*', prefix + '/'] shell_command(cmdline) copy_setup(profiles, host, remote_path, settings=settings) run_dservices(profiles, host, remote_path, settings=settings)
def pub_stage(src_path, host): '''Copy a directory tree from the local machine to the staged machine root directory. This is often used to copy credentials before running a deploy command.''' rsync, prefix = find_rsync(host, relative=True, admin=True, username=fab.env.user, key=fab.env.key_filename) cmdline = rsync + [src_path + '/./*', prefix + '/'] shell_command(cmdline)
def pub_deploy(hosts, profiles=[], identities=[], settings={}): """ Setup a machine with a specified set of profiles. """ remote_paths = [] for host_path in hosts: parts = host_path.split(':') remote_paths += [parts[1]] if len(parts) > 1 else [DEFAULT_REMOTE_PATH] hosts = [host_path.split(':')[0] for host_path in hosts] host_ips = CLOUD_BACKEND.network_ip(hosts) for host, ipaddr in host_ips.iteritems(): if not ipaddr: logging.error('cannot find IP for %s', host) fab.env.hosts = host_ips.values() for host, remote_path in zip(fab.env.hosts, remote_paths): fab.env.host_string = host if identities: rsync, prefix = find_rsync(host, relative=True, admin=True, username=fab.env.user, key=fab.env.key_filename) for src_path in identities: cmdline = rsync + [src_path + '/./*', prefix + '/'] shell_command(cmdline) copy_setup(profiles, host, remote_path, settings=settings) run_dservices(profiles, host, remote_path, settings=settings)
def copy_setup(profiles, host, remote_path, settings=None): """ Copy scripts needed for configuration onto the remote machine. """ if settings is None: settings = {} pythondir = os.path.dirname(os.path.dirname(__file__)) basedir = os.path.dirname(os.path.dirname(os.path.dirname(pythondir))) bindir = os.path.join(basedir, 'bin') etcdir = os.path.join(basedir, 'etc') sharedir = os.path.join(basedir, 'share') profilesdir = os.path.join(sharedir, 'tero', 'profiles') files = [ os.path.join(pythondir, 'tero'), os.path.join(pythondir, 'dws'), os.path.join(bindir, 'dservices'), os.path.join(bindir, 'dbldpkg'), os.path.join(bindir, 'dws'), os.path.join(sharedir, 'dws'), os.path.join(sharedir, 'tero'), os.path.join(etcdir, 'tero', 'config') ] prefix = os.path.commonprefix(files) dirpath = tempfile.mkdtemp() stage_top = os.path.join(dirpath, os.path.basename(remote_path)) stage_profile_dir = os.path.join(stage_top, 'share', 'tero', 'profiles') for staged in files: stage_path = staged.replace(prefix, stage_top + os.sep) if not os.path.exists(os.path.dirname(stage_path)): os.makedirs(os.path.dirname(stage_path)) if os.path.isdir(staged): shutil.copytree(staged, stage_path) else: shutil.copy(staged, stage_path) for profile_name in profiles: look = re.match(r'\w+@(\w+.)+\w+:\S+', profile_name) if not look: # This does not look like a profile on a remote machine # so let's assume it is local file. profile_abs_path = os.path.abspath(profile_name) if not os.path.isfile(profile_abs_path): profile_abs_path = os.path.join(profilesdir, profile_name + '.xml') if not os.path.isfile(profile_abs_path): raise ValueError('cannot find profile "%s"' % profile_name) if not profile_abs_path.startswith(profilesdir): # We are setting up a profile which is not in the default set, # so let's copy it to the machine being setup as well. shutil.copy(profile_abs_path, stage_profile_dir) if fab.env.password: # We will need a sudo password to install packages and configure # them according to a profile. askpass_path = os.path.join(stage_top, 'bin', 'askpass') with open(askpass_path, 'w') as askpass: askpass.write('#!/bin/sh\n') askpass.write('echo %s\n' % fab.env.password) import stat os.chmod(askpass_path, stat.S_IRWXU) if True: # XXX Either implementation is asking for password # XXX admin=True otherwise we cannot create directory in /var/www. cmdline, prefix = find_rsync(host, relative=False, admin=False, key=fab.env.key_filename) cmdline += ['--exclude=".git"', dirpath + '/*'] dest = host + ':' + os.path.dirname(remote_path) if fab.env.user: dest = fab.env.user + '@' + dest cmdline += [dest] shell_command(cmdline) else: import fabric.contrib.project fabric.contrib.project.rsync_project( local_dir=dirpath + '/*', remote_dir=os.path.dirname(remote_path), exclude=['.git']) if not os.path.isdir(dirpath): shutil.rmtree(dirpath)
def copy_setup(profiles, host, remote_path, settings=None): """ Copy scripts needed for configuration onto the remote machine. """ if settings is None: settings = {} pythondir = os.path.dirname(os.path.dirname(__file__)) basedir = os.path.dirname(os.path.dirname(os.path.dirname(pythondir))) bindir = os.path.join(basedir, 'bin') etcdir = os.path.join(basedir, 'etc') sharedir = os.path.join(basedir, 'share') profilesdir = os.path.join(sharedir, 'tero', 'profiles') files = [os.path.join(pythondir, 'tero'), os.path.join(pythondir, 'dws'), os.path.join(bindir, 'dservices'), os.path.join(bindir, 'dbldpkg'), os.path.join(bindir, 'dws'), os.path.join(sharedir, 'dws'), os.path.join(sharedir, 'tero'), os.path.join(etcdir, 'tero', 'config')] prefix = os.path.commonprefix(files) dirpath = tempfile.mkdtemp() stage_top = os.path.join(dirpath, os.path.basename(remote_path)) stage_profile_dir = os.path.join( stage_top, 'share', 'tero', 'profiles') for staged in files: stage_path = staged.replace(prefix, stage_top + os.sep) if not os.path.exists(os.path.dirname(stage_path)): os.makedirs(os.path.dirname(stage_path)) if os.path.isdir(staged): shutil.copytree(staged, stage_path) else: shutil.copy(staged, stage_path) for profile_name in profiles: look = re.match(r'\w+@(\w+.)+\w+:\S+', profile_name) if not look: # This does not look like a profile on a remote machine # so let's assume it is local file. profile_abs_path = os.path.abspath(profile_name) if not os.path.isfile(profile_abs_path): profile_abs_path = os.path.join( profilesdir, profile_name + '.xml') if not os.path.isfile(profile_abs_path): raise ValueError('cannot find profile "%s"' % profile_name) if not profile_abs_path.startswith(profilesdir): # We are setting up a profile which is not in the default set, # so let's copy it to the machine being setup as well. shutil.copy(profile_abs_path, stage_profile_dir) if fab.env.password: # We will need a sudo password to install packages and configure # them according to a profile. askpass_path = os.path.join(stage_top, 'bin', 'askpass') with open(askpass_path, 'w') as askpass: askpass.write('#!/bin/sh\n') askpass.write('echo %s\n' % fab.env.password) import stat os.chmod(askpass_path, stat.S_IRWXU) if True: # XXX Either implementation is asking for password # XXX admin=True otherwise we cannot create directory in /var/www. cmdline, prefix = find_rsync( host, relative=False, admin=False, key=fab.env.key_filename) cmdline += ['--exclude=".git"', dirpath + '/*'] dest = host + ':' + os.path.dirname(remote_path) if fab.env.user: dest = fab.env.user + '@' + dest cmdline += [dest] shell_command(cmdline) else: import fabric.contrib.project fabric.contrib.project.rsync_project( local_dir=dirpath + '/*', remote_dir=os.path.dirname(remote_path), exclude=['.git']) if not os.path.isdir(dirpath): shutil.rmtree(dirpath)