def deploy_webconf(): """ Deploy nginx and other wsgi server site configurations to the host """ deployed = [] log_dir = '/'.join([deployment_root(), 'log']) #TODO - incorrect - check for actual package to confirm installation if webserver_list(): if env.verbosity: print env.host, "DEPLOYING webconf:" if not exists(log_dir): run('ln -s /var/log log') #deploys confs for each domain based on sites app if 'apache2' in get_packages(): deployed += _deploy_webconf('/etc/apache2/sites-available', 'django-apache-template.txt') deployed += _deploy_webconf('/etc/nginx/sites-available', 'nginx-template.txt') elif 'gunicorn' in get_packages(): deployed += _deploy_webconf('/etc/nginx/sites-available', 'nginx-gunicorn-template.txt') upload_template('woven/maintenance.html', '/var/www/nginx-default/maintenance.html', use_sudo=True) sudo('chmod ugo+r /var/www/nginx-default/maintenance.html') else: print env.host, """WARNING: Apache or Nginx not installed""" return deployed
def deploy_wsgi(): """ deploy python wsgi file(s) """ remote_dir = "/".join([deployment_root(), "env", env.project_fullname, "wsgi"]) deployed = [] if env.verbosity: print env.host, "DEPLOYING wsgi", remote_dir domains = domain_sites() for domain in domains: deployed += mkdirs(remote_dir) with cd(remote_dir): u_domain = domain.replace(".", "_") filename = "%s.wsgi" % u_domain context = { "deployment_root": deployment_root(), "user": env.user, "project_name": env.project_name, "u_domain": u_domain, "root_domain": env.root_domain, } upload_template("/".join(["woven", "django-wsgi-template.txt"]), filename, context) if env.verbosity: print " * uploaded", filename # finally set the ownership/permissions # We'll use the group to allow www-data execute sudo("chown %s:www-data %s" % (env.user, filename)) run("chmod ug+xr %s" % filename) return deployed
def deploy_webconf(): """ Deploy nginx and other wsgi server site configurations to the host """ deployed = [] log_dir = '/'.join([deployment_root(),'log']) #TODO - incorrect - check for actual package to confirm installation if webserver_list(): if env.verbosity: print env.host,"DEPLOYING webconf:" if not exists(log_dir): run('ln -s /var/log log') #deploys confs for each domain based on sites app if 'apache2' in get_packages(): deployed += _deploy_webconf('/etc/apache2/sites-available','django-apache-template.txt') deployed += _deploy_webconf('/etc/nginx/sites-available','nginx-template.txt') elif 'gunicorn' in get_packages(): deployed += _deploy_webconf('/etc/nginx/sites-available','nginx-gunicorn-template.txt') if not exists('/var/www/nginx-default'): sudo('mkdir /var/www/nginx-default') upload_template('woven/maintenance.html','/var/www/nginx-default/maintenance.html',use_sudo=True) sudo('chmod ugo+r /var/www/nginx-default/maintenance.html') else: print env.host,"""WARNING: Apache or Nginx not installed""" return deployed
def restrict_ssh(rollback=False): """ Set some sensible restrictions in Ubuntu /etc/ssh/sshd_config and restart sshd UseDNS no #prevents dns spoofing sshd defaults to yes X11Forwarding no # defaults to no AuthorizedKeysFile %h/.ssh/authorized_keys uncomments PasswordAuthentication no and restarts sshd """ if not rollback: if server_state('ssh_restricted'): print env.host, 'Warning: sshd_config has already been modified. Skipping..' return False sshd_config = '/etc/ssh/sshd_config' if env.verbosity: print env.host, "RESTRICTING SSH with "+sshd_config filename = 'sshd_config' if not exists('/home/%s/.ssh/authorized_keys'% env.user): #do not pass go do not collect $200 print env.host, 'You need to upload_ssh_key first.' return False _backup_file(sshd_config) context = {"HOST_SSH_PORT": env.HOST_SSH_PORT} upload_template('woven/ssh/sshd_config','/etc/ssh/sshd_config',context=context,use_sudo=True) # Restart sshd sudo('/etc/init.d/ssh restart') # The user can modify the sshd_config file directly but we save if env.INTERACTIVE and contains('#PasswordAuthentication no','/etc/ssh/sshd_config',use_sudo=True): c_text = 'Woven will now remove password login from ssh, and use only your ssh key. \n' c_text = c_text + 'CAUTION: please confirm that you can ssh %s@%s -p%s from a terminal without requiring a password before continuing.\n'% (env.user, env.host, env.port) c_text += 'If you cannot login, press enter to rollback your sshd_config file' proceed = confirm(c_text,default=False) if not env.INTERACTIVE or proceed: #uncomments PasswordAuthentication no and restarts uncomment(sshd_config,'#(\s?)PasswordAuthentication(\s*)no',use_sudo=True) sudo('/etc/init.d/ssh restart') else: #rollback print env.host, 'Rolling back sshd_config to default and proceeding without passwordless login' _restore_file('/etc/ssh/sshd_config', delete_backup=False) sed('/etc/ssh/sshd_config','Port '+ str(env.DEFAULT_SSH_PORT),'Port '+str(env.HOST_SSH_PORT),use_sudo=True) sudo('/etc/init.d/ssh restart') return False set_server_state('ssh_restricted') return True else: #Full rollback _restore_file('/etc/ssh/sshd_config') if server_state('ssh_port_changed'): sed('/etc/ssh/sshd_config','Port '+ str(env.DEFAULT_SSH_PORT),'Port '+str(env.HOST_SSH_PORT),use_sudo=True) sudo('/etc/init.d/ssh restart') sudo('/etc/init.d/ssh restart') set_server_state('ssh_restricted', delete=True) return True
def _deploy_webconf(remote_dir, template): if not 'http:' in env.MEDIA_URL: media_url = env.MEDIA_URL else: media_url = '' if not 'http:' in env.STATIC_URL: static_url = env.STATIC_URL else: static_url = '' if not static_url: static_url = env.ADMIN_MEDIA_PREFIX deployed = [] users_added = [] domains = domain_sites() for d in domains: u_domain = d.name.replace('.', '_') wsgi_filename = d.settings.replace('.py', '.wsgi') site_user = ''.join(['site_', str(d.site_id)]) filename = ''.join([remote_dir, '/', u_domain, '-', env.project_version, '.conf']) context = { "project_name": env.project_name, "deployment_root": deployment_root(), "u_domain": u_domain, "domain": d.name, "root_domain": env.root_domain, "user": env.user, "site_user": site_user, "SITE_ID": d.site_id, "host_ip": socket.gethostbyname(env.host), "wsgi_filename": wsgi_filename, "MEDIA_URL": media_url, "STATIC_URL": static_url, } upload_template('/'.join(['woven', template]), filename, context, use_sudo=True) if env.verbosity: print " * uploaded", filename # Add site users if necessary. site_users = _site_users() if site_user not in users_added and site_user not in site_users: add_user(username=site_user, group='www-data', site_user=True) users_added.append(site_user) if env.verbosity: print " * useradded", site_user return deployed
def _deploy_webconf(remote_dir, template): if not 'http:' in env.MEDIA_URL: media_url = env.MEDIA_URL else: media_url = '' if not 'http:' in env.STATIC_URL: static_url = env.STATIC_URL else: static_url = '' if not static_url: static_url = env.ADMIN_MEDIA_PREFIX log_dir = '/'.join([deployment_root(), 'log']) deployed = [] users_added = [] domains = domain_sites() for d in domains: u_domain = d.name.replace('.', '_') wsgi_filename = d.settings.replace('.py', '.wsgi') site_user = ''.join(['site_', str(d.site_id)]) filename = ''.join( [remote_dir, '/', u_domain, '-', env.project_version, '.conf']) context = { "project_name": env.project_name, "deployment_root": deployment_root(), "u_domain": u_domain, "domain": d.name, "root_domain": env.root_domain, "user": env.user, "site_user": site_user, "SITE_ID": d.site_id, "host_ip": socket.gethostbyname(env.host), "wsgi_filename": wsgi_filename, "MEDIA_URL": media_url, "STATIC_URL": static_url, } upload_template('/'.join(['woven', template]), filename, context, use_sudo=True) if env.verbosity: print " * uploaded", filename #add site users if necessary site_users = _site_users() if site_user not in users_added and site_user not in site_users: add_user(username=site_user, group='www-data', site_user=True) users_added.append(site_user) if env.verbosity: print " * useradded", site_user return deployed
def restrict_ssh(rollback=False): """ Set some sensible restrictions in Ubuntu /etc/ssh/sshd_config and restart sshd UseDNS no #prevents dns spoofing sshd defaults to yes X11Forwarding no # defaults to no AuthorizedKeysFile %h/.ssh/authorized_keys uncomments PasswordAuthentication no and restarts sshd """ if not rollback: if server_state('ssh_restricted'): return False sshd_config = '/etc/ssh/sshd_config' if env.verbosity: print env.host, "RESTRICTING SSH with "+sshd_config filename = 'sshd_config' if not exists('/home/%s/.ssh/authorized_keys'% env.user): #do not pass go do not collect $200 print env.host, 'You need to upload_ssh_key first.' return False _backup_file(sshd_config) context = {"HOST_SSH_PORT": env.HOST_SSH_PORT} upload_template('woven/ssh/sshd_config','/etc/ssh/sshd_config',context=context,use_sudo=True) # Restart sshd sudo('/etc/init.d/ssh restart') # The user can modify the sshd_config file directly but we save proceed = True if not env.key_filename and (env.DISABLE_SSH_PASSWORD or env.INTERACTIVE) and contains('/etc/ssh/sshd_config','#PasswordAuthentication no',use_sudo=True): print "WARNING: You may want to test your node ssh login at this point ssh %s@%s -p%s"% (env.user, env.host, env.port) c_text = 'Would you like to disable password login and use only ssh key authentication' proceed = confirm(c_text,default=False) if not env.INTERACTIVE or proceed or env.DISABLE_SSH_PASSWORD: #uncomments PasswordAuthentication no and restarts uncomment(sshd_config,'#(\s?)PasswordAuthentication(\s*)no',use_sudo=True) sudo('/etc/init.d/ssh restart') set_server_state('ssh_restricted') return True else: #Full rollback _restore_file('/etc/ssh/sshd_config') if server_state('ssh_port_changed'): sed('/etc/ssh/sshd_config','Port '+ str(env.DEFAULT_SSH_PORT),'Port '+str(env.HOST_SSH_PORT),use_sudo=True) sudo('/etc/init.d/ssh restart') sudo('/etc/init.d/ssh restart') set_server_state('ssh_restricted', delete=True) return True
def upload_etc(): """ Upload and render all templates in the woven/etc directory to the respective directories on the nodes Only configuration for installed packages will be uploaded where that package creates it's own subdirectory in /etc/ ie /etc/apache2. For configuration that falls in some other non package directories ie init.d, logrotate.d etc it is intended that this function only replace existing configuration files. To ensure we don't upload etc files that are intended to accompany a particular package. """ #determine the templatedir if env.verbosity: print "UPLOAD ETC configuration templates" if not hasattr(env, 'project_template_dir'): #the normal pattern would mean the shortest path is the main one. #its probably the last listed length = 1000 env.project_template_dir = '' for dir in env.TEMPLATE_DIRS: if dir: len_dir = len(dir) if len_dir < length: length = len_dir env.project_template_dir = dir template_dir = os.path.join(os.path.split(os.path.realpath(__file__))[0],'templates','') default_templates = _get_template_files(template_dir) if env.project_template_dir: user_templates = _get_template_files(os.path.join(env.project_template_dir,'')) else: user_templates = set([]) etc_templates = user_templates | default_templates context = {'host_ip':socket.gethostbyname(env.host)} for t in etc_templates: dest = t.replace('woven','') directory = os.path.split(dest)[0] if directory in ['/etc','/etc/init.d','/etc/init','/etc/logrotate.d','/etc/rsyslog.d']: #must be replacing an existing file if exists(dest): upload = True elif exists(directory, use_sudo=True): upload = True else: upload = False if upload: upload_template(t,dest,context=context,use_sudo=True) sudo(' '.join(["chown root:root",dest])) if 'init.d' in dest: sudo(' '.join(["chmod ugo+rx",dest])) else: sudo(' '.join(["chmod ugo+r",dest])) if env.verbosity: print " * uploaded",dest
def setup_ufw(): """ Setup basic ufw rules just for ssh login """ if not env.ENABLE_UFW: return ufw_state = server_state("ufw_installed") if ufw_state and not env.overwrite or ufw_state == str(env.HOST_SSH_PORT): return # Check for actual package. ufw = run("dpkg -l | grep 'ufw' | awk '{print $2}'").strip() if not ufw: if env.verbosity: print env.host, "INSTALLING & ENABLING FIREWALL ufw" install_package("ufw") if env.verbosity: print env.host, "CONFIGURING FIREWALL ufw" # Upload basic woven (ssh) ufw app config. upload_template( "/".join(["woven", "ufw.txt"]), "/etc/ufw/applications.d/woven", {"HOST_SSH_PORT": env.HOST_SSH_PORT}, use_sudo=True, backup=False, ) sudo("chown root:root /etc/ufw/applications.d/woven") with settings(warn_only=True): if not ufw_state: sudo("ufw allow woven") else: sudo("ufw app update woven") _backup_file("/etc/ufw/ufw.conf") # Enable ufw. sed("/etc/ufw/ufw.conf", "ENABLED=no", "ENABLED=yes", use_sudo=True, backup="") with settings(warn_only=True): output = sudo("ufw reload") if env.verbosity: print output set_server_state("ufw_installed", str(env.HOST_SSH_PORT)) return
def upload_etc(): """ Upload and render all templates in the woven/etc directory to the respective directories on the nodes Only configuration for installed packages will be uploaded where that package creates it's own subdirectory in /etc/ ie /etc/apache2. For configuration that falls in some other non package directories ie init.d, logrotate.d etc it is intended that this function only replace existing configuration files. To ensure we don't upload etc files that are intended to accompany a particular package. """ role = env.role_lookup[env.host_string] packages = env.packages[role] #determine the templatedir if env.verbosity: print "UPLOAD ETC configuration templates" if not hasattr(env, 'project_template_dir'): #the normal pattern would mean the shortest path is the main one. #its probably the last listed length = 1000 env.project_template_dir = '' for dir in env.TEMPLATE_DIRS: if dir: len_dir = len(dir) if len_dir < length: length = len_dir env.project_template_dir = dir template_dir = os.path.join(os.path.split(os.path.realpath(__file__))[0],'templates','') default_templates = _get_template_files(template_dir) if env.project_template_dir: user_templates = _get_template_files(os.path.join(env.project_template_dir,'')) else: user_templates = set([]) etc_templates = user_templates | default_templates context = {'host_ip':socket.gethostbyname(env.host)} if env.overwrite or env.installed_packages[env.host]: mod_only = False else: mod_only = True for t in etc_templates: dest = t.replace('woven','',1) directory,filename = os.path.split(dest) package_name = filename.split('.')[0] if directory in ['/etc','/etc/init.d','/etc/init','/etc/logrotate.d','/etc/rsyslog.d']: #must be replacing an existing file if not exists(dest) and package_name not in packages: continue elif directory == '/etc/ufw/applications.d': #must be a package name if filename not in packages: continue elif not exists(directory, use_sudo=True): continue uploaded = upload_template(t,dest,context=context,use_sudo=True, modified_only=mod_only) if uploaded: sudo(' '.join(["chown root:root",dest])) if 'init.d' in dest: sudo(' '.join(["chmod ugo+rx",dest])) else: sudo(' '.join(["chmod ugo+r",dest])) if env.verbosity: print " * uploaded",dest
def deploy_webconf(): """ Deploy apache & nginx site configurations to the host """ deployed = [] log_dir = "/".join([deployment_root(), "log"]) # TODO - incorrect - check for actual package to confirm installation if exists("/etc/apache2/sites-enabled/") and exists("/etc/nginx/sites-enabled"): if env.verbosity: print env.host, "DEPLOYING webconf:" if not exists(log_dir): run("ln -s /var/log log") deployed += _deploy_webconf("/etc/apache2/sites-available", "django-apache-template.txt") deployed += _deploy_webconf("/etc/nginx/sites-available", "nginx-template.txt") upload_template("woven/maintenance.html", "/var/www/nginx-default/maintenance.html", use_sudo=True) sudo("chmod ugo+r /var/www/nginx-default/maintenance.html") else: print env.host, """WARNING: Apache or Nginx not installed""" return deployed
def setup_ufw(): """ Setup basic ufw rules just for ssh login """ if not env.ENABLE_UFW: return ufw_state = server_state('ufw_installed') if ufw_state and not env.overwrite or ufw_state == str(env.HOST_SSH_PORT): return #check for actual package ufw = run("dpkg -l | grep 'ufw' | awk '{print $2}'").strip() if not ufw: if env.verbosity: print env.host, "INSTALLING & ENABLING FIREWALL ufw" install_package('ufw') if env.verbosity: print env.host, "CONFIGURING FIREWALL ufw" #upload basic woven (ssh) ufw app config upload_template('/'.join(['woven','ufw.txt']), '/etc/ufw/applications.d/woven', {'HOST_SSH_PORT':env.HOST_SSH_PORT}, use_sudo=True, backup=False) sudo('chown root:root /etc/ufw/applications.d/woven') with settings(warn_only=True): if not ufw_state: sudo('ufw allow woven') else: sudo('ufw app update woven') _backup_file('/etc/ufw/ufw.conf') #enable ufw sed('/etc/ufw/ufw.conf','ENABLED=no','ENABLED=yes',use_sudo=True, backup='') with settings(warn_only=True): output = sudo('ufw reload') if env.verbosity: print output set_server_state('ufw_installed',str(env.HOST_SSH_PORT)) return
def _deploy_webconf(remote_dir, template): if not "http:" in env.MEDIA_URL: media_url = env.MEDIA_URL else: media_url = "" if not "http:" in env.STATIC_URL: static_url = env.STATIC_URL else: static_url = "" if not static_url: static_url = env.ADMIN_MEDIA_PREFIX log_dir = "/".join([deployment_root(), "log"]) deployed = [] domains = domain_sites() for d in domains: u_domain = d.replace(".", "_") filename = "".join([remote_dir, "/", u_domain, "-", env.project_version, ".conf"]) context = { "project_name": env.project_name, "deployment_root": deployment_root(), "u_domain": u_domain, "domain": d, "root_domain": env.root_domain, "user": env.user, "host_ip": socket.gethostbyname(env.host), "media_url": media_url, "static_url": static_url, } upload_template("/".join(["woven", template]), filename, context, use_sudo=True) if env.verbosity: print " * uploaded", filename return deployed
def restrict_ssh(rollback=False): """ Set some sensible restrictions in Ubuntu /etc/ssh/sshd_config and restart sshd. UseDNS no # Prevents dns spoofing sshd defaults to yes X11Forwarding no # Defaults to no AuthorizedKeysFile %h/.ssh/authorized_keys Also uncomment PasswordAuthentication no and restart sshd. """ if not rollback: if server_state("ssh_restricted"): return False sshd_config = "/etc/ssh/sshd_config" if env.verbosity: print env.host, "RESTRICTING SSH with " + sshd_config if not exists("/home/%s/.ssh/authorized_keys" % env.user): # Do not pass go, do not collect $200. print env.host, "You need to upload_ssh_key first." return False _backup_file(sshd_config) context = {"HOST_SSH_PORT": env.HOST_SSH_PORT} upload_template("woven/ssh/sshd_config", "/etc/ssh/sshd_config", context=context, use_sudo=True) # Restart sshd. sudo("/etc/init.d/ssh restart") # The user can modify the sshd_config file directly but we save. proceed = True if ( not env.key_filename and (env.DISABLE_SSH_PASSWORD or env.INTERACTIVE) and contains("/etc/ssh/sshd_config", "#PasswordAuthentication no", use_sudo=True) ): print "WARNING: You may want to test your node ssh login " "at this point ssh %s@%s -p%s" % ( env.user, env.host, env.port, ) c_text = "Would you like to disable password login and use " "only ssh key authentication" proceed = confirm(c_text, default=False) if not env.INTERACTIVE or proceed or env.DISABLE_SSH_PASSWORD: # Uncomments PasswordAuthentication no and restarts. uncomment(sshd_config, "#(\s?)PasswordAuthentication(\s*)no", use_sudo=True) sudo("/etc/init.d/ssh restart") set_server_state("ssh_restricted") return True else: # Full rollback. _restore_file("/etc/ssh/sshd_config") if server_state("ssh_port_changed"): sed( "/etc/ssh/sshd_config", "Port " + str(env.DEFAULT_SSH_PORT), "Port " + str(env.HOST_SSH_PORT), use_sudo=True, ) sudo("/etc/init.d/ssh restart") sudo("/etc/init.d/ssh restart") set_server_state("ssh_restricted", delete=True) return True
def deploy_wsgi(): """ deploy python wsgi file(s) """ if 'libapache2-mod-wsgi' in get_packages(): remote_dir = '/'.join([deployment_root(),'env',env.project_fullname,'wsgi']) wsgi = 'apache2' elif 'gunicorn' in get_packages(): remote_dir = '/etc/init' wsgi = 'gunicorn' deployed = [] #ensure project apps path is also added to environment variables as well as wsgi if env.PROJECT_APPS_PATH: pap = '/'.join([deployment_root(),'env', env.project_name,'project',env.project_package_name,env.PROJECT_APPS_PATH]) pap = ''.join(['export PYTHONPATH=$PYTHONPATH:',pap]) postactivate = '/'.join([deployment_root(),'env','postactivate']) if not exists(postactivate): append('#!/bin/bash', postactivate) run('chmod +x %s'% postactivate) if not contains('PYTHONPATH',postactivate): append(pap,postactivate) if env.verbosity: print env.host,"DEPLOYING wsgi", wsgi, remote_dir for file in _sitesettings_files(): deployed += mkdirs(remote_dir) with cd(remote_dir): settings_module = file.replace('.py','') context = {"deployment_root":deployment_root(), "user": env.user, "project_name": env.project_name, "project_package_name": env.project_package_name, "project_apps_path":env.PROJECT_APPS_PATH, "settings": settings_module, } if wsgi == 'apache2': filename = file.replace('.py','.wsgi') upload_template('/'.join(['woven','django-wsgi-template.txt']), filename, context, ) elif wsgi == 'gunicorn': filename = 'gunicorn-%s.conf'% env.project_name upload_template('/'.join(['woven','gunicorn.conf']), filename, context, backup=False, use_sudo=True ) if env.verbosity: print " * uploaded", filename #finally set the ownership/permissions #We'll use the group to allow www-data execute if wsgi == 'apache2': sudo("chown %s:www-data %s"% (env.user,filename)) run("chmod ug+xr %s"% filename) elif wsgi == 'gunicorn': sudo("chown root:root %s"% filename) sudo("chmod go+r %s"% filename) return deployed
def deploy_wsgi(): """ deploy python wsgi file(s) """ if 'libapache2-mod-wsgi' in get_packages(): remote_dir = '/'.join( [deployment_root(), 'env', env.project_fullname, 'wsgi']) wsgi = 'apache2' elif 'gunicorn' in get_packages(): remote_dir = '/etc/init' wsgi = 'gunicorn' deployed = [] #ensure project apps path is also added to environment variables as well as wsgi if env.PROJECT_APPS_PATH: pap = '/'.join([ deployment_root(), 'env', env.project_name, 'project', env.project_package_name, env.PROJECT_APPS_PATH ]) pap = ''.join(['export PYTHONPATH=$PYTHONPATH:', pap]) postactivate = '/'.join([deployment_root(), 'env', 'postactivate']) if not exists(postactivate): append('#!/bin/bash', postactivate) run('chmod +x %s' % postactivate) if not contains('PYTHONPATH', postactivate): append(pap, postactivate) if env.verbosity: print env.host, "DEPLOYING wsgi", wsgi, remote_dir for file in _sitesettings_files(): deployed += mkdirs(remote_dir) with cd(remote_dir): settings_module = file.replace('.py', '') context = { "deployment_root": deployment_root(), "user": env.user, "project_name": env.project_name, "project_package_name": env.project_package_name, "project_apps_path": env.PROJECT_APPS_PATH, "settings": settings_module, } if wsgi == 'apache2': filename = file.replace('.py', '.wsgi') upload_template( '/'.join(['woven', 'django-wsgi-template.txt']), filename, context, ) elif wsgi == 'gunicorn': filename = 'gunicorn-%s.conf' % env.project_name upload_template('/'.join(['woven', 'gunicorn.conf']), filename, context, backup=False, use_sudo=True) if env.verbosity: print " * uploaded", filename #finally set the ownership/permissions #We'll use the group to allow www-data execute if wsgi == 'apache2': sudo("chown %s:www-data %s" % (env.user, filename)) run("chmod ug+xr %s" % filename) elif wsgi == 'gunicorn': sudo("chown root:root %s" % filename) sudo("chmod go+r %s" % filename) return deployed
def upload_etc(): """ Upload and render all templates in the woven/etc directory to the respective directories on the nodes. Only configuration for installed packages will be uploaded where that package creates its own subdirectory in /etc/ eg. /etc/apache2. For configuration that falls in some other non package directories, ie. init.d, logrotate.d etc., it is intended that this function only replace existing configuration files. To ensure we don't upload etc files that are intended to accompany a particular package. """ role = env.role_lookup[env.host_string] packages = env.packages[role] # Determine the templatedir. if env.verbosity: print "UPLOAD ETC configuration templates" if not hasattr(env, "project_template_dir"): # The normal pattern would mean the shortest path is the main # one. It's probably the last listed. length = 1000 env.project_template_dir = "" for directory in env.TEMPLATE_DIRS: if directory: len_dir = len(directory) if len_dir < length: length = len_dir env.project_template_dir = directory template_dir = os.path.join(os.path.split(os.path.realpath(__file__))[0], "templates", "") default_templates = _get_template_files(template_dir) if env.project_template_dir: user_templates = _get_template_files(os.path.join(env.project_template_dir, "")) else: user_templates = set([]) etc_templates = user_templates | default_templates context = {"host_ip": socket.gethostbyname(env.host)} if env.overwrite or env.installed_packages[env.host]: mod_only = False else: mod_only = True for t in etc_templates: dest = t.replace("woven", "", 1) directory, filename = os.path.split(dest) package_name = filename.split(".")[0] if directory in ["/etc", "/etc/init.d", "/etc/init", "/etc/logrotate.d", "/etc/rsyslog.d"]: # Must be replacing an existing file. if not exists(dest) and package_name not in packages: continue elif directory == "/etc/ufw/applications.d": # Must be a package name. if filename not in packages: continue elif not exists(directory, use_sudo=True): continue uploaded = upload_template(t, dest, context=context, use_sudo=True, modified_only=mod_only) if uploaded: sudo(" ".join(["chown root:root", dest])) if "init.d" in dest: sudo(" ".join(["chmod ugo+rx", dest])) else: sudo(" ".join(["chmod ugo+r", dest])) if env.verbosity: print " * uploaded", dest