def deploy(self, patch=False): if not exists(self.deploy_root): run("mkdir -p %s" % self.deploy_root) with cd(self.deploy_root): u_domain = self.domain.replace('.','_') filename = "%s.wsgi"% u_domain context = {"user": env.user, "project_name": env.project_name, "u_domain":u_domain, "root_domain":env.root_domain, } wsgi_exists = exists(filename) if wsgi_exists and not patch: print env.host,"%s already exists on the host %s. Skipping..."% (self.deploy_type,filename) return False elif not wsgi_exists and patch: print env.host,"Error: Cannot patch %s %s. This version does not exist"% (project_fullname(), self.deploy_type) return False current_version = active_version() if current_version == env.project_fullname and not patch: print env.host,"Warning: Cannot deploy %s, version %s already active. Increase the version and re-deploy. Skipping.."% (self.deploy_type,env.project_fullname) return False else: #not exists upload_template('woven/'+self.template, filename, context, ) #finally set the ownership/permissions #We'll use the group to allow www-data execute if self.deploy_type == 'wsgi': sudo("chown %s:www-data %s"% (env.user,filename)) run("chmod ug+xr %s"% filename) set_server_state(self.state+env.project_fullname)
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(self,patch=False): with cd(self.deploy_root): log_dir = env.deployment_root+'log' if not exists(log_dir): run("mkdir -p %s"% log_dir) sudo("chown -R www-data:sudo %s" % log_dir) sudo("chmod -R ug+w %s"% log_dir) u_domain = self.domain.replace('.','_') filename = u_domain + '-'+self.version+'.conf' context = {"project_name": env.project_name, "u_domain":u_domain, "domain":self.domain, "root_domain":env.root_domain, "user":env.user, "host_ip":env.host, "media_url":self.media_url, "static_url":self.static_url, } conf_exists = exists(os.path.join(self.enabled_path,filename), use_sudo=True) state = server_state(self.state+env.project_fullname) if not conf_exists and patch: if env.verbosity: print env.host,"Cannot patch %s conf %s. This version does not exist on %s. Skipping"% (self.deploy_type, filename, env.host) return False elif state and not patch: #active version print "%s conf %s already exists on the host %s. Skipping"% (self.deploy_type, filename, env.host) return False else: enabled_sites = _ls_sites(self.enabled_path) if not patch: for site in enabled_sites: if env.verbosity: print env.host,'Disabling', site, filename sudo("rm %s%s"% (self.enabled_path,site)) upload_template('woven/'+self.template, filename, context, use_sudo=True) if not patch: #enable this site sudo("chmod 644 %s" % filename) if not exists(self.enabled_path+ filename): sudo("ln -s %s%s %s%s"% (self.deploy_root,filename,self.enabled_path,filename)) set_server_state(self.state + self.fullname) if env.verbosity: print env.host,'DEPLOYED',self.deploy_type
def install_packages(rollback = False,overwrite=False): """ Install a set of baseline packages on Ubuntu Server and configure where necessary overwrite will allow existing configurations to be overwritten """ u = env.HOST_BASE_PACKAGES + env.HOST_EXTRA_PACKAGES if not rollback: if env.verbosity: print env.host, "INSTALLING & CONFIGURING HOST PACKAGES:" #print ','.join(u) #Remove apparmor - TODO we may enable this later sudo('/etc/init.d/apparmor stop') sudo('update-rc.d -f apparmor remove') #Get a list of installed packages p = run("dpkg -l | awk '/ii/ {print $2}'").split('\n') #The principle we will use is to only install configurations and packages #if they do not already exist (ie manually installed or other method) for package in u: if not package in p: preinstalled = False apt_get_install(package) sudo("echo '%s' >> /var/local/woven/packages_installed.txt"% package) if package == 'apache2': sudo("a2dissite 000-default") elif package == 'nginx': sudo('rm -f /etc/nginx/sites-enabled/default') if env.verbosity: print ' * installed '+package else: preinstalled = True if package == 'apache2' and (overwrite or not preinstalled): if env.verbosity: print "Uploading Apache2 template /etc/apache2/ports.conf" context = {'host_ip':env.host} upload_template('woven/apache2/ports.conf','/etc/apache2/ports.conf',context=context, use_sudo=True) #Turn keep alive off on apache sed('/etc/apache2/apache2.conf',before='KeepAlive On',after='KeepAlive Off',use_sudo=True) with settings(warn_only=True): sudo("apache2ctl stop") elif package == 'nginx' and (overwrite or not preinstalled): if env.verbosity: print "Uploading Nginx templates /etc/nginx/nginx.conf /etc/nginx/proxy.conf" upload_template('woven/nginx/nginx.conf','/etc/nginx/nginx.conf',use_sudo=True) #Upload a default proxy upload_template('woven/nginx/proxy.conf','/etc/nginx/proxy.conf',use_sudo=True) with settings(warn_only=True): sudo("/etc/init.d/nginx stop") #Set unattended-updates configuration unattended_config = '/etc/apt/apt.conf.d/10periodic' if not exists(unattended_config, use_sudo=True): if env.verbosity: "Configuring unattended-updates /etc/apt/apt.conf.d/10periodic" sudo('touch '+unattended_config) #in theory append() should intelligently ignore lines if they already exist #in practice this doesn't work as expected for this particular list. #possibly some characters it is not matching correctly hence if the #file already exists we'll skip this append([ 'APT::Periodic::Update-Package-Lists "1";', 'APT::Periodic::Download-Upgradeable-Packages "1";', 'APT::Periodic::AutocleanInterval "7";', 'APT::Periodic::Unattended-Upgrade "1";', ], filename=' /etc/apt/apt.conf.d/10periodic',use_sudo=True) set_server_state('unattended_config_created') #Install base python packages #We'll use easy_install at this stage since it doesn't download if the package #is current whereas pip always downloads. #Once both these packages mature we'll move to using the standard Ubuntu packages sudo("easy_install -U virtualenv") sudo("easy_install -U pip") #cleanup after easy_install sudo("rm -rf build") else: #rollback p = sudo('cat /var/local/woven/packages_installed.txt').split('\n') for package in u: if package in p: apt_get_purge(package) p.remove(package) #Finally write back the list of packages sudo('rm -f /var/local/woven/packages_installed.txt') for package in p: sudo("echo '%s' >> /var/local/woven/packages_installed.txt"% package) #Rollback unattended updates if server_state('unattended_config_created'): sudo('rm -rf /etc/apt/apt.conf.d/10periodic') set_server_state('unattended_config_created',delete=True) #Finally remove any unneeded packages sudo('apt-get autoremove -qqy')