def trac_admin(env, cmd, sudoer=None): """ Runs trac-admin command on specified environment with permiss :param env: Name or path to the environment :param cmd: Command to pass to trac-admin :param sudoer: Optional sudo user, defaults to Apache user Examples:: fab dist.trac_admin:home,help fab dist.trac_admin:"home","mp deploy" fab dist.trac_admin:env="home",cmd="mp deploy",sudoer="root" fab dist.trac_admin:"/var/www/trac/projects/projectx","upgrade" fab dist.trac_admin:"/var/www/trac/projects/projectx","upgrade","www-data" """ trac_root_dir = config['trac_root'] sudoer = sudoer or config['webserver_user'] if sudoer == 'root': sudoer = None # Check if path is given, otherwise consider it project name if not exists(env): env = os.path.join(trac_root_dir, 'projects', env) if not exists(env): return abort('Given environment "%s" cannot be found on server' % env) with cd(env): tracadmin_cmd = 'trac-admin %s %s' % (env, cmd) sudo(tracadmin_cmd, user=sudoer)
def reset_databases(dumpfile): """ Recreate mysql database based from given dump """ put(dumpfile, "dump.sql") mysql = Service('mysql') mysql.stop() sudo('rm -rf /var/lib/mysql/') sudo('mysql_install_db') mysql.start() # Set new password for tracuser password = prompt('Set password for database user "tracuser": '******'mysqladmin -u root password "%s"' % password) sudo(""" echo "UPDATE mysql.user SET password=password(\'\') WHERE user=\'tracuser\';" >> dump.sql echo "UPDATE mysql.user SET password=password(\'{0}\') WHERE user=\'root\';" >> dump.sql echo "UPDATE trac_admin.user SET sha1_pw=sha1(\'{0}\'), mail=\'root@localhost\';" >> dump.sql echo "flush privileges;" >> dump.sql mysql -u root --password={0} < dump.sql """.format(password)) sudo('rm dump.sql')
def deploy_targz(packagename, opts): """ Run the deploy activities for source/custom tar.gz package. The script can deploy following kind of tar.gz packages: - Python source package: if setup.py is found from root folder, it is run with python setup.py install - Custom source package (created with build task): runs scripts/deploy.sh found from the package :param str packagename: Name of the package to deploy. Example 'mypackage-1.1.0.tar.gz' :param str opts: Optional parameters to pass to deploying app (easy_install, rpm, dpkg, deploy.sh) """ root_dir = config['trac_root'] webserver_user = config['webserver_user'] webserver_group = config['webserver_group'] releasename, releaseversion, releaseextension = split_package_name( packagename) # Get the subdirectory (where all the files are place) of the archive, if any out = run('tar ztf %s' % packagename) subdir = os.path.commonprefix(out.stdout.splitlines()) run('tar zxf %s' % packagename) with cd('~/%s' % subdir): # Run the setup.py if is found if exists('setup.py'): logger.info( 'Installing python module from source, using: %s/setup.py' % releasename) sudo('python setup.py install %s' % opts) # Custom package, expect to find scripts/deploy.sh else: logger.info( 'Running deploy script ./scripts/deploy.sh at directory: %s' % subdir) with settings(show('stdout')): sudo('./scripts/deploy.sh %s' % opts) # Fix file permissions logger.info('Setting the permissions to deployment folder') sudo('chown -L -R %s:%s %s' % (webserver_user, webserver_group, join(root_dir, 'dist', 'current'))) # Cleanup - needs to be done with sudo because of sudo is being used at running deploy.sh (at the moment) with cd('~'): logger.info('Cleaning up...') if subdir: sudo('rm -rf ./%s' % subdir) sudo('rm -rf ./%s' % releasename)
def deploy(package, opts=''): """ Uploads the given package to remote host and deploys it there. :param str package: Path to tar.gz package in local file system. In case of wildcard, all the matched package are deployed. Package can be in formats: tar.gz (custom package structure, deb, rpm :param str opts: Optional parameters to pass to deploying app (easy_install, rpm, dpkg, deploy.sh) Examples:: fab dist.deploy:package=../../package.tar.gz fab dist.deploy:package=../../package.tar.gz,opts="--theme --activate" fab dist.deploy:package=../../*.deb fab dist.deploy:package=../../*.deb,opts='--force' """ # Use glob to find package from local filesystem (glob supports wildcards) pmatches = glob(os.path.expandvars(os.path.expanduser(package))) if not pmatches: return abort('No package can be found with name: %s' % package) # Iterate matched packages # Upload package(s) to remote host and determine the name of release folder for pmatch in pmatches: package = os.path.normpath(pmatch) # Get the release name from package: drop the extension and version packagename = os.path.basename(package) releasename, releaseversion, releaseextension = split_package_name( packagename) # Upload package to home directory, with same as the orig logger.info('Uploading the package: %s -> %s' % (package, packagename)) put(package, packagename) logger.info('Release name: %s' % releasename) # Run the package specific deployment actions if releaseextension == 'tar.gz': deploy_targz(packagename, opts) elif releaseextension == 'egg': opts = opts or '-Z' sudo('easy_install %s %s' % (opts, packagename)) elif releaseextension == 'deb': opts = opts or '--install' sudo('dpkg %s %s' % (opts, packagename)) elif releaseextension == 'rpm': opts = opts or '-Uvh' sudo('rpm %s %s' % (opts, packagename)) # Remove the package with cd('~'): sudo('rm -f ./%s' % packagename) # Restart apache logger.info('Restarting apache') apache = Apache() apache.restart()
def deploy(package, opts=''): """ Uploads the given package to remote host and deploys it there. :param str package: Path to tar.gz package in local file system. In case of wildcard, all the matched package are deployed. Package can be in formats: tar.gz (custom package structure, deb, rpm :param str opts: Optional parameters to pass to deploying app (easy_install, rpm, dpkg, deploy.sh) Examples:: fab dist.deploy:package=../../package.tar.gz fab dist.deploy:package=../../package.tar.gz,opts="--theme --activate" fab dist.deploy:package=../../*.deb fab dist.deploy:package=../../*.deb,opts='--force' """ # Use glob to find package from local filesystem (glob supports wildcards) pmatches = glob(os.path.expandvars(os.path.expanduser(package))) if not pmatches: return abort('No package can be found with name: %s' % package) # Iterate matched packages # Upload package(s) to remote host and determine the name of release folder for pmatch in pmatches: package = os.path.normpath(pmatch) # Get the release name from package: drop the extension and version packagename = os.path.basename(package) releasename, releaseversion, releaseextension = split_package_name(packagename) # Upload package to home directory, with same as the orig logger.info('Uploading the package: %s -> %s' % (package, packagename)) put(package, packagename) logger.info('Release name: %s' % releasename) # Run the package specific deployment actions if releaseextension == 'tar.gz': deploy_targz(packagename, opts) elif releaseextension == 'egg': opts = opts or '-Z' sudo('easy_install %s %s' % (opts, packagename)) elif releaseextension == 'deb': opts = opts or '--install' sudo('dpkg %s %s' % (opts, packagename)) elif releaseextension == 'rpm': opts = opts or '-Uvh' sudo('rpm %s %s' % (opts, packagename)) # Remove the package with cd('~'): sudo('rm -f ./%s' % packagename) # Restart apache logger.info('Restarting apache') apache = Apache() apache.restart()
def whoami(): """ Show whoami both with and without sudo Testing purpose. """ logger.info('Running whoami with sudo: %s' % sudo('whoami')) logger.info('Running whoami with user: %s' % run('whoami'))
def deploy_targz(packagename, opts): """ Run the deploy activities for source/custom tar.gz package. The script can deploy following kind of tar.gz packages: - Python source package: if setup.py is found from root folder, it is run with python setup.py install - Custom source package (created with build task): runs scripts/deploy.sh found from the package :param str packagename: Name of the package to deploy. Example 'mypackage-1.1.0.tar.gz' :param str opts: Optional parameters to pass to deploying app (easy_install, rpm, dpkg, deploy.sh) """ root_dir = config['trac_root'] webserver_user = config['webserver_user'] webserver_group = config['webserver_group'] releasename, releaseversion, releaseextension = split_package_name(packagename) # Get the subdirectory (where all the files are place) of the archive, if any out = run('tar ztf %s' % packagename) subdir = os.path.commonprefix(out.stdout.splitlines()) run('tar zxf %s' % packagename) with cd('~/%s' % subdir): # Run the setup.py if is found if exists('setup.py'): logger.info('Installing python module from source, using: %s/setup.py' % releasename) sudo('python setup.py install %s' % opts) # Custom package, expect to find scripts/deploy.sh else: logger.info('Running deploy script ./scripts/deploy.sh at directory: %s' % subdir) with settings(show('stdout')): sudo('./scripts/deploy.sh %s' % opts) # Fix file permissions logger.info('Setting the permissions to deployment folder') sudo('chown -L -R %s:%s %s' % (webserver_user, webserver_group, join(root_dir, 'dist', 'current'))) # Cleanup - needs to be done with sudo because of sudo is being used at running deploy.sh (at the moment) with cd('~'): logger.info('Cleaning up...') if subdir: sudo('rm -rf ./%s' % subdir) sudo('rm -rf ./%s' % releasename)
def install_requirements(): """ Installs software and services required by the software .. NOTE:: Requires interactions for setting MySQL and LDAP password """ sudo(""" apt-get -y update apt-get -y install apache2 apt-get -y install mysql-server apt-get -y install git apt-get -y install subversion apt-get -y install python-memcache apt-get -y install python-ldap apt-get -y install python-sqlalchemy apt-get -y install libapache2-mod-python apt-get -y install libapache2-svn apt-get -y install python-mysqldb apt-get -y install python-svn apt-get -y install python-subversion apt-get -y install mercurial apt-get -y install unzip apt-get -y install slapd apt-get -y install ldap-utils apt-get -y install migrationtools apt-get -y install yui-compressor apt-get -y install python-setuptools apt-get -y install subversion apt-get -y install python-nose """) # Install apache modules sudo(""" a2enmod dav a2enmod dav_fs a2enmod ssl""" )
def install_requirements(): """ Installs software and services required by the software .. NOTE:: Requires interactions for setting MySQL and LDAP password """ sudo(""" apt-get -y update apt-get -y install apache2 apt-get -y install mysql-server apt-get -y install git apt-get -y install subversion apt-get -y install python-memcache apt-get -y install python-ldap apt-get -y install python-sqlalchemy apt-get -y install libapache2-mod-python apt-get -y install libapache2-svn apt-get -y install python-mysqldb apt-get -y install python-svn apt-get -y install python-subversion apt-get -y install mercurial apt-get -y install unzip apt-get -y install slapd apt-get -y install ldap-utils apt-get -y install migrationtools apt-get -y install yui-compressor apt-get -y install python-setuptools apt-get -y install subversion apt-get -y install python-nose """) # Install apache modules sudo(""" a2enmod dav a2enmod dav_fs a2enmod ssl""")
def create_repository(pname=None, rname=None, rtype=None): """ Creates version control repository :param str pname: Name of project where to create repository :param str rname: Name of repository you want to create :param str rtype: Type of the repository you want to create. Valid types are: git, ... Example usage:: fab system.create_repository:myproject,reponame,git """ assert rtype, 'Please provide repository type. Example: git' assert pname, 'Please provide project name. Example: myproject' assert rname, 'Please provide repository name. Example: reponame' root_dir = config['trac_repositories_path'] repo_dir = os.path.join(root_dir, '%s.%s' % (pname, rname)) webserver_user = config['webserver_user'] webserver_group = config['webserver_group'] # Dictionary for easy-replace variables = { 'rname':rname, 'pname':pname, 'rdir':repo_dir, 'rtype':rtype, } if rtype == 'git': q = 'Creating a %(rtype)s repo "%(rname)s" in %(rdir)s. Is this right (y/n)?' % variables if not str(prompt(q, default='n')).lower() == 'y': logger.info('Aborting.') return logger.info('Creating git repository') sudo('git --bare --git-dir=%(rdir)s init --shared=true' % variables) sudo('git --git-dir=%(rdir)s update-server-info' % variables) sudo('chown -R %s:%s %s' % (webserver_user, webserver_group, repo_dir)) logger.warn('Manual step required. Add following in projects trac.ini') print '[repositories]' print '%(rname)s.dir = %(rdir)s' % variables print '%(rname)s.type = %(rtype)s' % variables print '' else: raise NotImplementedError('Repository type not implemented')
def create_repository(pname=None, rname=None, rtype=None): """ Creates version control repository :param str pname: Name of project where to create repository :param str rname: Name of repository you want to create :param str rtype: Type of the repository you want to create. Valid types are: git, ... Example usage:: fab system.create_repository:myproject,reponame,git """ assert rtype, 'Please provide repository type. Example: git' assert pname, 'Please provide project name. Example: myproject' assert rname, 'Please provide repository name. Example: reponame' root_dir = config['trac_repositories_path'] repo_dir = os.path.join(root_dir, '%s.%s' % (pname, rname)) webserver_user = config['webserver_user'] webserver_group = config['webserver_group'] # Dictionary for easy-replace variables = { 'rname': rname, 'pname': pname, 'rdir': repo_dir, 'rtype': rtype, } if rtype == 'git': q = 'Creating a %(rtype)s repo "%(rname)s" in %(rdir)s. Is this right (y/n)?' % variables if not str(prompt(q, default='n')).lower() == 'y': logger.info('Aborting.') return logger.info('Creating git repository') sudo('git --bare --git-dir=%(rdir)s init --shared=true' % variables) sudo('git --git-dir=%(rdir)s update-server-info' % variables) sudo('chown -R %s:%s %s' % (webserver_user, webserver_group, repo_dir)) logger.warn('Manual step required. Add following in projects trac.ini') print '[repositories]' print '%(rname)s.dir = %(rdir)s' % variables print '%(rname)s.type = %(rtype)s' % variables print '' else: raise NotImplementedError('Repository type not implemented')
def create_users(): """ Creates system users and groups, required by service """ sudo('addgroup devel')