def install_nginx(): """ Install Nginx web-server """ check_sudo() check_os() if not confirm('Do you want to install nginx?'): return print_green('INFO: Install nginx...') set_apt_repositories(NGINX_REPOSITORIES, NGINX_REPOS_INSTALL_KEYS_COMMANDS, subconf_name='nginx') apt_update() apt_install('nginx', noconfirm=True) user = prompt('Set user to nginx', default='www-data', validate='[\w\-]+') workers = prompt('Set worker_processes', default='1', validate='\d+') cmbs = prompt('Set client_max_body_size (MB)', default='32', validate='\d+') gzl = prompt('Set gzip_comp_level (set 0 to disable gzip)', default='1', validate='\d+') cfn = '/etc/nginx/nginx.conf' sed(cfn, r'user\s+nginx;', r'user {};'.format(user), use_sudo=True) sed(cfn, r'worker_processes\s+[0-9]+;', r'worker_processes {};'.format(workers), use_sudo=True, backup='') sed(cfn, r'http \{', (r'http \{\n\n' r' server_names_hash_bucket_size 64;\n' r' client_max_body_size {cmbs}m;\n\n').replace('{cmbs}', cmbs), use_sudo=True, backup='') if gzl != '0': sed(cfn, r'\s+#\s*gzip on;', (r' gzip on;\n' r' gzip_proxied any;\n' r' gzip_comp_level {gzl};\n' r' gzip_min_length 1000;\n' r' gzip_proxied expired no-cache no-store private auth;\n' r' gzip_types text/plain text/javascript text/xml text/css application/x-javascript ' r'application/javascript application/xml application/json image/svg+xml;\n' r' gzip_disable "msie6";\n' r' gzip_vary on;\n').format(gzl=gzl), use_sudo=True, backup='') print_green('INFO: Install nginx... OK')
def install_postgis(postgres_ver=None, postgis_ver=None): """ Install PostGIS for PostgreSQL """ assert postgres_ver in SUPPORT_POSTGRESQL_VERSIONS or postgres_ver is None assert postgis_ver in ('2.3', '2.4') or postgis_ver is None if postgres_ver and postgis_ver and postgis_ver not in SUPPORT_POSTGIS_VERSIONS[postgres_ver]: AssertionError('Invalid postgis_ver {} for postgres_ver {}'.format(postgres_ver, postgis_ver)) check_sudo() os_name, os_ver = check_os() if not confirm('Do you want to install GEOS, GDAL, PROJ.4 and PostGIS?'): return allow_versions = ', '.join(SUPPORT_POSTGRESQL_VERSIONS) while postgres_ver not in SUPPORT_POSTGRESQL_VERSIONS: postgres_ver = prompt('Write PostgreSQL version you have ({}):'.format(allow_versions), default=SUPPORT_POSTGRESQL_VERSIONS[-1]) allow_versions = ', '.join(SUPPORT_POSTGIS_VERSIONS[postgres_ver]) while postgis_ver not in SUPPORT_POSTGIS_VERSIONS[postgres_ver]: postgis_ver = prompt('Write PostGIS version you need ({}):'.format(allow_versions), default=SUPPORT_POSTGIS_VERSIONS[postgres_ver][-1]) print_green('INFO: Install GEOS, GDAL, PROJ.4 and PostGIS {} for PostgreSQL {}...'.format(postgis_ver, postgres_ver)) packages = ['libgeos-dev libgeos++-dev gdal-bin python-gdal libproj-dev'] if os_name == 'Debian' and os_ver == '8': packages.extend(['libgeos-c1 libgeos-3.4.2 libgdal-dev libgdal1-dev libproj0']) if os_name == 'Debian' and os_ver == '9': packages.extend(['libgeos-c1v5 libgeos-3.5.1 libgdal-dev libproj12']) apt_install(' '.join(packages), noconfirm=True) apt_install('postgresql-{}-postgis-{}'.format(postgres_ver, postgis_ver), noconfirm=True) apt_install('libgeoip1 spatialite-bin', noconfirm=True) print_green('INFO: Install GEOS, GDAL, PROJ.4 and PostGIS {} for PostgreSQL {}... OK'.format(postgis_ver, postgres_ver))
def configure_virtualenvwrapper_for_user(username, python_ver='2'): """ Configure virtualenvwrapper for user """ assert python_ver in ('2', '3') python_ver = int(python_ver) check_sudo() check_os() if not confirm('Do you want to configure python {} virtualenvwrapper to user "{}"?'.format(python_ver, username)): return if not exists('/usr/local/bin/virtualenvwrapper.sh', use_sudo=True): abort('virtualenvwrapper is not installed.') print_green('INFO: Configure virtualenvwrapper to user {}...'.format(username)) user_dir = '/home/{}'.format(username) if not exists(user_dir, use_sudo=True): print_red("Directory {} doesn't exists :(".format(user_dir)) if not confirm('Do you want to ignore this error and continue? (else will be abort)', default=False): abort("Directory {} doesn't exists :(".format(user_dir)) else: bashrc = '{}/.bashrc'.format(user_dir) python_path = '/usr/bin/python2.7' if python_ver == 3: python_path = '/usr/bin/python{}'.format(get_python3_version()) append(bashrc, 'export WORKON_HOME=$HOME/.virtualenvs', use_sudo=True) append(bashrc, 'export VIRTUALENVWRAPPER_HOOK_DIR=$WORKON_HOME', use_sudo=True) append(bashrc, 'export VIRTUALENVWRAPPER_PYTHON={}'.format(python_path), use_sudo=True) append(bashrc, 'source /usr/local/bin/virtualenvwrapper.sh', use_sudo=True) print_green('INFO: Configure python {} virtualenvwrapper to user {}... OK'.format(python_ver, username))
def check_os(): """ Check OS supported by fabdeb """ if '_fd_checked_os_' in env: return env._fd_checked_os_ print_green('INFO: Check your OS...') remote_os_issue = sudo('cat /etc/issue', quiet=True) if remote_os_issue.failed: remote_os_issue = '' remote_os_issue = remote_os_issue.replace('\\n', '').replace('\\l', '').strip() remote_os_name = allow_versions = ok = None if remote_os_issue: for os_issue, versions, os_name in SUPPORT_OS: if os_issue in remote_os_issue: remote_os_name = os_name allow_versions = versions ok = True break if not ok: abort('Your OS "{}" is not supported :('.format(remote_os_issue)) remote_os_ver = sudo('cat /etc/debian_version', quiet=True) if remote_os_ver.failed: remote_os_ver = '' remote_os_ver = remote_os_ver.split('.', 1)[0].strip() if remote_os_ver not in allow_versions: abort('Your OS "{}" version "{}" is not supported :('.format( remote_os_issue, remote_os_ver)) print_green('INFO: Check your OS... OK') env._fd_checked_os_ = remote_os_name, remote_os_ver return env._fd_checked_os_
def add_user_to_proftpd(username): """ Setup proftpd for user (user's home directory will be available via ftp) """ check_sudo() check_os() if not confirm('Do you want to setup proftpd for user "{}"?'.format(username)): return if not exists('/usr/sbin/proftpd'): abort('proftpd is not installed') print_green('INFO: Add user "{}" to proftpd...'.format(username)) if not user_exists(username): abort('User {} does not exists'.format(username)) t = sudo('id {}'.format(username)) uid, gid = re.search(r'uid=(\d+)\(.+gid=(\d+)\(', t).groups() passwd_fn = '/etc/proftpd/ftpd.passwd' sudo('ftpasswd --passwd --file={passwd} --name={user} --shell=/bin/false ' '--home=/home/{user} --uid={uid} --gid={gid}'.format(passwd=passwd_fn, user=username, uid=uid, gid=gid)) ftpaccess = ('<Limit READ WRITE DIRS>\n' ' Order deny,allow\n' ' Allowuser {user}\n' '</Limit>\n').format(user=username).encode() put(BytesIO(ftpaccess), '/home/{}/.ftpaccess'.format(username), use_sudo=True) if confirm('Do you want to restart proftpd?'): service_restart('proftpd') print_green('INFO: Add user "{}" to proftpd... OK'.format(username))
def install_supervisor_latest(): """ Install supervisor daemon from python repository. """ check_sudo() check_os() if not confirm('Do you want to install supervisor?'): return print_green('INFO: Install supervisor...') sudo('pip2.7 install -U supervisor') if not exists('/etc/supervisor', use_sudo=True): sudo('mkdir /etc/supervisor') if not exists('/etc/supervisor/conf.d', use_sudo=True): sudo('mkdir /etc/supervisor/conf.d') if not exists('/var/log/supervisor', use_sudo=True): sudo('mkdir /var/log/supervisor') put(os.path.join(os.path.dirname(__file__), 'confs', 'supervisord.conf'), '/etc/supervisor/supervisord.conf', use_sudo=True) put(os.path.join(os.path.dirname(__file__), 'scripts', 'supervisor'), '/etc/init.d/supervisor', use_sudo=True) sudo('chmod 775 /etc/init.d/supervisor') sudo('update-rc.d supervisor defaults') sudo('service supervisor start') print_green('INFO: Install supervisor... OK')
def configure_timezone(): """ Configure timezone """ check_sudo() check_os() print_green('INFO: Configure timezone...') current_tz = sudo('cat /etc/timezone', quiet=True).strip() def validate_tz(tz): tz = tz.strip() fn = '/usr/share/zoneinfo/{}'.format(tz) if ('.' not in tz and exists(fn, use_sudo=True) and sudo('head -c 4 {}'.format(fn), quiet=True) == 'TZif'): return tz raise ValueError( 'Invalid timezone. See http://twiki.org/cgi-bin/xtra/tzdatepick.html' ) new_timezone = prompt('Set timezone', default=current_tz, validate=validate_tz) if current_tz != new_timezone: sudo('timedatectl set-timezone {}'.format(new_timezone)) print_green('INFO: Configure timezone... OK')
def install_proftpd(): """ Install proftpd server """ check_sudo() check_os() if not confirm('Do you want to install proftpd?'): return print_green('INFO: Install proftpd...') apt_install('proftpd', noconfirm=True) conf_fn = '/etc/proftpd/proftpd.conf' sudo('cp {fn} {fn}.bak'.format(fn=conf_fn), warn_only=True) sed(conf_fn, r'UseIPv6\s+on', r'UseIPv6\t\t\t\toff\nUseReverseDNS\t\t\toff', use_sudo=True, backup='') sn = prompt('Set ftp server name', default='MyFTPServer', validate=r'[\w\- ]+') sed(conf_fn, r'ServerName\s+".+"', r'ServerName\t\t\t"{}"'.format(sn), use_sudo=True, backup='') sed(conf_fn, r'TimeoutNoTransfer.+', r'TimeoutNoTransfer\t\t3600', use_sudo=True, backup='') sed(conf_fn, r'TimeoutStalled.+', r'TimeoutStalled\t\t\t3600', use_sudo=True, backup='') sed(conf_fn, r'TimeoutIdle.+', r'TimeoutIdle\t\t\t7200', use_sudo=True, backup='') uncomment(conf_fn, r'#\s*DefaultRoot', use_sudo=True, backup='') uncomment(conf_fn, r'#\s*RequireValidShell', use_sudo=True, backup='') # todo uncomment only first value instead all uncomment(conf_fn, r'#\s*PassivePorts', use_sudo=True, backup='') t = (r'<Global>\n' r' RootLogin off\n' r'</Global>\n' r'AuthUserFile /etc/proftpd/ftpd.passwd\n' r'<Directory ~/>\n' r' HideFiles "(\\\\.ftpaccess)$"\n' r'</Directory>\n') sed(conf_fn, r'(# Include other custom configuration files)', r'{}\n\1'.format(t), use_sudo=True, backup='') print_green('INFO: Install proftpd... OK')
def configure_hostname(): """ Configure hostname, host ip, /etc/hosts """ check_sudo() check_os() print_green('INFO: Configure hostname...') chn = sudo('cat /etc/hostname').strip() nhn = prompt('Set hostname', default=chn, validate=r'[\w\.\-]+') ip = prompt( 'Set host ip', default=socket.gethostbyname(env.host), validate= r'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$' ) sudo('echo "{}" > /etc/hostname'.format(nhn)) comment('/etc/hosts', r'127.0.0.1', use_sudo=True) comment('/etc/hosts', r'127.0.1.1', use_sudo=True, backup='') append('/etc/hosts', '\n127.0.0.1\tlocalhost', use_sudo=True) append('/etc/hosts', '127.0.1.1\t{}'.format(nhn.split('.')[0]), use_sudo=True) append('/etc/hosts', '{}\t{}'.format(ip, nhn), use_sudo=True) sudo('hostname -F /etc/hostname') print_green('INFO: Configure hostname... OK')
def apt_update(): """ aptitude update """ check_sudo() check_os() print_green('INFO: Apt update...') sudo('aptitude update -q') print_green('INFO: Apt update... OK')
def apt_dist_upgrade(): """ aptitude dist-upgrade """ check_sudo() check_os() print_green('INFO: APT dist upgrade...') opts = '-q -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold"' sudo('aptitude dist-upgrade {}'.format(opts)) print_green('INFO: APT dist upgrade... OK')
def install_supervisor(): """ Install supervisor daemon """ check_sudo() check_os() if not confirm('Do you want to install supervisor?'): return print_green('INFO: Install supervisor...') apt_install('supervisor', noconfirm=True) print_green('INFO: Install supervisor... OK')
def apt_cleanup(): """ aptitude autoclean and clean """ check_sudo() check_os() if not confirm('Do you want to apt clean up?'): return print_green('INFO: Apt clean up...') sudo('aptitude autoclean -q -y') sudo('aptitude clean -q -y') print_green('INFO: Apt clean up... OK')
def install_python_venv(python_ver='2'): """ Install virtualenv & virtualenvwrapper for python """ assert python_ver in ('2', '3') python_ver = int(python_ver) check_sudo() check_os() print_green('INFO: Install python {} virtualenv & virtualenvwrapper...'.format(python_ver)) sudo('pip{} install -q virtualenv'.format(python_ver)) sudo('pip{} install -q virtualenvwrapper'.format(python_ver)) print_green('INFO: Install python {} virtualenv & virtualenvwrapper... OK'.format(python_ver))
def add_db_to_postgresql(dbname, owner=None): """ Create new PostgreSQL database """ check_sudo() check_os() print_green('INFO: Adding DB "{}" to PostreSQL...'.format(dbname)) with settings(sudo_user='******'): if owner: sudo('createdb -O {} {}'.format(owner, dbname)) else: sudo('createdb {}'.format(dbname)) print_green('INFO: Adding DB "{}" to PostreSQL... OK'.format(dbname))
def add_user_to_postgresql(username, return_pwd=False): """ Add new PostgreSQL user """ check_sudo() check_os() print_green('INFO: Adding user "{}" to PostreSQL...'.format(username)) pwd = password_prompt('Set password to new postgresql user "{}"'.format(username)) with settings(sudo_user='******'): sudo('createuser {}'.format(username)) set_postgresql_user_password(username, pwd) print_green('INFO: Adding user "{}" to PostreSQL... OK'.format(username)) return pwd if return_pwd else None
def install_postgresql(ver=None): """ Install PostgreSQL server """ # simple settings helper http://pgtune.leopard.in.ua/ assert ver in SUPPORT_POSTGRESQL_VERSIONS or ver is None check_sudo() check_os() if not confirm('Do you want to install PostreSQL{}?'.format( ' {}'.format(ver) if ver else '')): return allow_versions = ', '.join(SUPPORT_POSTGRESQL_VERSIONS) while ver not in SUPPORT_POSTGRESQL_VERSIONS: ver = prompt( 'Write PostgreSQL version you need ({}):'.format(allow_versions), default=SUPPORT_POSTGRESQL_VERSIONS[-1]) print_green('INFO: Install PostreSQL {}...'.format(ver)) set_apt_repositories(POSTGRESQL_REPOSITORIES, POSTGRESQL_REPOS_INSTALL_KEYS_COMMANDS, subconf_name='postgres') apt_update() apt_install( 'postgresql-{ver} postgresql-server-dev-{ver} libpq-dev'.format( ver=ver), noconfirm=True) set_postgresql_user_password( 'postgres', password_prompt('Set password to superuser postgres')) la = prompt( 'Set listen_addresses (hostname or ip, comma separated; set * for all)', default='localhost', validate='[\w\.\-\*]+').strip() t = BytesIO() postgresql_conf = '/etc/postgresql/{}/main/postgresql.conf'.format(ver) get(postgresql_conf, local_path=t, use_sudo=True) t = BytesIO( re.sub(br"#listen_addresses = 'localhost'", r"listen_addresses = '{}'".format(la).encode(), t.getvalue())) put(t, postgresql_conf, use_sudo=True) sudo('chown postgres:postgres {}'.format(postgresql_conf)) sudo('chmod 644 {}'.format(postgresql_conf)) hba = '/etc/postgresql/{}/main/pg_hba.conf'.format(ver) sed(hba, r'(local\s+all\s+all\s+)peer', r'\1md5', use_sudo=True) if confirm('Do you want to allow connect to PostgreSQL from out?'): append( hba, 'host all all 0.0.0.0/0 md5', use_sudo=True) install_postgis(postgres_ver=ver) if confirm('Do you want to restart PostgreSQL?'): service_restart('postgresql') print_green('INFO: Install PostreSQL {}... OK'.format(ver))
def add_user_to_postgresql(username, return_pwd=False): """ Add new PostgreSQL user """ check_sudo() check_os() print_green('INFO: Adding user "{}" to PostreSQL...'.format(username)) pwd = password_prompt( 'Set password to new postgresql user "{}"'.format(username)) with settings(sudo_user='******'): sudo('createuser {}'.format(username)) set_postgresql_user_password(username, pwd) print_green('INFO: Adding user "{}" to PostreSQL... OK'.format(username)) return pwd if return_pwd else None
def install_python_venv(python_ver='2'): """ Install virtualenv & virtualenvwrapper for python """ assert python_ver in ('2', '3') python_ver = int(python_ver) check_sudo() check_os() print_green( 'INFO: Install python {} virtualenv & virtualenvwrapper...'.format( python_ver)) sudo('pip{} install -q virtualenv'.format(python_ver)) sudo('pip{} install -q virtualenvwrapper'.format(python_ver)) print_green( 'INFO: Install python {} virtualenv & virtualenvwrapper... OK'.format( python_ver))
def apt_install(pkgs, comment=None, noconfirm=False): """ aptitude install ... """ check_sudo() check_os() assert isinstance(pkgs, str) pkgs = ' '.join(pkgs.split()) comment = ' {}'.format(comment) if comment else '' if not noconfirm and not confirm('Do you want to apt install {}?{}'.format( pkgs, comment)): return print_green('INFO: Apt install {}...'.format(pkgs)) opts = '-q -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold"' sudo('aptitude install {} {}'.format(opts, pkgs)) print_green('INFO: Apt install {}... OK'.format(pkgs))
def check_sudo(): """ Check available sudo command """ if '_fd_checked_sudo_' in env: return print_green('INFO: Check sudo...') t = sudo('whoami', quiet=True) if t.failed: print_red('NOTE: For using this fabfile you need to install sudo:\n' ' # aptitude install sudo\n' 'and add your non-root user to group sudo:\n' ' # adduser YourNonRootUserName sudo') abort(t) print_green('INFO: Check sudo... OK') env._fd_checked_sudo_ = True
def create_postgres_extensions_in_db(dbname, extensions): """ Create PostGIS extension in PostgreSQL database """ check_sudo() check_os() if isinstance(extensions, str): extensions = (extensions,) if not extensions: return for extension in extensions: if extension not in ('postgis', 'hstore'): raise AssertionError print_green('INFO: Create PostgreSQL extensions in DB "{}": {}...'.format(dbname, ', '.join(extensions))) for extension in extensions: sudo('sudo -u postgres psql -d {} -c "CREATE EXTENSION IF NOT EXISTS {};"'.format(dbname, extension)) print_green('INFO: Create PostgreSQL extensions in DB "{}": {}... OK'.format(dbname, ', '.join(extensions)))
def install_nodejs(ver=None): """ Install nodejs """ assert ver in SUPPORT_NODEJS_VERSIONS or ver is None check_sudo() check_os() if not confirm('Do you want to install Node.js{}?'.format(' {}'.format(ver) if ver else '')): return allow_versions = ', '.join(SUPPORT_NODEJS_VERSIONS) while ver not in SUPPORT_NODEJS_VERSIONS: ver = prompt('Write Node.js version you need ({}):'.format(allow_versions), default=SUPPORT_NODEJS_VERSIONS[0]) print_green('INFO: Install Node.js {}...'.format(ver)) sudo('wget -q -O - https://deb.nodesource.com/setup_{v}.x | bash -'.format(v=ver)) apt_install('nodejs', noconfirm=True) print_green('INFO: Install Node.js {}... OK'.format(ver))
def install_redis(): """ Install Redis-server """ def _clean(): with cd('/tmp'): sudo('rm -rf redis-stable', warn_only=True) check_sudo() check_os() if not confirm('Do you want to install Redis?'): return print_green('INFO: Install Redis...') with cd('/tmp'): sudo('wget -q http://download.redis.io/redis-stable.tar.gz') sudo('tar xzf redis-stable.tar.gz') sudo('rm redis-stable.tar.gz') with cd('/tmp/redis-stable'): sudo('make') if confirm('Do you want run tests?'): sudo('make test', warn_only=True) if not confirm('Do you want continue install Redis?'): _clean() print_yellow('INFO: Install Redis... CANCELLED') return sudo('make install') conf_fn = None while True: out = sudo('utils/install_server.sh', warn_only=True) if out.failed: if confirm('Do you want to repeat run install_server.sh?'): continue else: conf_fn = re.search(r'Config file\s+:\s(.+?)\n', out).group(1).strip() break if conf_fn: bind = prompt('Set bind IP address (or addresses separated by space)', default='127.0.0.1', validate=bind_validate) dbs = prompt('Set dadabases count', default='20', validate='\d+') sed(conf_fn, r'(# bind 127.0.0.1)', r'\1\nbind {}'.format(bind), use_sudo=True) sed(conf_fn, r'(databases [0-9]+)', r'# \1\ndatabases {}'.format(dbs), use_sudo=True) _clean() if confirm('Do you want to set parameter vm.overcommit_memory=1 to /etc/sysctl.conf? (Recommended)'): append('/etc/sysctl.conf', 'vm.overcommit_memory=1', use_sudo=True) print_green('INFO: Install Redis... OK')
def install_ntp(): """ Install ntp daemon """ check_sudo() check_os() if not confirm('Do you want install NTP client?'): return print_green('INFO: Install ntp...') apt_install('ntp ntpdate', noconfirm=True) print_red( "Go to http://www.pool.ntp.org/ and select servers in your server's country.\n" "For example (Ukraine):\n" " 0.ua.pool.ntp.org\n" " 1.ua.pool.ntp.org\n" " 2.ua.pool.ntp.org\n" " 3.ua.pool.ntp.org") def read_ntp_servers(): ntp_server_list = [] while True: t = prompt('Set NTP-server host. (Set empty string to continue)', default='').strip() if not t: break ntp_server_list.append(t) return ntp_server_list while True: ntp_servers = read_ntp_servers() print_yellow('You wrote following NTP-server list:\n {}'.format( '\n '.join(ntp_servers or ('-empty-', )))) if confirm('Are you confirm this NTP-server list?'): break if ntp_servers: ntp_conf_fn = '/etc/ntp.conf' comment(ntp_conf_fn, r'^server\s', use_sudo=True) for ntp_server in ntp_servers: append(ntp_conf_fn, 'server {} iburst'.format(ntp_server), use_sudo=True) print_green('INFO: Install ntp... OK')
def set_apt_repositories(repos, repos_install_keys_commands, subconf_name=None): check_sudo() check_os() print_green('INFO: Set apt repositories...') repositories_f = BytesIO(get_apt_repositories_text(repos).encode()) if subconf_name: put(repositories_f, '/etc/apt/sources.list.d/{}.list'.format(subconf_name.strip()), mode=0o644, use_sudo=True) else: sudo('mv /etc/apt/sources.list /etc/apt/sources.list.bak', warn_only=True) put(repositories_f, '/etc/apt/sources.list', mode=0o644, use_sudo=True) for command in get_apt_repo_install_keys_commands( repos_install_keys_commands): sudo(command) print_green('INFO: Set apt repositories... OK')
def install_pngquant_jpegtran(): """ Install pngquant and jpegtran -- console utility for compress PNG- and JPEG-images """ check_sudo() check_os() if not confirm('Do you want to install pngquant and jpegtran?'): return print_green('INFO: Install pngquant and jpegtran...') apt_install('libpng-dev liblcms2-dev libjpeg-progs', noconfirm=True) with cd('/tmp'): sudo('git clone --recursive https://github.com/pornel/pngquant.git') with cd('/tmp/pngquant'): sudo('./configure --with-lcms2 && make') sudo('make install') if confirm('Do you want make symlink /usr/local/bin/pngquant to /bin/pngquant?'): sudo('ln -sf /usr/local/bin/pngquant /bin/pngquant') with cd('/tmp'): sudo('rm -rf pngquant') print_green('INFO: Install pngquant and jpegtran... OK')
def configure_virtualenvwrapper_for_user(username, python_ver='2'): """ Configure virtualenvwrapper for user """ assert python_ver in ('2', '3') python_ver = int(python_ver) check_sudo() check_os() if not confirm( 'Do you want to configure python {} virtualenvwrapper to user "{}"?' .format(python_ver, username)): return if not exists('/usr/local/bin/virtualenvwrapper.sh', use_sudo=True): abort('virtualenvwrapper is not installed.') print_green( 'INFO: Configure virtualenvwrapper to user {}...'.format(username)) user_dir = '/home/{}'.format(username) if not exists(user_dir, use_sudo=True): print_red("Directory {} doesn't exists :(".format(user_dir)) if not confirm( 'Do you want to ignore this error and continue? (else will be abort)', default=False): abort("Directory {} doesn't exists :(".format(user_dir)) else: bashrc = '{}/.bashrc'.format(user_dir) python_path = '/usr/bin/python2.7' if python_ver == 3: python_path = '/usr/bin/python{}'.format(get_python3_version()) append(bashrc, 'export WORKON_HOME=$HOME/.virtualenvs', use_sudo=True) append(bashrc, 'export VIRTUALENVWRAPPER_HOOK_DIR=$WORKON_HOME', use_sudo=True) append(bashrc, 'export VIRTUALENVWRAPPER_PYTHON={}'.format(python_path), use_sudo=True) append(bashrc, 'source /usr/local/bin/virtualenvwrapper.sh', use_sudo=True) print_green( 'INFO: Configure python {} virtualenvwrapper to user {}... OK'.format( python_ver, username))
def install_python_pkgs_managers(python_ver='2'): """ Install setuptools & pip for python """ assert python_ver in ('2', '3') python_ver = int(python_ver) check_sudo() check_os() print_green('INFO: Install python {} setuptools & pip...'.format(python_ver)) with cd('/tmp'): # there is problem. maybe aptitude install python-setuptools is better way if python_ver == 3: sudo('wget -q https://bootstrap.pypa.io/ez_setup.py -O - | python3') else: sudo('wget -q https://bootstrap.pypa.io/ez_setup.py -O - | python') sudo('rm setuptools-*.zip') if python_ver == 3: sudo('easy_install-{} -q pip'.format(get_python3_version())) else: sudo('easy_install -q pip') print_green('INFO: Install python {} setuptools & pip... OK'.format(python_ver))
def install_postgis(postgres_ver=None, postgis_ver=None): """ Install PostGIS for PostgreSQL """ assert postgres_ver in SUPPORT_POSTGRESQL_VERSIONS or postgres_ver is None assert postgis_ver in ('2.3', '2.4') or postgis_ver is None if postgres_ver and postgis_ver and postgis_ver not in SUPPORT_POSTGIS_VERSIONS[ postgres_ver]: AssertionError('Invalid postgis_ver {} for postgres_ver {}'.format( postgres_ver, postgis_ver)) check_sudo() os_name, os_ver = check_os() if not confirm('Do you want to install GEOS, GDAL, PROJ.4 and PostGIS?'): return allow_versions = ', '.join(SUPPORT_POSTGRESQL_VERSIONS) while postgres_ver not in SUPPORT_POSTGRESQL_VERSIONS: postgres_ver = prompt( 'Write PostgreSQL version you have ({}):'.format(allow_versions), default=SUPPORT_POSTGRESQL_VERSIONS[-1]) allow_versions = ', '.join(SUPPORT_POSTGIS_VERSIONS[postgres_ver]) while postgis_ver not in SUPPORT_POSTGIS_VERSIONS[postgres_ver]: postgis_ver = prompt( 'Write PostGIS version you need ({}):'.format(allow_versions), default=SUPPORT_POSTGIS_VERSIONS[postgres_ver][-1]) print_green( 'INFO: Install GEOS, GDAL, PROJ.4 and PostGIS {} for PostgreSQL {}...'. format(postgis_ver, postgres_ver)) packages = ['libgeos-dev libgeos++-dev gdal-bin python-gdal libproj-dev'] if os_name == 'Debian' and os_ver == '8': packages.extend( ['libgeos-c1 libgeos-3.4.2 libgdal-dev libgdal1-dev libproj0']) if os_name == 'Debian' and os_ver == '9': packages.extend(['libgeos-c1v5 libgeos-3.5.1 libgdal-dev libproj12']) apt_install(' '.join(packages), noconfirm=True) apt_install('postgresql-{}-postgis-{}'.format(postgres_ver, postgis_ver), noconfirm=True) apt_install('libgeoip1 spatialite-bin', noconfirm=True) print_green( 'INFO: Install GEOS, GDAL, PROJ.4 and PostGIS {} for PostgreSQL {}... OK' .format(postgis_ver, postgres_ver))
def create_postgres_extensions_in_db(dbname, extensions): """ Create PostGIS extension in PostgreSQL database """ check_sudo() check_os() if isinstance(extensions, str): extensions = (extensions, ) if not extensions: return for extension in extensions: if extension not in ('postgis', 'hstore'): raise AssertionError print_green('INFO: Create PostgreSQL extensions in DB "{}": {}...'.format( dbname, ', '.join(extensions))) for extension in extensions: sudo( 'sudo -u postgres psql -d {} -c "CREATE EXTENSION IF NOT EXISTS {};"' .format(dbname, extension)) print_green( 'INFO: Create PostgreSQL extensions in DB "{}": {}... OK'.format( dbname, ', '.join(extensions)))
def add_user(username, py_ver='2', skip_confirm=False): """ Add new system user """ assert py_ver in ('2', '3') check_sudo() check_os() if user_exists(username): abort('User {} exists'.format(username)) if not skip_confirm: if not confirm('Do you want to create new user?'): return print_green('INFO: Add system user "{}"...'.format(username)) sudo('adduser {}'.format(username)) uncomment('/home/{}/.bashrc'.format(username), r'#\s*force_color_prompt=yes', use_sudo=True) from fabdeb.python import configure_virtualenvwrapper_for_user configure_virtualenvwrapper_for_user(username, python_ver=py_ver) from fabdeb.ftp import add_user_to_proftpd add_user_to_proftpd(username) print_green('INFO: Add system user "{}"... OK'.format(username))
def install_postgresql(ver=None): """ Install PostgreSQL server """ # simple settings helper http://pgtune.leopard.in.ua/ assert ver in SUPPORT_POSTGRESQL_VERSIONS or ver is None check_sudo() check_os() if not confirm('Do you want to install PostreSQL{}?'.format(' {}'.format(ver) if ver else '')): return allow_versions = ', '.join(SUPPORT_POSTGRESQL_VERSIONS) while ver not in SUPPORT_POSTGRESQL_VERSIONS: ver = prompt('Write PostgreSQL version you need ({}):'.format(allow_versions), default=SUPPORT_POSTGRESQL_VERSIONS[-1]) print_green('INFO: Install PostreSQL {}...'.format(ver)) set_apt_repositories(POSTGRESQL_REPOSITORIES, POSTGRESQL_REPOS_INSTALL_KEYS_COMMANDS, subconf_name='postgres') apt_update() apt_install('postgresql-{ver} postgresql-server-dev-{ver} libpq-dev'.format(ver=ver), noconfirm=True) set_postgresql_user_password('postgres', password_prompt('Set password to superuser postgres')) la = prompt('Set listen_addresses (hostname or ip, comma separated; set * for all)', default='localhost', validate='[\w\.\-\*]+').strip() t = BytesIO() postgresql_conf = '/etc/postgresql/{}/main/postgresql.conf'.format(ver) get(postgresql_conf, local_path=t, use_sudo=True) t = BytesIO( re.sub(br"#listen_addresses = 'localhost'", r"listen_addresses = '{}'".format(la).encode(), t.getvalue()) ) put(t, postgresql_conf, use_sudo=True) sudo('chown postgres:postgres {}'.format(postgresql_conf)) sudo('chmod 644 {}'.format(postgresql_conf)) hba = '/etc/postgresql/{}/main/pg_hba.conf'.format(ver) sed(hba, r'(local\s+all\s+all\s+)peer', r'\1md5', use_sudo=True) if confirm('Do you want to allow connect to PostgreSQL from out?'): append(hba, 'host all all 0.0.0.0/0 md5', use_sudo=True) install_postgis(postgres_ver=ver) if confirm('Do you want to restart PostgreSQL?'): service_restart('postgresql') print_green('INFO: Install PostreSQL {}... OK'.format(ver))
def install_python_pkgs_managers(python_ver='2'): """ Install setuptools & pip for python """ assert python_ver in ('2', '3') python_ver = int(python_ver) check_sudo() check_os() print_green( 'INFO: Install python {} setuptools & pip...'.format(python_ver)) with cd('/tmp'): # there is problem. maybe aptitude install python-setuptools is better way if python_ver == 3: sudo( 'wget -q https://bootstrap.pypa.io/ez_setup.py -O - | python3') else: sudo('wget -q https://bootstrap.pypa.io/ez_setup.py -O - | python') sudo('rm setuptools-*.zip') if python_ver == 3: sudo('easy_install-{} -q pip'.format(get_python3_version())) else: sudo('easy_install -q pip') print_green( 'INFO: Install python {} setuptools & pip... OK'.format(python_ver))
def setup_swap(): """ Setup SWAP and configure swappiness """ check_sudo() check_os() print_green('INFO: Setup SWAP...') t = sudo('swapon -s', quiet=True) if not re.search(r'\s\d+\s', t): swap_size = int( prompt( "Server doesn't have SWAP. Set size in MB to create SWAP. Keep 0 to skip.", default='0', validate=r'\d+')) if swap_size: swap_fn = '/swapfile' sudo('fallocate -l {size}M {sfn}'.format(size=swap_size, sfn=swap_fn)) command_defrag = 'e4defrag {sfn}'.format(sfn=swap_fn) print_green( 'Defragmenting swap file: {}...'.format(command_defrag)) sudo(command_defrag, quiet=True) sudo( 'chown root:root {sfn} && chmod 600 {sfn}'.format(sfn=swap_fn)) sudo('mkswap {sfn}'.format(sfn=swap_fn)) sudo('swapon {sfn}'.format(sfn=swap_fn)) append('/etc/fstab', '{sfn} swap swap defaults 0 0'.format(sfn=swap_fn), use_sudo=True) swappiness_size = int( prompt("Set vm.swappiness parameter to /etc/sysctl.conf", default='10', validate=r'\d+')) append('/etc/sysctl.conf', 'vm.swappiness={}'.format(swappiness_size), use_sudo=True) sudo('sysctl -p') print_green('INFO: Setup SWAP... OK')
def install_exim4(): """ Install email-server exim4, configure DKIM and generate DKIM-keys """ check_sudo() check_os() if not confirm('Do you want install exim4?'): return print_green('INFO: Install exim4...') apt_install('exim4', noconfirm=True) dkim_keys_path = '/etc/exim4/dkim' print_red('You need run exim4 configure:\n' ' # dpkg-reconfigure exim4-config\n' 'and set options:\n' ' General type of mail configuration: internet site; ...using SMTP\n' ' System mail name: your-real-domain.com\n' ' IP-address to listen on for incoming SMTP connectins: 127.0.0.1; ::1\n' ' Other destinations for which mail is accepted: <allow empty>\n' ' Domains to relay mail for: <allow empty>\n' ' Machines to relay mail for: <allow empty>\n' ' Keep number of DNS-queries minimal: No\n' ' Delivery method for local mail: mbox format\n' ' Split configuration into small files: No\n' ' Root and postmaster mail recipient: <allow empty>\n') if confirm('Do you want install opendkim and setup dkim in exim4?'): apt_install('opendkim opendkim-tools', noconfirm=True) sudo('mkdir {}'.format(dkim_keys_path), warn_only=True) sudo('chown Debian-exim:Debian-exim {dkp} && chmod 700 {dkp}'.format(dkp=dkim_keys_path)) dkim_selector = prompt('Set DKIM selector name', default='mail', validate=r'[\w]+') sudo('cp /etc/exim4/exim4.conf.template /etc/exim4/exim4.conf.template.bak') t = BytesIO() get('/etc/exim4/exim4.conf.template', local_path=t, use_sudo=True) t = BytesIO(re.sub( br'(# This transport is used for delivering messages over SMTP connections\.\n).*?' br'(remote_smtp:.+?driver = smtp\n).+?(\.ifdef)', r'\1\n' r'DKIM_DOMAIN_NAME = ${{lc:${{domain:$h_from:}}}}\n' r'DKIM_FILE = {dkp}/${{lc:${{domain:$h_from:}}}}.key\n' r'DKIM_PRIV_KEY = ${{if exists{{DKIM_FILE}}{{DKIM_FILE}}{{0}}}}\n\n' r'\2\n' r' dkim_domain = DKIM_DOMAIN_NAME\n' r' dkim_selector = {dsn}\n' r' dkim_private_key = DKIM_PRIV_KEY\n\n' r'\3'.format(dkp=dkim_keys_path, dsn=dkim_selector).encode(), t.getvalue(), flags=(re.M | re.S) )) put(t, '/etc/exim4/exim4.conf.template', use_sudo=True) sudo('chown root:root {cfn} && chmod 644 {cfn}'.format(cfn='/etc/exim4/exim4.conf.template')) print_red('You need to have DKIM keys.\n' 'You can generate their:\n' ' # opendkim-genkey -D {dkp} -d your-real-domain.com -s {dsn}\n' ' # mv {dkp}/{dsn}.private {dkp}/your-real-domain.com.key\n' ' # mv {dkp}/{dsn}.txt {dkp}/your-real-domain.com.txt\n' ' # chown Debian-exim:Debian-exim {dkp}/*\n' ' # chmod 600 {dkp}/*\n' 'Set DNS record for your your-real-domain.com from {dkp}/your-real-domain.com.txt\n' 'And may set DNS ADSP record:\n' ' _adsp._domainkey IN TXT "dkim=all"\n' 'For test sending mail run:\n' ' # echo testmail | /usr/sbin/sendmail [email protected]\n' ''.format(dkp=dkim_keys_path, dsn=dkim_selector)) service_restart('exim4') print_green('INFO: Install exim4... OK')
def install_user_rsa_key(username): """ Install RSA/SSH key for user """ check_sudo() check_os() if not user_exists: abort('User {} noes not exist'.format(username)) if not confirm('Do you want set SSH key?'): return print_green('INFO: Set SSH key...') print_yellow( 'Setup SSH key methods:\n' '1: Generate new ~/.ssh/id_rsa key and manually add public key to remote servers.\n' '2: Copy exists SSH RSA key from local to ~/.ssh/id_rsa.\n' '3: Copy exists SSH RSA key from local to ~/.ssh/{keyname}.rsa and configure ~/.ssh/config.' ) n = prompt('Select method', default='1', validate='[1-3]') def file_exists_validator(fn): fn = fn.replace('\\', '/') if not os.path.exists(fn): raise ValueError('File {} does not exist.'.format(fn)) return fn with settings(sudo_user=username, user=username, group=username): sudo('mkdir ~/.ssh', warn_only=True) if n == '1': with settings(sudo_user=username, user=username, group=username): sudo('ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_rsa') sudo('chmod 600 ~/.ssh/id_rsa', warn_only=True) pub = sudo('cat ~/.ssh/id_rsa.pub', quiet=True) print_red( 'Add this public key to remote host:\n\n{}\n\n'.format(pub)) while not confirm('Did you do it?'): pass elif n == '2': local_key_fn = prompt( 'Set path to RSA key in local (in windows skip part "C:")', default='/home/yourusername/.ssh/id_rsa', validate=file_exists_validator) put(local_key_fn, '/home/{}/.ssh/id_rsa'.format(username), use_sudo=True, mode=0o600) sudo('chown {u}:{u} /home/{u}/.ssh/id_rsa'.format(u=username)) elif n == '3': local_key_fn = prompt( 'Set path to RSA key in local (in windows skip part "C:")', default='/home/yourusername/.ssh/id_rsa', validate=file_exists_validator) kn = prompt('Set key name which will be saved as ~/.ssh/{keyname}.rsa', default='key', validate='\w+') put(local_key_fn, '/home/{u}/.ssh/{kn}.rsa'.format(u=username, kn=kn), use_sudo=True, mode=0o600) sudo('chown {u}:{u} /home/{u}/.ssh/{kn}.rsa'.format(u=username, kn=kn)) h = p = u = None while True: h = prompt( 'Set hostname for which will be used ~/.ssh/{}.rsa key (without port!)' .format(kn), default='github.com', validate='.+') p = prompt( 'Set port for which will be used ~/.ssh/{}.rsa key e.g. "22" (not requirement)' .format(kn), default='', validate='|\d+') u = prompt( 'Set user for which will be used ~/.ssh/{}.rsa key e.g. "git" (not requirement)' .format(kn), validate='|\w+') print_yellow(('HostHame: {h}\n' 'Port: {p}\n' 'User: {u}').format(h=h, p=(p or '-NONE-'), u=(u or '-NONE-'))) if confirm('Are you confirm it?'): break cf = '~/.ssh/config' with settings(sudo_user=username, user=username, group=username): append(cf, '\nHost {}'.format(h), use_sudo=True) append(cf, '\tHostName {}'.format(h), use_sudo=True) append(cf, '\tIdentityFile ~/.ssh/{}.rsa'.format(kn), use_sudo=True) if p: append(cf, '\tPort {}'.format(p), use_sudo=True) if u: append(cf, '\tUser {}'.format(u), use_sudo=True) else: abort('Unknown method') print_green('INFO: Set SSH key... OK')