2014-06-23 11:10:09 -07:00
|
|
|
from fabric.api import cd, lcd, env, local, parallel, serial
|
2016-02-05 16:58:08 -08:00
|
|
|
from fabric.api import put, run, settings, sudo, prefix
|
2013-03-22 13:36:32 -07:00
|
|
|
from fabric.operations import prompt
|
2016-02-05 16:58:08 -08:00
|
|
|
from fabric.contrib import django
|
2016-02-09 13:43:21 -08:00
|
|
|
from fabric.contrib import files
|
2016-02-05 16:58:08 -08:00
|
|
|
from fabric.state import connections
|
2012-07-09 15:49:57 -07:00
|
|
|
# from fabric.colors import red, green, blue, cyan, magenta, white, yellow
|
2012-10-15 16:32:32 -07:00
|
|
|
from boto.s3.connection import S3Connection
|
|
|
|
from boto.s3.key import Key
|
|
|
|
from boto.ec2.connection import EC2Connection
|
2013-05-15 17:52:35 -07:00
|
|
|
from vendor import yaml
|
2013-05-20 13:40:46 -07:00
|
|
|
from pprint import pprint
|
2013-08-12 14:21:07 -07:00
|
|
|
from collections import defaultdict
|
2016-02-04 21:07:28 -08:00
|
|
|
from contextlib import contextmanager as _contextmanager
|
2012-07-09 15:49:57 -07:00
|
|
|
import os
|
2012-10-15 16:32:32 -07:00
|
|
|
import time
|
|
|
|
import sys
|
2013-01-07 11:33:24 -08:00
|
|
|
import re
|
2013-08-23 17:29:32 -07:00
|
|
|
|
2020-11-09 12:24:32 -05:00
|
|
|
# django.setup()
|
2020-06-06 23:53:12 -04:00
|
|
|
|
2013-03-18 09:51:20 +00:00
|
|
|
try:
|
2015-09-21 16:13:09 -07:00
|
|
|
import digitalocean
|
2013-03-18 09:51:20 +00:00
|
|
|
except ImportError:
|
2015-09-21 16:13:09 -07:00
|
|
|
print "Digital Ocean's API not loaded. Install python-digitalocean."
|
2013-03-18 09:51:20 +00:00
|
|
|
|
2010-12-16 13:54:09 -05:00
|
|
|
|
2020-06-29 17:39:55 -04:00
|
|
|
django.settings_module('newsblur.settings')
|
2011-07-17 11:31:07 -07:00
|
|
|
try:
|
|
|
|
from django.conf import settings as django_settings
|
|
|
|
except ImportError:
|
|
|
|
print " ---> Django not installed yet."
|
2016-12-12 19:55:54 -08:00
|
|
|
django_settings = None
|
2010-07-30 23:50:49 -04:00
|
|
|
|
2011-07-17 15:52:06 -07:00
|
|
|
# ============
|
|
|
|
# = DEFAULTS =
|
|
|
|
# ============
|
|
|
|
|
2020-11-12 19:38:53 -05:00
|
|
|
env.NEWSBLUR_PATH = "/srv/newsblur"
|
|
|
|
env.SECRETS_PATH = "/srv/secrets-newsblur"
|
|
|
|
env.VENDOR_PATH = "/srv/code"
|
2013-05-15 17:46:45 -07:00
|
|
|
env.user = 'sclay'
|
2013-08-12 11:58:23 -07:00
|
|
|
env.key_filename = os.path.join(env.SECRETS_PATH, 'keys/newsblur.key')
|
2015-03-09 18:20:49 -07:00
|
|
|
env.connection_attempts = 10
|
2015-12-20 14:11:37 -08:00
|
|
|
env.do_ip_to_hostname = {}
|
|
|
|
env.colorize_errors = True
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2010-07-30 23:50:49 -04:00
|
|
|
# =========
|
|
|
|
# = Roles =
|
|
|
|
# =========
|
|
|
|
|
2013-03-24 22:31:46 -07:00
|
|
|
try:
|
|
|
|
hosts_path = os.path.expanduser(os.path.join(env.SECRETS_PATH, 'configs/hosts.yml'))
|
|
|
|
roles = yaml.load(open(hosts_path))
|
|
|
|
for role_name, hosts in roles.items():
|
|
|
|
if isinstance(hosts, dict):
|
2013-03-25 09:46:43 -07:00
|
|
|
roles[role_name] = [host for host in hosts.keys()]
|
2013-03-24 22:31:46 -07:00
|
|
|
env.roledefs = roles
|
|
|
|
except:
|
|
|
|
print " ***> No role definitions found in %s. Using default roles." % hosts_path
|
|
|
|
env.roledefs = {
|
|
|
|
'app' : ['app01.newsblur.com'],
|
|
|
|
'db' : ['db01.newsblur.com'],
|
|
|
|
'task' : ['task01.newsblur.com'],
|
|
|
|
}
|
2010-07-30 23:50:49 -04:00
|
|
|
|
2021-01-04 13:33:07 -05:00
|
|
|
def do_roledefs(split=False, debug=False):
|
2015-09-21 16:13:09 -07:00
|
|
|
doapi = digitalocean.Manager(token=django_settings.DO_TOKEN_FABRIC)
|
|
|
|
droplets = doapi.get_all_droplets()
|
2015-12-20 14:11:37 -08:00
|
|
|
env.do_ip_to_hostname = {}
|
2013-06-02 18:35:26 -07:00
|
|
|
hostnames = {}
|
2013-05-20 13:40:46 -07:00
|
|
|
for droplet in droplets:
|
|
|
|
roledef = re.split(r"([0-9]+)", droplet.name)[0]
|
|
|
|
if roledef not in env.roledefs:
|
|
|
|
env.roledefs[roledef] = []
|
2013-06-02 18:35:26 -07:00
|
|
|
if roledef not in hostnames:
|
|
|
|
hostnames[roledef] = []
|
|
|
|
if droplet.ip_address not in hostnames[roledef]:
|
|
|
|
hostnames[roledef].append({'name': droplet.name, 'address': droplet.ip_address})
|
2015-12-20 14:11:37 -08:00
|
|
|
env.do_ip_to_hostname[droplet.ip_address] = droplet.name
|
2013-06-02 18:35:26 -07:00
|
|
|
if droplet.ip_address not in env.roledefs[roledef]:
|
2013-05-20 13:40:46 -07:00
|
|
|
env.roledefs[roledef].append(droplet.ip_address)
|
2013-06-02 18:35:26 -07:00
|
|
|
|
|
|
|
if split:
|
|
|
|
return hostnames
|
2013-05-20 12:57:45 -07:00
|
|
|
return droplets
|
2013-05-20 13:40:46 -07:00
|
|
|
|
|
|
|
def list_do():
|
2015-12-20 14:11:37 -08:00
|
|
|
droplets = assign_digitalocean_roledefs(split=True)
|
2013-06-14 12:29:19 -07:00
|
|
|
pprint(droplets)
|
2020-09-14 10:13:54 -04:00
|
|
|
|
|
|
|
# Uncomment below to print all IP addresses
|
|
|
|
# for group in droplets.values():
|
|
|
|
# for server in group:
|
|
|
|
# if 'address' in server:
|
|
|
|
# print(server['address'])
|
2015-05-06 19:22:53 -07:00
|
|
|
|
2015-09-21 16:13:09 -07:00
|
|
|
doapi = digitalocean.Manager(token=django_settings.DO_TOKEN_FABRIC)
|
|
|
|
droplets = doapi.get_all_droplets()
|
|
|
|
sizes = doapi.get_all_sizes()
|
|
|
|
sizes = dict((size.slug, size.price_monthly) for size in sizes)
|
2013-08-12 14:21:07 -07:00
|
|
|
role_costs = defaultdict(int)
|
|
|
|
total_cost = 0
|
|
|
|
for droplet in droplets:
|
|
|
|
roledef = re.split(r"([0-9]+)", droplet.name)[0]
|
2015-09-21 16:13:09 -07:00
|
|
|
cost = droplet.size['price_monthly']
|
2013-08-12 14:21:07 -07:00
|
|
|
role_costs[roledef] += cost
|
|
|
|
total_cost += cost
|
|
|
|
|
|
|
|
print "\n\n Costs:"
|
|
|
|
pprint(dict(role_costs))
|
|
|
|
print " ---> Total cost: $%s/month" % total_cost
|
2013-06-14 12:29:19 -07:00
|
|
|
|
2013-06-02 18:35:26 -07:00
|
|
|
def host(*names):
|
|
|
|
env.hosts = []
|
2014-01-28 15:14:23 -08:00
|
|
|
env.doname = ','.join(names)
|
2015-12-20 14:11:37 -08:00
|
|
|
hostnames = assign_digitalocean_roledefs(split=True)
|
2013-07-17 13:40:45 -07:00
|
|
|
for role, hosts in hostnames.items():
|
|
|
|
for host in hosts:
|
2013-06-16 08:16:14 -07:00
|
|
|
if isinstance(host, dict) and host['name'] in names:
|
2013-06-02 18:35:26 -07:00
|
|
|
env.hosts.append(host['address'])
|
|
|
|
print " ---> Using %s as hosts" % env.hosts
|
2013-05-20 12:03:04 -07:00
|
|
|
|
2011-03-24 09:27:05 -04:00
|
|
|
# ================
|
|
|
|
# = Environments =
|
|
|
|
# ================
|
2010-07-30 23:50:49 -04:00
|
|
|
|
2013-06-02 18:35:26 -07:00
|
|
|
def server():
|
2013-03-13 19:17:45 -07:00
|
|
|
env.NEWSBLUR_PATH = "/srv/newsblur"
|
|
|
|
env.VENDOR_PATH = "/srv/code"
|
2013-06-02 18:35:26 -07:00
|
|
|
|
2015-12-20 14:11:37 -08:00
|
|
|
def assign_digitalocean_roledefs(split=False):
|
2013-06-02 18:35:26 -07:00
|
|
|
server()
|
2013-05-20 13:40:46 -07:00
|
|
|
droplets = do_roledefs(split=split)
|
2013-06-12 13:52:43 -07:00
|
|
|
if split:
|
|
|
|
for roledef, hosts in env.roledefs.items():
|
|
|
|
if roledef not in droplets:
|
|
|
|
droplets[roledef] = hosts
|
2015-12-20 14:11:37 -08:00
|
|
|
|
2013-05-20 13:40:46 -07:00
|
|
|
return droplets
|
2011-08-29 18:43:17 -07:00
|
|
|
|
2010-12-16 13:54:09 -05:00
|
|
|
def app():
|
2020-12-05 14:12:05 -05:00
|
|
|
assign_digitalocean_roledefs()
|
|
|
|
env.roles = ['app']
|
2013-04-15 18:32:13 -07:00
|
|
|
|
2013-06-23 13:47:19 -07:00
|
|
|
def web():
|
2015-12-20 14:11:37 -08:00
|
|
|
assign_digitalocean_roledefs()
|
|
|
|
env.roles = ['app', 'push', 'work', 'search']
|
2013-06-23 13:47:19 -07:00
|
|
|
|
2013-04-15 18:32:13 -07:00
|
|
|
def work():
|
2015-12-20 14:11:37 -08:00
|
|
|
assign_digitalocean_roledefs()
|
2020-12-05 14:37:20 -05:00
|
|
|
env.roles = ['work']
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2013-05-20 15:52:11 -07:00
|
|
|
def www():
|
2015-12-20 14:11:37 -08:00
|
|
|
assign_digitalocean_roledefs()
|
2013-05-20 15:52:11 -07:00
|
|
|
env.roles = ['www']
|
|
|
|
|
2012-03-29 13:57:38 -07:00
|
|
|
def dev():
|
2015-12-20 14:11:37 -08:00
|
|
|
assign_digitalocean_roledefs()
|
2012-03-29 13:57:38 -07:00
|
|
|
env.roles = ['dev']
|
2011-07-17 15:52:06 -07:00
|
|
|
|
2013-05-14 16:01:06 -07:00
|
|
|
def debug():
|
2015-12-20 14:11:37 -08:00
|
|
|
assign_digitalocean_roledefs()
|
2013-05-14 16:01:06 -07:00
|
|
|
env.roles = ['debug']
|
|
|
|
|
|
|
|
def node():
|
2015-12-20 14:11:37 -08:00
|
|
|
assign_digitalocean_roledefs()
|
2013-05-14 16:01:06 -07:00
|
|
|
env.roles = ['node']
|
|
|
|
|
2013-08-12 14:21:07 -07:00
|
|
|
def push():
|
2015-12-20 14:11:37 -08:00
|
|
|
assign_digitalocean_roledefs()
|
2013-08-12 14:21:07 -07:00
|
|
|
env.roles = ['push']
|
|
|
|
|
2010-12-16 13:54:09 -05:00
|
|
|
def db():
|
2015-12-20 14:11:37 -08:00
|
|
|
assign_digitalocean_roledefs()
|
|
|
|
env.roles = ['db', 'search']
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2010-12-16 13:54:09 -05:00
|
|
|
def task():
|
2015-12-20 14:11:37 -08:00
|
|
|
assign_digitalocean_roledefs()
|
2020-12-03 11:58:35 -05:00
|
|
|
env.roles = ['task']
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2012-10-25 14:20:36 -07:00
|
|
|
def ec2task():
|
|
|
|
ec2()
|
|
|
|
env.roles = ['ec2task']
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2012-09-18 13:08:25 -07:00
|
|
|
def ec2():
|
|
|
|
env.user = 'ubuntu'
|
|
|
|
env.key_filename = ['/Users/sclay/.ec2/sclay.pem']
|
2015-12-20 14:11:37 -08:00
|
|
|
assign_digitalocean_roledefs()
|
2013-05-04 23:27:36 -07:00
|
|
|
|
|
|
|
def all():
|
2015-12-20 14:11:37 -08:00
|
|
|
assign_digitalocean_roledefs()
|
|
|
|
env.roles = ['app', 'db', 'task', 'debug', 'node', 'push', 'work', 'www', 'search']
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2011-02-08 22:07:59 -05:00
|
|
|
# =============
|
|
|
|
# = Bootstrap =
|
|
|
|
# =============
|
|
|
|
|
2011-03-24 09:27:05 -04:00
|
|
|
def setup_common():
|
|
|
|
setup_installs()
|
2013-05-08 01:59:33 -07:00
|
|
|
change_shell()
|
2011-03-24 09:27:05 -04:00
|
|
|
setup_user()
|
2011-12-13 17:50:33 -08:00
|
|
|
setup_sudoers()
|
2013-03-20 15:05:52 -07:00
|
|
|
setup_ulimit()
|
2018-02-13 11:23:49 -08:00
|
|
|
setup_do_monitoring()
|
2016-02-09 11:11:19 -08:00
|
|
|
setup_libxml()
|
|
|
|
setup_psql_client()
|
2011-03-24 09:27:05 -04:00
|
|
|
setup_repo()
|
|
|
|
setup_local_files()
|
2013-05-20 13:40:46 -07:00
|
|
|
setup_time_calibration()
|
2016-02-04 12:48:45 -08:00
|
|
|
setup_pip()
|
2016-02-04 21:07:28 -08:00
|
|
|
setup_virtualenv()
|
2016-02-09 11:11:19 -08:00
|
|
|
setup_repo_local_settings()
|
|
|
|
pip()
|
2011-03-24 09:27:05 -04:00
|
|
|
setup_supervisor()
|
|
|
|
setup_hosts()
|
2020-12-03 11:58:35 -05:00
|
|
|
setup_pgbouncer()
|
2011-03-24 09:27:05 -04:00
|
|
|
config_pgbouncer()
|
2013-06-17 16:16:43 -07:00
|
|
|
setup_mongoengine_repo()
|
2013-06-20 13:17:18 -07:00
|
|
|
# setup_forked_mongoengine()
|
2015-03-09 18:20:49 -07:00
|
|
|
# setup_pymongo_repo()
|
2011-03-24 09:27:05 -04:00
|
|
|
setup_logrotate()
|
2020-12-02 22:19:11 -05:00
|
|
|
copy_certificates()
|
2011-03-24 09:27:05 -04:00
|
|
|
setup_nginx()
|
2012-12-24 20:24:45 -08:00
|
|
|
setup_munin()
|
2011-03-24 09:27:05 -04:00
|
|
|
|
2013-01-16 11:06:59 -08:00
|
|
|
def setup_all():
|
2011-02-09 15:45:41 -05:00
|
|
|
setup_common()
|
2013-01-16 11:06:59 -08:00
|
|
|
setup_app(skip_common=True)
|
|
|
|
setup_db(skip_common=True)
|
|
|
|
setup_task(skip_common=True)
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2016-11-30 13:43:13 -08:00
|
|
|
def setup_app(skip_common=False, node=False):
|
2013-01-16 11:06:59 -08:00
|
|
|
if not skip_common:
|
|
|
|
setup_common()
|
2011-09-07 22:35:20 -07:00
|
|
|
setup_app_firewall()
|
2015-05-06 19:22:53 -07:00
|
|
|
setup_motd('app')
|
2012-05-02 16:46:00 -07:00
|
|
|
copy_app_settings()
|
2013-06-23 13:47:19 -07:00
|
|
|
config_nginx()
|
2011-07-17 20:53:30 -07:00
|
|
|
setup_gunicorn(supervisor=True)
|
2016-11-30 13:43:13 -08:00
|
|
|
if node:
|
|
|
|
setup_node()
|
2013-06-23 13:47:19 -07:00
|
|
|
deploy_web()
|
2012-12-10 10:49:36 -08:00
|
|
|
config_monit_app()
|
2015-03-09 18:20:49 -07:00
|
|
|
setup_usage_monitor()
|
2013-06-02 18:35:26 -07:00
|
|
|
done()
|
2017-04-24 05:33:39 -07:00
|
|
|
sudo('reboot')
|
2011-02-09 15:45:41 -05:00
|
|
|
|
2013-07-01 08:06:45 -07:00
|
|
|
def setup_app_image():
|
|
|
|
copy_app_settings()
|
|
|
|
setup_hosts()
|
|
|
|
config_pgbouncer()
|
2016-02-16 11:08:33 -08:00
|
|
|
pull()
|
|
|
|
pip()
|
2013-07-01 08:06:45 -07:00
|
|
|
deploy_web()
|
2016-02-16 11:08:33 -08:00
|
|
|
done()
|
2016-05-04 19:37:54 +08:00
|
|
|
sudo('reboot')
|
2013-07-01 08:06:45 -07:00
|
|
|
|
2013-06-23 13:47:19 -07:00
|
|
|
def setup_node():
|
|
|
|
setup_node_app()
|
2021-01-04 15:55:16 -05:00
|
|
|
config_node(full=True)
|
2013-06-23 13:47:19 -07:00
|
|
|
|
2020-10-19 15:07:14 -04:00
|
|
|
def setup_db(engine=None, skip_common=False, skip_benchmark=False):
|
2015-05-06 22:36:43 -07:00
|
|
|
if not skip_common:
|
|
|
|
setup_common()
|
2015-07-06 19:09:13 -07:00
|
|
|
setup_db_firewall()
|
2015-05-06 22:36:43 -07:00
|
|
|
setup_motd('db')
|
|
|
|
copy_db_settings()
|
2015-08-11 12:26:53 -07:00
|
|
|
if engine == "postgres":
|
2013-03-15 17:05:44 -07:00
|
|
|
setup_postgres(standby=False)
|
2015-03-09 14:50:07 -07:00
|
|
|
setup_postgres_backups()
|
2013-03-20 12:24:36 -07:00
|
|
|
elif engine == "postgres_slave":
|
2013-03-15 17:05:44 -07:00
|
|
|
setup_postgres(standby=True)
|
2020-12-02 19:22:06 -05:00
|
|
|
elif engine and engine.startswith("mongo"):
|
2015-05-10 12:12:53 -07:00
|
|
|
setup_mongo()
|
2016-11-10 10:11:46 -08:00
|
|
|
# setup_mongo_mms()
|
2015-03-09 14:50:07 -07:00
|
|
|
setup_mongo_backups()
|
2013-03-20 12:24:36 -07:00
|
|
|
elif engine == "redis":
|
2013-03-15 17:05:44 -07:00
|
|
|
setup_redis()
|
2015-03-09 14:50:07 -07:00
|
|
|
setup_redis_backups()
|
2015-08-18 08:51:43 -07:00
|
|
|
setup_redis_monitor()
|
2013-04-07 17:19:59 -07:00
|
|
|
elif engine == "redis_slave":
|
|
|
|
setup_redis(slave=True)
|
2015-08-18 08:51:43 -07:00
|
|
|
setup_redis_monitor()
|
2014-04-22 15:15:42 -07:00
|
|
|
elif engine == "elasticsearch":
|
|
|
|
setup_elasticsearch()
|
|
|
|
setup_db_search()
|
2013-01-16 11:06:59 -08:00
|
|
|
setup_gunicorn(supervisor=False)
|
2012-03-30 14:56:16 -07:00
|
|
|
setup_db_munin()
|
2015-08-11 18:13:50 -07:00
|
|
|
setup_db_monitor()
|
2015-03-09 18:20:49 -07:00
|
|
|
setup_usage_monitor()
|
2017-01-11 20:13:04 -08:00
|
|
|
if not skip_benchmark:
|
|
|
|
benchmark()
|
2013-06-02 18:35:26 -07:00
|
|
|
done()
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2013-01-16 11:06:59 -08:00
|
|
|
# if env.user == 'ubuntu':
|
|
|
|
# setup_db_mdadm()
|
2011-03-14 21:44:30 -04:00
|
|
|
|
2013-04-03 16:23:55 -07:00
|
|
|
def setup_task(queue=None, skip_common=False):
|
2013-01-16 11:06:59 -08:00
|
|
|
if not skip_common:
|
|
|
|
setup_common()
|
2011-09-07 22:35:20 -07:00
|
|
|
setup_task_firewall()
|
2015-05-06 19:22:53 -07:00
|
|
|
setup_motd('task')
|
2012-05-02 16:46:00 -07:00
|
|
|
copy_task_settings()
|
2013-04-03 16:23:55 -07:00
|
|
|
enable_celery_supervisor(queue)
|
2011-03-19 18:35:44 -04:00
|
|
|
setup_gunicorn(supervisor=False)
|
2012-08-15 17:02:55 -07:00
|
|
|
config_monit_task()
|
2015-03-09 18:20:49 -07:00
|
|
|
setup_usage_monitor()
|
2013-06-02 18:35:26 -07:00
|
|
|
done()
|
2016-12-02 13:06:16 -08:00
|
|
|
sudo('reboot')
|
2011-02-09 15:45:41 -05:00
|
|
|
|
2013-07-01 11:50:30 -07:00
|
|
|
def setup_task_image():
|
2014-08-22 08:17:53 -07:00
|
|
|
setup_installs()
|
2013-07-01 11:50:30 -07:00
|
|
|
copy_task_settings()
|
|
|
|
setup_hosts()
|
|
|
|
config_pgbouncer()
|
2014-01-28 15:14:23 -08:00
|
|
|
pull()
|
|
|
|
pip()
|
2015-05-10 12:12:53 -07:00
|
|
|
deploy(reload=True)
|
2014-01-28 15:14:23 -08:00
|
|
|
done()
|
2016-12-02 12:37:23 -08:00
|
|
|
sudo('reboot')
|
2013-07-01 11:50:30 -07:00
|
|
|
|
2011-03-14 21:44:30 -04:00
|
|
|
# ==================
|
|
|
|
# = Setup - Common =
|
|
|
|
# ==================
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2013-07-17 13:40:45 -07:00
|
|
|
def done():
|
|
|
|
print "\n\n\n\n-----------------------------------------------------"
|
2016-10-14 13:31:34 -07:00
|
|
|
print "\n\n %s / %s IS SUCCESSFULLY BOOTSTRAPPED" % (env.get('doname') or env.host_string, env.host_string)
|
2013-07-17 13:40:45 -07:00
|
|
|
print "\n\n-----------------------------------------------------\n\n\n\n"
|
|
|
|
|
2011-02-08 22:07:59 -05:00
|
|
|
def setup_installs():
|
2013-07-17 13:40:45 -07:00
|
|
|
packages = [
|
|
|
|
'build-essential',
|
|
|
|
'gcc',
|
|
|
|
'scons',
|
|
|
|
'libreadline-dev',
|
|
|
|
'sysstat',
|
|
|
|
'iotop',
|
|
|
|
'git',
|
2020-12-02 19:22:06 -05:00
|
|
|
'python2',
|
2021-01-04 09:07:42 -05:00
|
|
|
'python2.7-dev',
|
2013-07-17 13:40:45 -07:00
|
|
|
'locate',
|
|
|
|
'software-properties-common',
|
|
|
|
'libpcre3-dev',
|
|
|
|
'libncurses5-dev',
|
|
|
|
'libdbd-pg-perl',
|
|
|
|
'libssl-dev',
|
2014-05-22 11:28:45 -07:00
|
|
|
'libffi-dev',
|
2015-12-18 15:34:05 -08:00
|
|
|
'libevent-dev',
|
2013-07-17 13:40:45 -07:00
|
|
|
'make',
|
2016-03-08 13:26:11 -08:00
|
|
|
'postgresql-common',
|
|
|
|
'ssl-cert',
|
2013-07-17 13:40:45 -07:00
|
|
|
'python-setuptools',
|
|
|
|
'libyaml-0-2',
|
2021-01-04 15:55:16 -05:00
|
|
|
'pgbouncer',
|
2013-07-17 13:40:45 -07:00
|
|
|
'python-yaml',
|
|
|
|
'python-numpy',
|
|
|
|
'curl',
|
|
|
|
'monit',
|
|
|
|
'ufw',
|
|
|
|
'libjpeg8',
|
|
|
|
'libjpeg62-dev',
|
|
|
|
'libfreetype6',
|
|
|
|
'libfreetype6-dev',
|
2016-02-05 16:58:08 -08:00
|
|
|
'libmysqlclient-dev',
|
|
|
|
'libblas-dev',
|
|
|
|
'liblapack-dev',
|
|
|
|
'libatlas-base-dev',
|
|
|
|
'gfortran',
|
2016-02-05 17:35:12 -08:00
|
|
|
'libpq-dev',
|
2013-07-17 13:40:45 -07:00
|
|
|
]
|
2014-09-24 17:00:33 -07:00
|
|
|
# sudo("sed -i -e 's/archive.ubuntu.com\|security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list")
|
|
|
|
put("config/apt_sources.conf", "/etc/apt/sources.list", use_sudo=True)
|
2018-02-26 14:32:23 -08:00
|
|
|
run('sleep 10') # Dies on a lock, so just delay
|
2011-02-09 15:45:41 -05:00
|
|
|
sudo('apt-get -y update')
|
2020-12-02 20:51:33 -05:00
|
|
|
run('sleep 10') # Dies on a lock, so just delay
|
2020-12-02 19:22:06 -05:00
|
|
|
sudo('DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" dist-upgrade')
|
2021-01-04 13:33:07 -05:00
|
|
|
run('sleep 10') # Dies on a lock, so just delay
|
2020-12-02 19:22:06 -05:00
|
|
|
sudo('DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install %s' % ' '.join(packages))
|
2013-06-21 13:11:54 -07:00
|
|
|
|
2013-06-24 00:43:07 -07:00
|
|
|
with settings(warn_only=True):
|
|
|
|
sudo("ln -s /usr/lib/x86_64-linux-gnu/libjpeg.so /usr/lib")
|
|
|
|
sudo("ln -s /usr/lib/x86_64-linux-gnu/libfreetype.so /usr/lib")
|
|
|
|
sudo("ln -s /usr/lib/x86_64-linux-gnu/libz.so /usr/lib")
|
2013-06-21 13:11:54 -07:00
|
|
|
|
2013-03-20 12:24:36 -07:00
|
|
|
with settings(warn_only=True):
|
|
|
|
sudo('mkdir -p %s' % env.VENDOR_PATH)
|
2013-03-20 15:05:52 -07:00
|
|
|
sudo('chown %s.%s %s' % (env.user, env.user, env.VENDOR_PATH))
|
2013-05-08 01:59:33 -07:00
|
|
|
|
|
|
|
def change_shell():
|
|
|
|
sudo('apt-get -y install zsh')
|
|
|
|
with settings(warn_only=True):
|
|
|
|
run('git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh')
|
|
|
|
sudo('chsh %s -s /bin/zsh' % env.user)
|
|
|
|
|
2011-03-14 21:44:30 -04:00
|
|
|
def setup_user():
|
2012-09-18 13:08:25 -07:00
|
|
|
# run('useradd -c "NewsBlur" -m newsblur -s /bin/zsh')
|
2011-03-14 21:44:30 -04:00
|
|
|
# run('openssl rand -base64 8 | tee -a ~conesus/.password | passwd -stdin conesus')
|
|
|
|
run('mkdir -p ~/.ssh && chmod 700 ~/.ssh')
|
2011-03-15 10:02:13 -04:00
|
|
|
run('rm -fr ~/.ssh/id_dsa*')
|
2011-03-14 21:44:30 -04:00
|
|
|
run('ssh-keygen -t dsa -f ~/.ssh/id_dsa -N ""')
|
2011-03-15 10:02:13 -04:00
|
|
|
run('touch ~/.ssh/authorized_keys')
|
|
|
|
put("~/.ssh/id_dsa.pub", "authorized_keys")
|
2013-08-12 11:58:23 -07:00
|
|
|
run("echo \"\n\" >> ~sclay/.ssh/authorized_keys")
|
|
|
|
run('echo `cat authorized_keys` >> ~sclay/.ssh/authorized_keys')
|
2012-09-18 13:08:25 -07:00
|
|
|
run('rm authorized_keys')
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2017-03-28 10:43:20 -07:00
|
|
|
def copy_ssh_keys(username='sclay', private=False):
|
|
|
|
sudo('mkdir -p ~%s/.ssh' % username)
|
|
|
|
|
|
|
|
put(os.path.join(env.SECRETS_PATH, 'keys/newsblur.key.pub'), 'local.key.pub')
|
2017-03-30 10:55:11 -07:00
|
|
|
sudo('mv local.key.pub ~%s/.ssh/id_rsa.pub' % username)
|
2017-03-28 10:43:20 -07:00
|
|
|
if private:
|
|
|
|
put(os.path.join(env.SECRETS_PATH, 'keys/newsblur.key'), 'local.key')
|
2017-03-30 10:55:11 -07:00
|
|
|
sudo('mv local.key ~%s/.ssh/id_rsa' % username)
|
2017-03-28 10:43:20 -07:00
|
|
|
|
|
|
|
sudo("echo \"\n\" >> ~%s/.ssh/authorized_keys" % username)
|
2017-03-30 10:55:11 -07:00
|
|
|
sudo("echo `cat ~%s/.ssh/id_rsa.pub` >> ~%s/.ssh/authorized_keys" % (username, username))
|
2017-03-28 10:43:20 -07:00
|
|
|
sudo('chown -R %s.%s ~%s/.ssh' % (username, username, username))
|
2018-03-09 09:43:46 -08:00
|
|
|
sudo('chmod 700 ~%s/.ssh' % username)
|
2017-03-30 10:55:11 -07:00
|
|
|
sudo('chmod 600 ~%s/.ssh/id_rsa*' % username)
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2011-02-09 15:45:41 -05:00
|
|
|
def setup_repo():
|
2012-10-15 16:32:32 -07:00
|
|
|
sudo('mkdir -p /srv')
|
2013-05-20 19:27:10 -07:00
|
|
|
sudo('chown -R %s.%s /srv' % (env.user, env.user))
|
2013-05-20 13:40:46 -07:00
|
|
|
with settings(warn_only=True):
|
2013-05-20 19:27:10 -07:00
|
|
|
run('git clone https://github.com/samuelclay/NewsBlur.git %s' % env.NEWSBLUR_PATH)
|
2013-05-20 13:40:46 -07:00
|
|
|
with settings(warn_only=True):
|
2013-05-20 19:27:10 -07:00
|
|
|
sudo('ln -sfn /srv/code /home/%s/code' % env.user)
|
|
|
|
sudo('ln -sfn /srv/newsblur /home/%s/newsblur' % env.user)
|
2011-07-17 15:52:06 -07:00
|
|
|
|
|
|
|
def setup_repo_local_settings():
|
2016-02-04 12:48:45 -08:00
|
|
|
with virtualenv():
|
2020-12-05 17:23:31 -05:00
|
|
|
run('cp newsblur/local_settings.py.template newsblur/local_settings.py')
|
2011-02-09 15:45:41 -05:00
|
|
|
run('mkdir -p logs')
|
2011-03-19 18:35:44 -04:00
|
|
|
run('touch logs/newsblur.log')
|
2011-02-09 15:45:41 -05:00
|
|
|
|
2011-03-15 10:02:13 -04:00
|
|
|
def setup_local_files():
|
2021-01-04 11:27:17 -05:00
|
|
|
run('mkdir -p ~/.config/procps')
|
|
|
|
put("config/toprc", "~/.config/procps/toprc")
|
2021-01-04 15:55:16 -05:00
|
|
|
run('rm -f ~/.toprc')
|
2016-02-09 09:52:09 -08:00
|
|
|
put("config/zshrc", "~/.zshrc")
|
|
|
|
put('config/gitconfig.txt', '~/.gitconfig')
|
|
|
|
put('config/ssh.conf', '~/.ssh/config')
|
2011-03-15 10:02:13 -04:00
|
|
|
|
2013-05-29 18:00:09 -07:00
|
|
|
def setup_psql_client():
|
2020-12-02 19:22:06 -05:00
|
|
|
sudo('apt-get -y install postgresql-client')
|
2013-05-29 18:00:09 -07:00
|
|
|
sudo('mkdir -p /var/run/postgresql')
|
2015-02-23 13:31:05 -08:00
|
|
|
with settings(warn_only=True):
|
|
|
|
sudo('chown postgres.postgres /var/run/postgresql')
|
2013-05-29 18:00:09 -07:00
|
|
|
|
2011-02-09 15:45:41 -05:00
|
|
|
def setup_libxml():
|
|
|
|
sudo('apt-get -y install libxml2-dev libxslt1-dev python-lxml')
|
2011-03-24 09:27:05 -04:00
|
|
|
|
|
|
|
def setup_libxml_code():
|
2011-07-17 15:56:28 -07:00
|
|
|
with cd(env.VENDOR_PATH):
|
2011-03-24 09:27:05 -04:00
|
|
|
run('git clone git://git.gnome.org/libxml2')
|
|
|
|
run('git clone git://git.gnome.org/libxslt')
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2011-07-17 20:53:30 -07:00
|
|
|
with cd(os.path.join(env.VENDOR_PATH, 'libxml2')):
|
2011-03-24 09:27:05 -04:00
|
|
|
run('./configure && make && sudo make install')
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2011-07-17 20:53:30 -07:00
|
|
|
with cd(os.path.join(env.VENDOR_PATH, 'libxslt')):
|
2011-03-24 09:27:05 -04:00
|
|
|
run('./configure && make && sudo make install')
|
2011-07-17 12:08:24 -07:00
|
|
|
|
|
|
|
def setup_psycopg():
|
2012-02-23 13:20:10 -08:00
|
|
|
sudo('easy_install -U psycopg2')
|
2013-03-19 18:06:01 +00:00
|
|
|
|
2016-02-04 21:07:28 -08:00
|
|
|
def setup_virtualenv():
|
2016-02-09 11:11:19 -08:00
|
|
|
sudo('rm -fr ~/.cache') # Clean `sudo pip`
|
2017-02-20 18:40:20 -08:00
|
|
|
sudo('pip install --upgrade virtualenv')
|
|
|
|
sudo('pip install --upgrade virtualenvwrapper')
|
|
|
|
setup_local_files()
|
2016-02-08 20:24:27 -08:00
|
|
|
with prefix('WORKON_HOME=%s' % os.path.join(env.NEWSBLUR_PATH, 'venv')):
|
|
|
|
with prefix('source /usr/local/bin/virtualenvwrapper.sh'):
|
|
|
|
with cd(env.NEWSBLUR_PATH):
|
|
|
|
# sudo('rmvirtualenv newsblur')
|
|
|
|
# sudo('rm -fr venv')
|
2016-02-09 09:52:09 -08:00
|
|
|
with settings(warn_only=True):
|
2020-06-15 17:53:35 -04:00
|
|
|
run('mkvirtualenv newsblur')
|
2016-02-08 20:24:27 -08:00
|
|
|
run('echo "import sys; sys.setdefaultencoding(\'utf-8\')" | sudo tee venv/newsblur/lib/python2.7/sitecustomize.py')
|
2016-11-11 11:23:05 -08:00
|
|
|
run('echo "/srv/newsblur" | sudo tee venv/newsblur/lib/python2.7/site-packages/newsblur.pth')
|
2016-02-04 21:07:28 -08:00
|
|
|
|
2016-02-04 12:48:45 -08:00
|
|
|
@_contextmanager
|
|
|
|
def virtualenv():
|
2016-02-08 20:24:27 -08:00
|
|
|
with prefix('WORKON_HOME=%s' % os.path.join(env.NEWSBLUR_PATH, 'venv')):
|
2016-02-08 18:04:42 -08:00
|
|
|
with prefix('source /usr/local/bin/virtualenvwrapper.sh'):
|
|
|
|
with cd(env.NEWSBLUR_PATH):
|
2016-02-08 20:24:27 -08:00
|
|
|
with prefix('workon newsblur'):
|
|
|
|
yield
|
2016-02-04 12:48:45 -08:00
|
|
|
|
|
|
|
def setup_pip():
|
2020-12-02 19:22:06 -05:00
|
|
|
with cd(env.VENDOR_PATH), settings(warn_only=True):
|
2021-01-23 19:27:54 -05:00
|
|
|
run('curl https://bootstrap.pypa.io/2.6/get-pip.py | sudo python2')
|
|
|
|
# sudo('python2 get-pip.py')
|
2020-12-02 19:22:06 -05:00
|
|
|
|
2016-02-04 12:48:45 -08:00
|
|
|
|
2016-02-03 12:55:39 -08:00
|
|
|
@parallel
|
2014-01-21 16:56:03 -08:00
|
|
|
def pip():
|
2020-12-05 14:37:20 -05:00
|
|
|
role = role_for_host()
|
|
|
|
|
2014-04-11 18:09:23 -07:00
|
|
|
pull()
|
2016-02-04 12:48:45 -08:00
|
|
|
with virtualenv():
|
2020-12-05 14:37:20 -05:00
|
|
|
if role == "task":
|
|
|
|
with settings(warn_only=True):
|
|
|
|
sudo('fallocate -l 4G /swapfile')
|
|
|
|
sudo('chmod 600 /swapfile')
|
|
|
|
sudo('mkswap /swapfile')
|
|
|
|
sudo('swapon /swapfile')
|
2016-12-14 13:31:20 -08:00
|
|
|
sudo('chown %s.%s -R %s' % (env.user, env.user, os.path.join(env.NEWSBLUR_PATH, 'venv')))
|
2021-01-23 19:27:54 -05:00
|
|
|
# run('easy_install -U pip')
|
|
|
|
# run('pip install --upgrade pip')
|
|
|
|
# run('pip install --upgrade setuptools')
|
2016-02-05 18:27:06 -08:00
|
|
|
run('pip install -r requirements.txt')
|
2020-12-05 14:37:20 -05:00
|
|
|
if role == "task":
|
|
|
|
with settings(warn_only=True):
|
|
|
|
sudo('swapoff /swapfile')
|
2016-12-05 22:09:05 -08:00
|
|
|
|
|
|
|
def solo_pip(role):
|
|
|
|
if role == "app":
|
|
|
|
gunicorn_stop()
|
|
|
|
pip()
|
|
|
|
deploy_code(reload=True)
|
|
|
|
elif role == "task":
|
|
|
|
celery_stop()
|
|
|
|
copy_task_settings()
|
|
|
|
pip()
|
|
|
|
celery()
|
2014-01-21 16:56:03 -08:00
|
|
|
|
2011-03-14 21:44:30 -04:00
|
|
|
def setup_supervisor():
|
2020-11-12 20:27:25 -05:00
|
|
|
sudo('apt-get update')
|
2011-03-14 21:44:30 -04:00
|
|
|
sudo('apt-get -y install supervisor')
|
2013-04-07 17:19:59 -07:00
|
|
|
put('config/supervisord.conf', '/etc/supervisor/supervisord.conf', use_sudo=True)
|
|
|
|
sudo('/etc/init.d/supervisor stop')
|
2013-04-06 12:31:51 -07:00
|
|
|
sudo('sleep 2')
|
2013-05-29 18:00:09 -07:00
|
|
|
sudo('ulimit -n 100000 && /etc/init.d/supervisor start')
|
2016-12-02 13:06:16 -08:00
|
|
|
sudo("/usr/sbin/update-rc.d -f supervisor defaults")
|
2016-12-06 17:58:59 -08:00
|
|
|
sudo('systemctl enable supervisor')
|
|
|
|
sudo('systemctl start supervisor')
|
2013-03-14 18:43:01 -07:00
|
|
|
|
2013-04-21 06:07:01 -07:00
|
|
|
@parallel
|
2011-03-15 18:06:24 -04:00
|
|
|
def setup_hosts():
|
2013-07-17 13:40:45 -07:00
|
|
|
put(os.path.join(env.SECRETS_PATH, 'configs/hosts'), '/etc/hosts', use_sudo=True)
|
2015-08-03 12:23:49 -07:00
|
|
|
sudo('echo "\n\n127.0.0.1 `hostname`" | sudo tee -a /etc/hosts')
|
2011-03-19 16:19:53 -04:00
|
|
|
|
2015-12-18 15:34:05 -08:00
|
|
|
def setup_pgbouncer():
|
|
|
|
sudo('apt-get remove -y pgbouncer')
|
2020-12-03 11:58:35 -05:00
|
|
|
sudo('apt-get install -y libevent-dev pkg-config libc-ares2 libc-ares-dev')
|
|
|
|
PGBOUNCER_VERSION = '1.15.0'
|
2015-12-18 15:34:05 -08:00
|
|
|
with cd(env.VENDOR_PATH), settings(warn_only=True):
|
|
|
|
run('wget https://pgbouncer.github.io/downloads/files/%s/pgbouncer-%s.tar.gz' % (PGBOUNCER_VERSION, PGBOUNCER_VERSION))
|
|
|
|
run('tar -xzf pgbouncer-%s.tar.gz' % PGBOUNCER_VERSION)
|
|
|
|
run('rm pgbouncer-%s.tar.gz' % PGBOUNCER_VERSION)
|
|
|
|
with cd('pgbouncer-%s' % PGBOUNCER_VERSION):
|
2020-12-03 11:58:35 -05:00
|
|
|
run('./configure --prefix=/usr/local')
|
2015-12-18 15:34:05 -08:00
|
|
|
run('make')
|
|
|
|
sudo('make install')
|
|
|
|
sudo('ln -s /usr/local/bin/pgbouncer /usr/sbin/pgbouncer')
|
|
|
|
config_pgbouncer()
|
|
|
|
|
2011-03-23 15:43:15 -04:00
|
|
|
def config_pgbouncer():
|
2016-03-08 13:26:11 -08:00
|
|
|
sudo('mkdir -p /etc/pgbouncer')
|
2015-02-23 13:31:05 -08:00
|
|
|
put('config/pgbouncer.conf', 'pgbouncer.conf')
|
|
|
|
sudo('mv pgbouncer.conf /etc/pgbouncer/pgbouncer.ini')
|
|
|
|
put(os.path.join(env.SECRETS_PATH, 'configs/pgbouncer_auth.conf'), 'userlist.txt')
|
|
|
|
sudo('mv userlist.txt /etc/pgbouncer/userlist.txt')
|
2015-08-03 12:23:49 -07:00
|
|
|
sudo('echo "START=1" | sudo tee /etc/default/pgbouncer')
|
2016-12-02 12:37:23 -08:00
|
|
|
# sudo('su postgres -c "/etc/init.d/pgbouncer stop"', pty=False)
|
2011-09-09 17:43:56 -07:00
|
|
|
with settings(warn_only=True):
|
2016-12-02 12:37:23 -08:00
|
|
|
sudo('/etc/init.d/pgbouncer stop')
|
2013-10-11 19:46:33 -07:00
|
|
|
sudo('pkill -9 pgbouncer -e')
|
2012-05-15 15:25:01 -07:00
|
|
|
run('sleep 2')
|
2012-07-20 01:26:56 -07:00
|
|
|
sudo('/etc/init.d/pgbouncer start', pty=False)
|
|
|
|
|
2017-03-15 20:16:36 -07:00
|
|
|
@parallel
|
2017-03-28 21:16:09 -07:00
|
|
|
def kill_pgbouncer(stop=False):
|
2016-12-02 12:37:23 -08:00
|
|
|
# sudo('su postgres -c "/etc/init.d/pgbouncer stop"', pty=False)
|
|
|
|
with settings(warn_only=True):
|
|
|
|
sudo('/etc/init.d/pgbouncer stop')
|
2013-06-24 00:12:10 -07:00
|
|
|
run('sleep 2')
|
2016-10-14 11:24:42 -07:00
|
|
|
sudo('rm /var/log/postgresql/pgbouncer.pid')
|
2012-07-20 01:26:56 -07:00
|
|
|
with settings(warn_only=True):
|
2015-04-16 19:07:37 -07:00
|
|
|
sudo('pkill -9 pgbouncer')
|
2013-06-24 00:12:10 -07:00
|
|
|
run('sleep 2')
|
2017-03-28 21:16:09 -07:00
|
|
|
if not stop:
|
2016-02-05 16:58:08 -08:00
|
|
|
run('sudo /etc/init.d/pgbouncer start', pty=False)
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2012-08-15 17:02:55 -07:00
|
|
|
def config_monit_task():
|
|
|
|
put('config/monit_task.conf', '/etc/monit/conf.d/celery.conf', use_sudo=True)
|
2015-08-03 12:23:49 -07:00
|
|
|
sudo('echo "START=yes" | sudo tee /etc/default/monit')
|
2012-08-15 17:02:55 -07:00
|
|
|
sudo('/etc/init.d/monit restart')
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2013-05-28 18:21:55 -07:00
|
|
|
def config_monit_node():
|
|
|
|
put('config/monit_node.conf', '/etc/monit/conf.d/node.conf', use_sudo=True)
|
2015-08-03 12:23:49 -07:00
|
|
|
sudo('echo "START=yes" | sudo tee /etc/default/monit')
|
2013-05-28 18:21:55 -07:00
|
|
|
sudo('/etc/init.d/monit restart')
|
|
|
|
|
2014-09-18 10:12:19 -07:00
|
|
|
def config_monit_original():
|
|
|
|
put('config/monit_original.conf', '/etc/monit/conf.d/node_original.conf', use_sudo=True)
|
2015-08-03 12:23:49 -07:00
|
|
|
sudo('echo "START=yes" | sudo tee /etc/default/monit')
|
2014-09-18 10:12:19 -07:00
|
|
|
sudo('/etc/init.d/monit restart')
|
|
|
|
|
2012-12-10 10:49:36 -08:00
|
|
|
def config_monit_app():
|
|
|
|
put('config/monit_app.conf', '/etc/monit/conf.d/gunicorn.conf', use_sudo=True)
|
2015-08-03 12:23:49 -07:00
|
|
|
sudo('echo "START=yes" | sudo tee /etc/default/monit')
|
2012-12-10 10:49:36 -08:00
|
|
|
sudo('/etc/init.d/monit restart')
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2013-12-22 15:17:13 -08:00
|
|
|
def config_monit_work():
|
|
|
|
put('config/monit_work.conf', '/etc/monit/conf.d/work.conf', use_sudo=True)
|
2015-08-03 12:23:49 -07:00
|
|
|
sudo('echo "START=yes" | sudo tee /etc/default/monit')
|
2013-12-22 15:17:13 -08:00
|
|
|
sudo('/etc/init.d/monit restart')
|
|
|
|
|
2013-07-05 23:24:13 -07:00
|
|
|
def config_monit_redis():
|
2013-09-17 15:56:16 -07:00
|
|
|
sudo('chown root.root /etc/init.d/redis')
|
|
|
|
sudo('chmod a+x /etc/init.d/redis')
|
|
|
|
put('config/monit_debug.sh', '/etc/monit/monit_debug.sh', use_sudo=True)
|
|
|
|
sudo('chmod a+x /etc/monit/monit_debug.sh')
|
2013-07-05 23:24:13 -07:00
|
|
|
put('config/monit_redis.conf', '/etc/monit/conf.d/redis.conf', use_sudo=True)
|
2015-08-03 12:23:49 -07:00
|
|
|
sudo('echo "START=yes" | sudo tee /etc/default/monit')
|
2011-03-28 10:07:45 -04:00
|
|
|
sudo('/etc/init.d/monit restart')
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2013-06-17 16:16:43 -07:00
|
|
|
def setup_mongoengine_repo():
|
2013-03-20 16:06:02 -07:00
|
|
|
with cd(env.VENDOR_PATH), settings(warn_only=True):
|
|
|
|
run('rm -fr mongoengine')
|
|
|
|
run('git clone https://github.com/MongoEngine/mongoengine.git')
|
|
|
|
sudo('rm -fr /usr/local/lib/python2.7/dist-packages/mongoengine')
|
|
|
|
sudo('rm -fr /usr/local/lib/python2.7/dist-packages/mongoengine-*')
|
2013-05-20 19:27:10 -07:00
|
|
|
sudo('ln -sfn %s /usr/local/lib/python2.7/dist-packages/mongoengine' %
|
2013-03-20 16:06:02 -07:00
|
|
|
os.path.join(env.VENDOR_PATH, 'mongoengine/mongoengine'))
|
2013-06-17 16:16:43 -07:00
|
|
|
with cd(os.path.join(env.VENDOR_PATH, 'mongoengine')), settings(warn_only=True):
|
|
|
|
run('git co v0.8.2')
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2015-03-09 18:20:49 -07:00
|
|
|
def clear_pymongo_repo():
|
|
|
|
sudo('rm -fr /usr/local/lib/python2.7/dist-packages/pymongo*')
|
|
|
|
sudo('rm -fr /usr/local/lib/python2.7/dist-packages/bson*')
|
|
|
|
sudo('rm -fr /usr/local/lib/python2.7/dist-packages/gridfs*')
|
|
|
|
|
2011-03-19 16:19:53 -04:00
|
|
|
def setup_pymongo_repo():
|
2013-03-20 16:06:02 -07:00
|
|
|
with cd(env.VENDOR_PATH), settings(warn_only=True):
|
|
|
|
run('git clone git://github.com/mongodb/mongo-python-driver.git pymongo')
|
2012-11-06 11:28:36 -08:00
|
|
|
# with cd(os.path.join(env.VENDOR_PATH, 'pymongo')):
|
|
|
|
# sudo('python setup.py install')
|
2015-03-09 18:20:49 -07:00
|
|
|
clear_pymongo_repo()
|
2013-05-20 19:27:10 -07:00
|
|
|
sudo('ln -sfn %s /usr/local/lib/python2.7/dist-packages/' %
|
2012-11-06 11:28:36 -08:00
|
|
|
os.path.join(env.VENDOR_PATH, 'pymongo/{pymongo,bson,gridfs}'))
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2011-03-19 16:19:53 -04:00
|
|
|
def setup_forked_mongoengine():
|
2013-03-20 16:06:02 -07:00
|
|
|
with cd(os.path.join(env.VENDOR_PATH, 'mongoengine')), settings(warn_only=True):
|
|
|
|
run('git remote add clay https://github.com/samuelclay/mongoengine.git')
|
|
|
|
run('git pull')
|
|
|
|
run('git fetch clay')
|
|
|
|
run('git checkout -b clay_master clay/master')
|
2011-05-18 14:23:43 -04:00
|
|
|
|
|
|
|
def switch_forked_mongoengine():
|
2011-07-17 20:53:30 -07:00
|
|
|
with cd(os.path.join(env.VENDOR_PATH, 'mongoengine')):
|
2011-05-20 09:51:56 -04:00
|
|
|
run('git co dev')
|
2012-09-18 13:08:25 -07:00
|
|
|
run('git pull %s dev --force' % env.user)
|
2011-05-20 09:51:56 -04:00
|
|
|
# run('git checkout .')
|
|
|
|
# run('git checkout master')
|
|
|
|
# run('get branch -D dev')
|
|
|
|
# run('git checkout -b dev origin/dev')
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2013-08-13 15:45:40 -07:00
|
|
|
def setup_logrotate(clear=True):
|
2014-02-20 14:52:11 -08:00
|
|
|
if clear:
|
|
|
|
run('find /srv/newsblur/logs/*.log | xargs tee')
|
2016-12-18 10:04:43 -08:00
|
|
|
with settings(warn_only=True):
|
|
|
|
sudo('find /var/log/mongodb/*.log | xargs tee')
|
2011-03-23 15:43:15 -04:00
|
|
|
put('config/logrotate.conf', '/etc/logrotate.d/newsblur', use_sudo=True)
|
2013-04-02 15:41:50 -07:00
|
|
|
put('config/logrotate.mongo.conf', '/etc/logrotate.d/mongodb', use_sudo=True)
|
2016-01-23 18:00:44 -08:00
|
|
|
put('config/logrotate.nginx.conf', '/etc/logrotate.d/nginx', use_sudo=True)
|
|
|
|
sudo('chown root.root /etc/logrotate.d/{newsblur,mongodb,nginx}')
|
|
|
|
sudo('chmod 644 /etc/logrotate.d/{newsblur,mongodb,nginx}')
|
2014-02-20 14:52:11 -08:00
|
|
|
with settings(warn_only=True):
|
|
|
|
sudo('chown sclay.sclay /srv/newsblur/logs/*.log')
|
2013-08-13 15:45:40 -07:00
|
|
|
sudo('logrotate -f /etc/logrotate.d/newsblur')
|
2016-01-23 18:00:44 -08:00
|
|
|
sudo('logrotate -f /etc/logrotate.d/nginx')
|
|
|
|
sudo('logrotate -f /etc/logrotate.d/mongodb')
|
2013-03-17 20:14:55 -07:00
|
|
|
|
|
|
|
def setup_ulimit():
|
2013-03-26 16:55:29 -07:00
|
|
|
# Increase File Descriptor limits.
|
2013-03-20 15:05:52 -07:00
|
|
|
run('export FILEMAX=`sysctl -n fs.file-max`', pty=False)
|
|
|
|
sudo('mv /etc/security/limits.conf /etc/security/limits.conf.bak', pty=False)
|
|
|
|
sudo('touch /etc/security/limits.conf', pty=False)
|
2015-08-03 12:23:49 -07:00
|
|
|
run('echo "root soft nofile 100000\n" | sudo tee -a /etc/security/limits.conf', pty=False)
|
|
|
|
run('echo "root hard nofile 100000\n" | sudo tee -a /etc/security/limits.conf', pty=False)
|
|
|
|
run('echo "* soft nofile 100000\n" | sudo tee -a /etc/security/limits.conf', pty=False)
|
|
|
|
run('echo "* hard nofile 100090\n" | sudo tee -a /etc/security/limits.conf', pty=False)
|
|
|
|
run('echo "fs.file-max = 100000\n" | sudo tee -a /etc/sysctl.conf', pty=False)
|
2013-04-23 17:58:25 -07:00
|
|
|
sudo('sysctl -p')
|
2013-06-02 18:35:26 -07:00
|
|
|
sudo('ulimit -n 100000')
|
|
|
|
connections.connect(env.host_string)
|
2015-02-11 17:30:15 -08:00
|
|
|
|
2013-03-17 20:14:55 -07:00
|
|
|
# run('touch /home/ubuntu/.bash_profile')
|
|
|
|
# run('echo "ulimit -n $FILEMAX" >> /home/ubuntu/.bash_profile')
|
|
|
|
|
|
|
|
# Increase Ephemeral Ports.
|
|
|
|
# sudo chmod 666 /etc/sysctl.conf
|
|
|
|
# echo "net.ipv4.ip_local_port_range = 1024 65535" >> /etc/sysctl.conf
|
|
|
|
# sudo chmod 644 /etc/sysctl.conf
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2018-02-13 11:23:49 -08:00
|
|
|
def setup_do_monitoring():
|
|
|
|
run('curl -sSL https://agent.digitalocean.com/install.sh | sh')
|
|
|
|
|
2013-08-12 11:58:23 -07:00
|
|
|
def setup_syncookies():
|
2015-08-03 12:23:49 -07:00
|
|
|
sudo('echo 1 | sudo tee /proc/sys/net/ipv4/tcp_syncookies')
|
2013-08-12 11:58:23 -07:00
|
|
|
sudo('sudo /sbin/sysctl -w net.ipv4.tcp_syncookies=1')
|
|
|
|
|
2013-03-14 18:43:01 -07:00
|
|
|
def setup_sudoers(user=None):
|
2015-08-05 13:11:53 -07:00
|
|
|
sudo('echo "%s ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/sclay' % (user or env.user))
|
|
|
|
sudo('chmod 0440 /etc/sudoers.d/sclay')
|
2011-02-09 15:45:41 -05:00
|
|
|
|
|
|
|
def setup_nginx():
|
2020-12-02 19:22:06 -05:00
|
|
|
NGINX_VERSION = '1.19.5'
|
2013-03-20 16:06:02 -07:00
|
|
|
with cd(env.VENDOR_PATH), settings(warn_only=True):
|
|
|
|
sudo("groupadd nginx")
|
|
|
|
sudo("useradd -g nginx -d /var/www/htdocs -s /bin/false nginx")
|
|
|
|
run('wget http://nginx.org/download/nginx-%s.tar.gz' % NGINX_VERSION)
|
|
|
|
run('tar -xzf nginx-%s.tar.gz' % NGINX_VERSION)
|
|
|
|
run('rm nginx-%s.tar.gz' % NGINX_VERSION)
|
|
|
|
with cd('nginx-%s' % NGINX_VERSION):
|
2014-05-22 09:21:38 -07:00
|
|
|
run('./configure --with-http_ssl_module --with-http_stub_status_module --with-http_gzip_static_module --with-http_realip_module ')
|
2013-03-20 16:06:02 -07:00
|
|
|
run('make')
|
|
|
|
sudo('make install')
|
2013-06-23 13:47:19 -07:00
|
|
|
config_nginx()
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2013-06-23 13:47:19 -07:00
|
|
|
def config_nginx():
|
2011-03-21 20:07:24 -04:00
|
|
|
put("config/nginx.conf", "/usr/local/nginx/conf/nginx.conf", use_sudo=True)
|
|
|
|
sudo("mkdir -p /usr/local/nginx/conf/sites-enabled")
|
|
|
|
sudo("mkdir -p /var/log/nginx")
|
2011-08-26 09:34:30 -07:00
|
|
|
put("config/nginx.newsblur.conf", "/usr/local/nginx/conf/sites-enabled/newsblur.conf", use_sudo=True)
|
2011-03-21 20:07:24 -04:00
|
|
|
put("config/nginx-init", "/etc/init.d/nginx", use_sudo=True)
|
2013-03-25 11:53:31 -07:00
|
|
|
sudo('sed -i -e s/nginx_none/`cat /etc/hostname`/g /usr/local/nginx/conf/sites-enabled/newsblur.conf')
|
2011-03-21 20:07:24 -04:00
|
|
|
sudo("chmod 0755 /etc/init.d/nginx")
|
|
|
|
sudo("/usr/sbin/update-rc.d -f nginx defaults")
|
2011-03-31 18:51:23 -04:00
|
|
|
sudo("/etc/init.d/nginx restart")
|
2012-09-19 12:00:41 -07:00
|
|
|
copy_certificates()
|
2012-04-23 13:18:50 -07:00
|
|
|
|
2011-03-24 09:27:05 -04:00
|
|
|
# ===============
|
|
|
|
# = Setup - App =
|
|
|
|
# ===============
|
|
|
|
|
2011-09-07 22:35:20 -07:00
|
|
|
def setup_app_firewall():
|
|
|
|
sudo('ufw default deny')
|
2013-05-08 01:59:33 -07:00
|
|
|
sudo('ufw allow ssh') # ssh
|
|
|
|
sudo('ufw allow 80') # http
|
|
|
|
sudo('ufw allow 8000') # gunicorn
|
|
|
|
sudo('ufw allow 8888') # socket.io
|
|
|
|
sudo('ufw allow 8889') # socket.io ssl
|
|
|
|
sudo('ufw allow 443') # https
|
2011-09-07 22:35:20 -07:00
|
|
|
sudo('ufw --force enable')
|
|
|
|
|
2014-12-30 14:40:06 -08:00
|
|
|
def remove_gunicorn():
|
|
|
|
with cd(env.VENDOR_PATH):
|
|
|
|
sudo('rm -fr gunicorn')
|
|
|
|
|
2016-02-09 09:52:09 -08:00
|
|
|
def setup_gunicorn(supervisor=True, restart=True):
|
2011-03-24 09:27:05 -04:00
|
|
|
if supervisor:
|
|
|
|
put('config/supervisor_gunicorn.conf', '/etc/supervisor/conf.d/gunicorn.conf', use_sudo=True)
|
2015-05-06 19:22:53 -07:00
|
|
|
sudo('supervisorctl reread')
|
2016-02-09 09:52:09 -08:00
|
|
|
if restart:
|
2020-12-07 17:52:22 -05:00
|
|
|
sudo('supervisorctl update')
|
2014-12-30 14:40:06 -08:00
|
|
|
# with cd(env.VENDOR_PATH):
|
|
|
|
# sudo('rm -fr gunicorn')
|
|
|
|
# run('git clone git://github.com/benoitc/gunicorn.git')
|
|
|
|
# with cd(os.path.join(env.VENDOR_PATH, 'gunicorn')):
|
|
|
|
# run('git pull')
|
|
|
|
# sudo('python setup.py develop')
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2011-03-24 09:27:05 -04:00
|
|
|
|
|
|
|
def update_gunicorn():
|
2011-07-17 20:53:30 -07:00
|
|
|
with cd(os.path.join(env.VENDOR_PATH, 'gunicorn')):
|
2011-03-24 09:27:05 -04:00
|
|
|
run('git pull')
|
|
|
|
sudo('python setup.py develop')
|
2011-03-14 21:44:30 -04:00
|
|
|
|
2011-04-15 11:34:41 -04:00
|
|
|
def setup_staging():
|
|
|
|
run('git clone https://github.com/samuelclay/NewsBlur.git staging')
|
|
|
|
with cd('~/staging'):
|
|
|
|
run('cp ../newsblur/local_settings.py local_settings.py')
|
|
|
|
run('mkdir -p logs')
|
|
|
|
run('touch logs/newsblur.log')
|
2012-01-02 18:22:06 -08:00
|
|
|
|
2013-06-23 13:47:19 -07:00
|
|
|
def setup_node_app():
|
2020-06-15 17:53:35 -04:00
|
|
|
sudo('curl -sL https://deb.nodesource.com/setup_14.x | sudo bash -')
|
2018-04-30 21:57:44 -07:00
|
|
|
sudo('apt-get install -y nodejs')
|
2017-11-30 18:37:03 -08:00
|
|
|
# run('curl -L https://npmjs.org/install.sh | sudo sh')
|
2018-04-30 21:57:44 -07:00
|
|
|
# sudo('apt-get install npm')
|
2019-04-13 16:17:13 -04:00
|
|
|
sudo('sudo npm install -g npm')
|
2012-01-02 18:22:06 -08:00
|
|
|
sudo('npm install -g supervisor')
|
2012-01-13 22:25:06 -08:00
|
|
|
sudo('ufw allow 8888')
|
2019-04-13 16:01:51 -04:00
|
|
|
sudo('ufw allow 4040')
|
2012-04-07 14:44:52 -07:00
|
|
|
|
2019-04-13 16:17:13 -04:00
|
|
|
def config_node(full=False):
|
2021-01-04 16:47:24 -05:00
|
|
|
sudo('rm -f /etc/supervisor/conf.d/gunicorn.conf')
|
|
|
|
sudo('rm -f /etc/supervisor/conf.d/node.conf')
|
2012-04-07 14:44:52 -07:00
|
|
|
put('config/supervisor_node_unread.conf', '/etc/supervisor/conf.d/node_unread.conf', use_sudo=True)
|
2015-07-06 19:09:13 -07:00
|
|
|
put('config/supervisor_node_unread_ssl.conf', '/etc/supervisor/conf.d/node_unread_ssl.conf', use_sudo=True)
|
2013-03-28 18:13:08 -07:00
|
|
|
put('config/supervisor_node_favicons.conf', '/etc/supervisor/conf.d/node_favicons.conf', use_sudo=True)
|
2019-04-13 15:28:56 -04:00
|
|
|
put('config/supervisor_node_text.conf', '/etc/supervisor/conf.d/node_text.conf', use_sudo=True)
|
2019-04-13 16:17:13 -04:00
|
|
|
|
|
|
|
if full:
|
|
|
|
run("rm -fr /srv/newsblur/node/node_modules")
|
|
|
|
with cd(os.path.join(env.NEWSBLUR_PATH, "node")):
|
|
|
|
run("npm install")
|
|
|
|
|
2012-03-29 17:24:23 -07:00
|
|
|
sudo('supervisorctl reload')
|
2012-01-14 18:54:59 -08:00
|
|
|
|
2013-03-18 13:14:37 -07:00
|
|
|
@parallel
|
2012-05-02 16:46:00 -07:00
|
|
|
def copy_app_settings():
|
2020-11-12 20:27:25 -05:00
|
|
|
run('rm -f %s/local_settings.py' % env.NEWSBLUR_PATH)
|
2013-07-17 13:40:45 -07:00
|
|
|
put(os.path.join(env.SECRETS_PATH, 'settings/app_settings.py'),
|
2020-11-12 20:27:25 -05:00
|
|
|
'%s/newsblur/local_settings.py' % env.NEWSBLUR_PATH)
|
|
|
|
run('echo "\nSERVER_NAME = \\\\"`hostname`\\\\"" >> %s/newsblur/local_settings.py' % env.NEWSBLUR_PATH)
|
2012-05-21 09:40:44 -07:00
|
|
|
|
2014-06-23 11:10:09 -07:00
|
|
|
def assemble_certificates():
|
|
|
|
with lcd(os.path.join(env.SECRETS_PATH, 'certificates/comodo')):
|
|
|
|
local('pwd')
|
|
|
|
local('cat STAR_newsblur_com.crt EssentialSSLCA_2.crt ComodoUTNSGCCA.crt UTNAddTrustSGCCA.crt AddTrustExternalCARoot.crt > newsblur.com.crt')
|
|
|
|
|
2012-05-21 09:40:44 -07:00
|
|
|
def copy_certificates():
|
2020-06-01 17:17:31 -04:00
|
|
|
cert_path = os.path.join(env.NEWSBLUR_PATH, 'config/certificates')
|
2013-05-16 18:20:54 -07:00
|
|
|
run('mkdir -p %s' % cert_path)
|
2021-01-11 16:44:25 -05:00
|
|
|
fullchain_path = "/etc/letsencrypt/live/newsblur.com/fullchain.pem"
|
|
|
|
privkey_path = "/etc/letsencrypt/live/newsblur.com/privkey.pem"
|
|
|
|
run('ln -fs %s %s' % (fullchain_path, os.path.join(cert_path, 'newsblur.com.crt')))
|
|
|
|
run('ln -fs %s %s' % (fullchain_path, os.path.join(cert_path, 'newsblur.com.pem'))) # For backwards compatibility with hard-coded nginx configs
|
|
|
|
run('ln -fs %s %s' % (privkey_path, os.path.join(cert_path, 'newsblur.com.key')))
|
2021-01-11 17:49:52 -05:00
|
|
|
run('ln -fs %s %s' % (privkey_path, os.path.join(cert_path, 'newsblur.com.crt.key'))) # HAProxy
|
2016-08-12 10:46:15 -07:00
|
|
|
put(os.path.join(env.SECRETS_PATH, 'certificates/comodo/dhparams.pem'), cert_path)
|
2016-11-17 19:53:02 -08:00
|
|
|
put(os.path.join(env.SECRETS_PATH, 'certificates/ios/aps_development.pem'), cert_path)
|
2021-01-20 13:29:12 -05:00
|
|
|
|
|
|
|
# Export aps.cer from Apple issued certificate using Keychain Assistant
|
2019-12-21 09:06:47 -05:00
|
|
|
# openssl x509 -in aps.cer -inform DER -outform PEM -out aps.pem
|
2016-11-17 19:53:02 -08:00
|
|
|
put(os.path.join(env.SECRETS_PATH, 'certificates/ios/aps.pem'), cert_path)
|
2019-12-21 09:06:47 -05:00
|
|
|
# Export aps.p12 from aps.cer using Keychain Assistant
|
|
|
|
# openssl pkcs12 -in aps.p12 -out aps.p12.pem -nodes
|
2019-12-20 16:01:57 -05:00
|
|
|
put(os.path.join(env.SECRETS_PATH, 'certificates/ios/aps.p12.pem'), cert_path)
|
2021-01-20 13:29:12 -05:00
|
|
|
|
2020-06-01 17:09:57 -04:00
|
|
|
def setup_certbot():
|
2021-01-11 16:44:25 -05:00
|
|
|
sudo('snap install --classic certbot')
|
|
|
|
sudo('snap set certbot trust-plugin-with-root=ok')
|
|
|
|
sudo('snap install certbot-dns-dnsimple')
|
|
|
|
sudo('ln -fs /snap/bin/certbot /usr/bin/certbot')
|
|
|
|
put(os.path.join(env.SECRETS_PATH, 'configs/certbot.conf'),
|
|
|
|
os.path.join(env.NEWSBLUR_PATH, 'certbot.conf'))
|
2021-01-11 17:49:52 -05:00
|
|
|
sudo('chmod 0600 %s' % os.path.join(env.NEWSBLUR_PATH, 'certbot.conf'))
|
2021-01-11 16:44:25 -05:00
|
|
|
sudo('certbot certonly -n --agree-tos '
|
|
|
|
' --dns-dnsimple --dns-dnsimple-credentials %s'
|
|
|
|
' --email samuel@newsblur.com --domains newsblur.com '
|
2021-01-11 17:49:52 -05:00
|
|
|
' -d "*.newsblur.com" -d "popular.global.newsblur.com"' %
|
2021-01-11 16:44:25 -05:00
|
|
|
(os.path.join(env.NEWSBLUR_PATH, 'certbot.conf')))
|
|
|
|
sudo('chmod 0755 /etc/letsencrypt/{live,archive}')
|
2021-01-11 17:49:52 -05:00
|
|
|
sudo('chmod 0755 /etc/letsencrypt/archive/newsblur.com/privkey1.pem')
|
2021-01-11 16:44:25 -05:00
|
|
|
|
2021-01-11 17:49:52 -05:00
|
|
|
# def setup_certbot_old():
|
2021-01-11 16:44:25 -05:00
|
|
|
# sudo('add-apt-repository -y universe')
|
|
|
|
# sudo('add-apt-repository -y ppa:certbot/certbot')
|
|
|
|
# sudo('apt-get update')
|
|
|
|
# sudo('apt-get install -y certbot')
|
|
|
|
# sudo('apt-get install -y python3-certbot-dns-dnsimple')
|
2021-01-11 17:49:52 -05:00
|
|
|
# put(os.path.join(env.SECRETS_PATH, 'configs/certbot.conf'),
|
|
|
|
# os.path.join(env.NEWSBLUR_PATH, 'certbot.conf'))
|
|
|
|
# sudo('chmod 0600 %s' % os.path.join(env.NEWSBLUR_PATH, 'certbot.conf'))
|
|
|
|
# sudo('certbot certonly -n --agree-tos '
|
|
|
|
# ' --dns-dnsimple --dns-dnsimple-credentials %s'
|
|
|
|
# ' --email samuel@newsblur.com --domains newsblur.com '
|
|
|
|
# ' -d "*.newsblur.com" -d "global.popular.newsblur.com"' %
|
|
|
|
# (os.path.join(env.NEWSBLUR_PATH, 'certbot.conf')))
|
|
|
|
# sudo('chmod 0755 /etc/letsencrypt/{live,archive}')
|
|
|
|
# sudo('chmod 0755 /etc/letsencrypt/archive/newsblur.com/privkey1.pem')
|
2020-06-01 17:09:57 -04:00
|
|
|
|
2012-12-25 15:09:46 -08:00
|
|
|
@parallel
|
2012-06-26 11:19:53 -07:00
|
|
|
def maintenance_on():
|
2016-11-10 17:24:31 -08:00
|
|
|
role = role_for_host()
|
|
|
|
if role in ['work', 'search']:
|
|
|
|
sudo('supervisorctl stop all')
|
|
|
|
else:
|
|
|
|
put('templates/maintenance_off.html', '%s/templates/maintenance_off.html' % env.NEWSBLUR_PATH)
|
|
|
|
with virtualenv():
|
|
|
|
run('mv templates/maintenance_off.html templates/maintenance_on.html')
|
2012-12-25 15:09:46 -08:00
|
|
|
|
2013-03-20 22:00:03 -07:00
|
|
|
@parallel
|
2012-06-26 11:19:53 -07:00
|
|
|
def maintenance_off():
|
2016-11-10 17:24:31 -08:00
|
|
|
role = role_for_host()
|
|
|
|
if role in ['work', 'search']:
|
|
|
|
sudo('supervisorctl start all')
|
|
|
|
else:
|
|
|
|
with virtualenv():
|
|
|
|
run('mv templates/maintenance_on.html templates/maintenance_off.html')
|
|
|
|
run('git checkout templates/maintenance_off.html')
|
2013-03-14 21:40:14 -07:00
|
|
|
|
2013-04-23 18:35:37 -07:00
|
|
|
def setup_haproxy(debug=False):
|
2015-07-14 16:20:46 -07:00
|
|
|
version = "1.5.14"
|
2013-05-09 16:54:29 -07:00
|
|
|
sudo('ufw allow 81') # nginx moved
|
|
|
|
sudo('ufw allow 1936') # haproxy stats
|
2014-10-27 16:32:10 -07:00
|
|
|
# sudo('apt-get install -y haproxy')
|
|
|
|
# sudo('apt-get remove -y haproxy')
|
2013-03-17 10:28:26 -07:00
|
|
|
with cd(env.VENDOR_PATH):
|
2015-05-07 10:59:38 -07:00
|
|
|
run('wget http://www.haproxy.org/download/1.5/src/haproxy-%s.tar.gz' % version)
|
|
|
|
run('tar -xf haproxy-%s.tar.gz' % version)
|
|
|
|
with cd('haproxy-%s' % version):
|
2013-03-17 10:28:26 -07:00
|
|
|
run('make TARGET=linux2628 USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1')
|
|
|
|
sudo('make install')
|
2013-03-14 21:40:14 -07:00
|
|
|
put('config/haproxy-init', '/etc/init.d/haproxy', use_sudo=True)
|
|
|
|
sudo('chmod u+x /etc/init.d/haproxy')
|
2013-04-01 14:41:54 -07:00
|
|
|
sudo('mkdir -p /etc/haproxy')
|
2013-04-23 18:35:37 -07:00
|
|
|
if debug:
|
|
|
|
put('config/debug_haproxy.conf', '/etc/haproxy/haproxy.cfg', use_sudo=True)
|
|
|
|
else:
|
2019-04-13 16:01:51 -04:00
|
|
|
build_haproxy()
|
2013-07-17 13:40:45 -07:00
|
|
|
put(os.path.join(env.SECRETS_PATH, 'configs/haproxy.conf'),
|
|
|
|
'/etc/haproxy/haproxy.cfg', use_sudo=True)
|
2015-08-03 12:23:49 -07:00
|
|
|
sudo('echo "ENABLED=1" | sudo tee /etc/default/haproxy')
|
2013-03-17 10:28:26 -07:00
|
|
|
cert_path = "%s/config/certificates" % env.NEWSBLUR_PATH
|
2013-03-14 22:39:58 -07:00
|
|
|
run('cat %s/newsblur.com.crt > %s/newsblur.pem' % (cert_path, cert_path))
|
|
|
|
run('cat %s/newsblur.com.key >> %s/newsblur.pem' % (cert_path, cert_path))
|
2013-03-17 12:39:05 -07:00
|
|
|
put('config/haproxy_rsyslog.conf', '/etc/rsyslog.d/49-haproxy.conf', use_sudo=True)
|
2016-12-27 14:31:19 -08:00
|
|
|
# sudo('restart rsyslog')
|
2016-03-16 11:28:32 -07:00
|
|
|
sudo('update-rc.d -f haproxy defaults')
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2013-03-14 22:39:58 -07:00
|
|
|
sudo('/etc/init.d/haproxy stop')
|
2019-04-13 16:01:51 -04:00
|
|
|
run('sleep 5')
|
2013-03-14 22:39:58 -07:00
|
|
|
sudo('/etc/init.d/haproxy start')
|
2013-03-14 21:40:14 -07:00
|
|
|
|
2013-03-17 10:28:26 -07:00
|
|
|
def config_haproxy(debug=False):
|
|
|
|
if debug:
|
|
|
|
put('config/debug_haproxy.conf', '/etc/haproxy/haproxy.cfg', use_sudo=True)
|
|
|
|
else:
|
2018-02-26 14:32:23 -08:00
|
|
|
build_haproxy()
|
2013-07-17 13:40:45 -07:00
|
|
|
put(os.path.join(env.SECRETS_PATH, 'configs/haproxy.conf'),
|
|
|
|
'/etc/haproxy/haproxy.cfg', use_sudo=True)
|
2018-02-26 14:32:23 -08:00
|
|
|
|
2015-07-14 17:42:55 -07:00
|
|
|
haproxy_check = run('haproxy -c -f /etc/haproxy/haproxy.cfg')
|
|
|
|
if haproxy_check.return_code == 0:
|
|
|
|
sudo('/etc/init.d/haproxy reload')
|
|
|
|
else:
|
|
|
|
print " !!!> Uh-oh, HAProxy config doesn't check out: %s" % haproxy_check.return_code
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2018-02-26 14:32:23 -08:00
|
|
|
def build_haproxy():
|
|
|
|
droplets = assign_digitalocean_roledefs(split=True)
|
|
|
|
servers = defaultdict(list)
|
2018-02-27 17:01:51 -08:00
|
|
|
gunicorn_counts_servers = ['app22', 'app26']
|
2018-02-26 18:35:02 -08:00
|
|
|
gunicorn_refresh_servers = ['app20', 'app21']
|
|
|
|
maintenance_servers = ['app20']
|
2021-01-04 17:53:06 -05:00
|
|
|
node_socket3_servers = ['node02', 'node03']
|
|
|
|
ignore_servers = []
|
2018-02-26 14:32:23 -08:00
|
|
|
|
2021-01-04 17:53:06 -05:00
|
|
|
for group_type in ['app', 'push', 'work', 'node_socket', 'node_socket3', 'node_favicon', 'node_text', 'www']:
|
2018-02-26 14:32:23 -08:00
|
|
|
group_type_name = group_type
|
|
|
|
if 'node' in group_type:
|
|
|
|
group_type_name = 'node'
|
|
|
|
for server in droplets[group_type_name]:
|
|
|
|
droplet_nums = re.findall(r'\d+', server['name'])
|
|
|
|
droplet_num = droplet_nums[0] if droplet_nums else ''
|
|
|
|
server_type = group_type
|
|
|
|
port = 80
|
|
|
|
check_inter = 3000
|
|
|
|
|
2018-02-26 18:35:02 -08:00
|
|
|
if server['name'] in ignore_servers:
|
|
|
|
print " ---> Ignoring %s" % server['name']
|
|
|
|
continue
|
2021-01-04 17:53:06 -05:00
|
|
|
if server['name'] in node_socket3_servers and group_type != 'node_socket3':
|
|
|
|
continue
|
|
|
|
if server['name'] not in node_socket3_servers and group_type == 'node_socket3':
|
|
|
|
continue
|
2018-02-26 14:32:23 -08:00
|
|
|
if server_type == 'www':
|
|
|
|
port = 81
|
|
|
|
if group_type == 'node_socket':
|
|
|
|
port = 8888
|
2021-01-04 17:53:06 -05:00
|
|
|
if group_type == 'node_socket3':
|
|
|
|
port = 8888
|
2019-04-13 19:35:58 -04:00
|
|
|
if group_type == 'node_text':
|
|
|
|
port = 4040
|
2018-02-26 14:32:23 -08:00
|
|
|
if group_type in ['app', 'push']:
|
|
|
|
port = 8000
|
|
|
|
address = "%s:%s" % (server['address'], port)
|
|
|
|
|
|
|
|
if server_type == 'app':
|
|
|
|
nginx_address = "%s:80" % (server['address'])
|
|
|
|
servers['nginx'].append(" server nginx%-15s %-22s check inter 3000ms" % (droplet_num, nginx_address))
|
|
|
|
if server['name'] in maintenance_servers:
|
|
|
|
nginx_address = "%s:80" % (server['address'])
|
|
|
|
servers['maintenance'].append(" server nginx%-15s %-22s check inter 3000ms" % (droplet_num, nginx_address))
|
|
|
|
|
|
|
|
if server['name'] in gunicorn_counts_servers:
|
|
|
|
server_type = 'gunicorn_counts'
|
|
|
|
check_inter = 15000
|
|
|
|
elif server['name'] in gunicorn_refresh_servers:
|
|
|
|
server_type = 'gunicorn_refresh'
|
|
|
|
check_inter = 30000
|
|
|
|
|
|
|
|
server_name = "%s%s" % (server_type, droplet_num)
|
|
|
|
servers[server_type].append(" server %-20s %-22s check inter %sms" % (server_name, address, check_inter))
|
|
|
|
|
|
|
|
h = open(os.path.join(env.NEWSBLUR_PATH, 'config/haproxy.conf.template'), 'r')
|
|
|
|
haproxy_template = h.read()
|
|
|
|
for sub, server_list in servers.items():
|
|
|
|
sorted_servers = '\n'.join(sorted(server_list))
|
|
|
|
haproxy_template = haproxy_template.replace("{{ %s }}" % sub, sorted_servers)
|
|
|
|
f = open(os.path.join(env.SECRETS_PATH, 'configs/haproxy.conf'), 'w')
|
|
|
|
f.write(haproxy_template)
|
|
|
|
f.close()
|
|
|
|
|
2020-12-05 14:12:05 -05:00
|
|
|
def upgrade_django(role=None):
|
|
|
|
if not role:
|
|
|
|
role = role_for_host()
|
|
|
|
|
2016-02-04 12:48:45 -08:00
|
|
|
with virtualenv(), settings(warn_only=True):
|
2020-11-13 11:02:27 -05:00
|
|
|
sudo('sudo dpkg --configure -a')
|
|
|
|
setup_supervisor()
|
2020-12-02 16:58:30 -05:00
|
|
|
pull()
|
|
|
|
run('git co django1.11')
|
2020-11-13 11:02:27 -05:00
|
|
|
if role == "task":
|
|
|
|
sudo('supervisorctl stop celery')
|
|
|
|
run('./utils/kill_celery.sh')
|
|
|
|
copy_task_settings()
|
|
|
|
enable_celery_supervisor(update=False)
|
2020-12-05 13:35:32 -05:00
|
|
|
elif role == "work":
|
|
|
|
copy_app_settings()
|
|
|
|
enable_celerybeat()
|
2020-12-05 14:12:05 -05:00
|
|
|
elif role == "web" or role == "app":
|
2020-11-13 11:02:27 -05:00
|
|
|
sudo('supervisorctl stop gunicorn')
|
|
|
|
run('./utils/kill_gunicorn.sh')
|
|
|
|
copy_app_settings()
|
|
|
|
setup_gunicorn(restart=False)
|
2020-12-05 14:37:20 -05:00
|
|
|
elif role == "node":
|
|
|
|
copy_app_settings()
|
|
|
|
config_node(full=True)
|
|
|
|
else:
|
|
|
|
copy_task_settings()
|
|
|
|
|
2020-11-12 20:27:25 -05:00
|
|
|
pip()
|
|
|
|
clean()
|
|
|
|
|
2020-12-05 14:37:20 -05:00
|
|
|
# sudo('reboot')
|
2014-05-16 12:18:59 -07:00
|
|
|
|
2020-11-09 12:24:32 -05:00
|
|
|
def clean():
|
|
|
|
with virtualenv(), settings(warn_only=True):
|
|
|
|
run('find . -name "*.pyc" -exec rm -f {} \;')
|
|
|
|
|
2020-12-02 19:22:06 -05:00
|
|
|
def downgrade_django(role=None):
|
|
|
|
with virtualenv(), settings(warn_only=True):
|
|
|
|
pull()
|
|
|
|
run('git co master')
|
|
|
|
pip()
|
|
|
|
run('pip uninstall -y django-paypal')
|
|
|
|
if role == "task":
|
|
|
|
copy_task_settings()
|
|
|
|
enable_celery_supervisor()
|
|
|
|
else:
|
|
|
|
copy_app_settings()
|
|
|
|
deploy()
|
|
|
|
|
2020-11-13 19:39:37 -05:00
|
|
|
def vendorize_paypal():
|
|
|
|
with virtualenv(), settings(warn_only=True):
|
|
|
|
run('pip uninstall -y django-paypal')
|
|
|
|
|
2013-03-22 15:27:10 -07:00
|
|
|
def upgrade_pil():
|
2016-02-04 12:48:45 -08:00
|
|
|
with virtualenv():
|
2013-03-22 16:12:01 -07:00
|
|
|
pull()
|
2017-02-07 08:27:56 -08:00
|
|
|
run('pip install --upgrade pillow')
|
2014-05-16 12:39:18 -07:00
|
|
|
# celery_stop()
|
2013-03-22 16:12:01 -07:00
|
|
|
sudo('apt-get remove -y python-imaging')
|
2014-05-16 13:07:12 -07:00
|
|
|
sudo('supervisorctl reload')
|
|
|
|
# kill()
|
2013-03-22 17:16:16 -07:00
|
|
|
|
|
|
|
def downgrade_pil():
|
2016-02-04 12:48:45 -08:00
|
|
|
with virtualenv():
|
2013-03-22 17:16:16 -07:00
|
|
|
sudo('apt-get install -y python-imaging')
|
|
|
|
sudo('rm -fr /usr/local/lib/python2.7/dist-packages/Pillow*')
|
|
|
|
pull()
|
2014-05-16 13:07:12 -07:00
|
|
|
sudo('supervisorctl reload')
|
|
|
|
# kill()
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2015-08-09 14:06:28 -07:00
|
|
|
def setup_db_monitor():
|
|
|
|
pull()
|
2016-02-04 12:48:45 -08:00
|
|
|
with virtualenv():
|
2021-01-04 09:07:42 -05:00
|
|
|
sudo('apt-get install -y libpq-dev python2.7-dev')
|
2016-12-14 13:17:58 -08:00
|
|
|
run('pip install -r flask/requirements.txt')
|
2015-08-09 14:28:27 -07:00
|
|
|
put('flask/supervisor_db_monitor.conf', '/etc/supervisor/conf.d/db_monitor.conf', use_sudo=True)
|
2015-08-09 14:06:28 -07:00
|
|
|
sudo('supervisorctl reread')
|
|
|
|
sudo('supervisorctl update')
|
|
|
|
|
2011-03-14 21:44:30 -04:00
|
|
|
# ==============
|
|
|
|
# = Setup - DB =
|
2013-05-08 01:59:33 -07:00
|
|
|
# ==============
|
2011-03-14 21:44:30 -04:00
|
|
|
|
2013-05-15 17:46:45 -07:00
|
|
|
@parallel
|
2011-03-19 18:35:44 -04:00
|
|
|
def setup_db_firewall():
|
2012-12-17 18:42:55 -08:00
|
|
|
ports = [
|
|
|
|
5432, # PostgreSQL
|
|
|
|
27017, # MongoDB
|
2013-01-07 10:48:42 -08:00
|
|
|
28017, # MongoDB web
|
2013-06-02 18:35:26 -07:00
|
|
|
27019, # MongoDB config
|
2012-12-17 18:42:55 -08:00
|
|
|
6379, # Redis
|
2013-04-01 12:30:37 -07:00
|
|
|
# 11211, # Memcached
|
2012-12-17 18:42:55 -08:00
|
|
|
3060, # Node original page server
|
2013-01-07 10:48:42 -08:00
|
|
|
9200, # Elasticsearch
|
2015-08-11 12:26:53 -07:00
|
|
|
5000, # DB Monitor
|
2012-12-17 18:42:55 -08:00
|
|
|
]
|
2013-06-02 18:35:26 -07:00
|
|
|
sudo('ufw --force reset')
|
2011-03-19 18:35:44 -04:00
|
|
|
sudo('ufw default deny')
|
2011-09-07 22:35:20 -07:00
|
|
|
sudo('ufw allow ssh')
|
|
|
|
sudo('ufw allow 80')
|
2020-10-21 19:57:17 -04:00
|
|
|
sudo('ufw allow 443')
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2013-03-14 12:41:24 -07:00
|
|
|
# DigitalOcean
|
2013-05-08 01:59:33 -07:00
|
|
|
for ip in set(env.roledefs['app'] +
|
|
|
|
env.roledefs['db'] +
|
|
|
|
env.roledefs['debug'] +
|
|
|
|
env.roledefs['task'] +
|
2013-06-02 18:35:26 -07:00
|
|
|
env.roledefs['work'] +
|
|
|
|
env.roledefs['push'] +
|
|
|
|
env.roledefs['www'] +
|
2016-01-28 08:33:02 -08:00
|
|
|
env.roledefs['search'] +
|
2013-04-22 10:38:53 -07:00
|
|
|
env.roledefs['node']):
|
2013-03-14 12:41:24 -07:00
|
|
|
sudo('ufw allow proto tcp from %s to any port %s' % (
|
|
|
|
ip,
|
|
|
|
','.join(map(str, ports))
|
|
|
|
))
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2012-09-18 13:08:25 -07:00
|
|
|
# EC2
|
2015-07-09 18:03:30 -07:00
|
|
|
# for host in set(env.roledefs['ec2task']):
|
|
|
|
# ip = re.search('ec2-(\d+-\d+-\d+-\d+)', host).group(1).replace('-', '.')
|
|
|
|
# sudo('ufw allow proto tcp from %s to any port %s' % (
|
|
|
|
# ip,
|
|
|
|
# ','.join(map(str, ports))
|
|
|
|
# ))
|
2013-01-07 10:48:42 -08:00
|
|
|
|
2011-08-24 21:41:44 -07:00
|
|
|
sudo('ufw --force enable')
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2011-03-15 10:02:13 -04:00
|
|
|
def setup_rabbitmq():
|
2015-08-03 12:23:49 -07:00
|
|
|
sudo('echo "deb http://www.rabbitmq.com/debian/ testing main" | sudo tee -a /etc/apt/sources.list')
|
2011-03-19 19:24:14 -04:00
|
|
|
run('wget http://www.rabbitmq.com/rabbitmq-signing-key-public.asc')
|
|
|
|
sudo('apt-key add rabbitmq-signing-key-public.asc')
|
|
|
|
run('rm rabbitmq-signing-key-public.asc')
|
|
|
|
sudo('apt-get update')
|
2011-03-15 10:02:13 -04:00
|
|
|
sudo('apt-get install -y rabbitmq-server')
|
2011-03-17 19:26:21 -04:00
|
|
|
sudo('rabbitmqctl add_user newsblur newsblur')
|
|
|
|
sudo('rabbitmqctl add_vhost newsblurvhost')
|
|
|
|
sudo('rabbitmqctl set_permissions -p newsblurvhost newsblur ".*" ".*" ".*"')
|
2011-03-15 10:02:13 -04:00
|
|
|
|
2013-04-01 12:30:37 -07:00
|
|
|
# def setup_memcached():
|
|
|
|
# sudo('apt-get -y install memcached')
|
2011-11-08 14:46:30 -08:00
|
|
|
|
2012-05-15 15:25:01 -07:00
|
|
|
def setup_postgres(standby=False):
|
2018-03-09 09:43:46 -08:00
|
|
|
shmmax = 17818362112
|
2015-08-03 12:23:49 -07:00
|
|
|
hugepages = 9000
|
2020-12-02 20:51:33 -05:00
|
|
|
sudo('echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" |sudo tee /etc/apt/sources.list.d/pgdg.list')
|
2015-07-06 19:09:13 -07:00
|
|
|
sudo('wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -')
|
2020-12-02 20:51:33 -05:00
|
|
|
sudo('apt update')
|
|
|
|
sudo('apt install -y postgresql-13')
|
|
|
|
put('config/postgresql-13.conf', '/etc/postgresql/13/main/postgresql.conf', use_sudo=True)
|
|
|
|
put('config/postgres_hba-13.conf', '/etc/postgresql/13/main/pg_hba.conf', use_sudo=True)
|
|
|
|
sudo('mkdir -p /var/lib/postgresql/13/archive')
|
|
|
|
sudo('chown -R postgres.postgres /etc/postgresql/13/main')
|
|
|
|
sudo('chown -R postgres.postgres /var/lib/postgresql/13/main')
|
|
|
|
sudo('chown -R postgres.postgres /var/lib/postgresql/13/archive')
|
2015-08-03 12:23:49 -07:00
|
|
|
sudo('echo "%s" | sudo tee /proc/sys/kernel/shmmax' % shmmax)
|
|
|
|
sudo('echo "\nkernel.shmmax = %s" | sudo tee -a /etc/sysctl.conf' % shmmax)
|
|
|
|
sudo('echo "\nvm.nr_hugepages = %s\n" | sudo tee -a /etc/sysctl.conf' % hugepages)
|
2018-02-27 17:55:16 -08:00
|
|
|
run('echo "ulimit -n 100000" > postgresql.defaults')
|
|
|
|
sudo('mv postgresql.defaults /etc/default/postgresql')
|
2013-06-23 16:43:37 -07:00
|
|
|
sudo('sysctl -p')
|
2018-04-30 18:52:46 -07:00
|
|
|
sudo('rm -f /lib/systemd/system/postgresql.service') # Ubuntu 16 has wrong default
|
2017-03-16 21:45:26 -07:00
|
|
|
sudo('systemctl daemon-reload')
|
|
|
|
sudo('systemctl enable postgresql')
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2012-05-15 15:25:01 -07:00
|
|
|
if standby:
|
2020-12-02 20:51:33 -05:00
|
|
|
put('config/postgresql_recovery.conf', '/var/lib/postgresql/13/recovery.conf', use_sudo=True)
|
|
|
|
sudo('chown -R postgres.postgres /var/lib/postgresql/13/recovery.conf')
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2012-05-04 13:37:01 -07:00
|
|
|
sudo('/etc/init.d/postgresql stop')
|
|
|
|
sudo('/etc/init.d/postgresql start')
|
2011-03-15 18:06:24 -04:00
|
|
|
|
2015-07-21 15:15:29 -07:00
|
|
|
def config_postgres(standby=False):
|
2020-12-02 20:51:33 -05:00
|
|
|
put('config/postgresql-13.conf', '/etc/postgresql/13/main/postgresql.conf', use_sudo=True)
|
|
|
|
put('config/postgres_hba.conf', '/etc/postgresql/13/main/pg_hba.conf', use_sudo=True)
|
|
|
|
sudo('chown postgres.postgres /etc/postgresql/13/main/postgresql.conf')
|
2018-02-27 17:55:16 -08:00
|
|
|
run('echo "ulimit -n 100000" > postgresql.defaults')
|
|
|
|
sudo('mv postgresql.defaults /etc/default/postgresql')
|
2018-02-27 17:23:27 -08:00
|
|
|
|
2020-12-02 20:51:33 -05:00
|
|
|
sudo('/etc/init.d/postgresql reload 13')
|
2018-03-09 09:43:46 -08:00
|
|
|
|
|
|
|
def upgrade_postgres():
|
|
|
|
sudo('su postgres -c "/usr/lib/postgresql/10/bin/pg_upgrade -b /usr/lib/postgresql/9.4/bin -B /usr/lib/postgresql/10/bin -d /var/lib/postgresql/9.4/main -D /var/lib/postgresql/10/main"')
|
2015-07-21 15:15:29 -07:00
|
|
|
|
2015-07-06 19:09:13 -07:00
|
|
|
def copy_postgres_to_standby(master='db01'):
|
|
|
|
# http://www.rassoc.com/gregr/weblog/2013/02/16/zero-to-postgresql-streaming-replication-in-10-mins/
|
|
|
|
|
|
|
|
# Make sure you can ssh from master to slave and back with the postgres user account.
|
2012-07-20 01:26:56 -07:00
|
|
|
# Need to give postgres accounts keys in authroized_keys.
|
2017-03-28 10:43:20 -07:00
|
|
|
|
2018-04-30 18:52:46 -07:00
|
|
|
# local: fab host:new copy_ssh_keys:postgres,private=True
|
2018-03-12 15:17:37 -07:00
|
|
|
# new: sudo su postgres; ssh old
|
2018-04-30 21:00:50 -07:00
|
|
|
# new: sudo su postgres; ssh db_pgsql
|
2018-03-12 15:17:37 -07:00
|
|
|
# old: sudo su postgres; ssh new
|
2016-07-21 17:17:17 -07:00
|
|
|
# old: sudo su postgres -c "psql -c \"SELECT pg_start_backup('label', true)\""
|
2018-03-09 09:43:46 -08:00
|
|
|
sudo('systemctl stop postgresql')
|
2018-04-30 18:52:46 -07:00
|
|
|
sudo('mkdir -p /var/lib/postgresql/9.4/archive')
|
|
|
|
sudo('chown postgres.postgres /var/lib/postgresql/9.4/archive')
|
2017-03-30 10:55:11 -07:00
|
|
|
with settings(warn_only=True):
|
2018-04-30 18:52:46 -07:00
|
|
|
sudo('su postgres -c "rsync -Pav -e \'ssh -i ~postgres/.ssh/newsblur.key\' --stats --progress postgres@%s:/var/lib/postgresql/9.4/main /var/lib/postgresql/9.4/ --exclude postmaster.pid"' % master)
|
|
|
|
put('config/postgresql_recovery.conf', '/var/lib/postgresql/9.4/main/recovery.conf', use_sudo=True)
|
2017-03-15 19:26:54 -07:00
|
|
|
sudo('systemctl start postgresql')
|
2016-07-21 17:17:17 -07:00
|
|
|
# old: sudo su postgres -c "psql -c \"SELECT pg_stop_backup()\""
|
|
|
|
|
|
|
|
# Don't forget to add 'setup_postgres_backups' to new
|
|
|
|
|
2017-03-14 14:59:25 -07:00
|
|
|
|
|
|
|
def disable_thp():
|
|
|
|
put('config/disable_transparent_hugepages.sh', '/etc/init.d/disable-transparent-hugepages', use_sudo=True)
|
|
|
|
sudo('chmod 755 /etc/init.d/disable-transparent-hugepages')
|
|
|
|
sudo('update-rc.d disable-transparent-hugepages defaults')
|
2015-07-06 19:09:13 -07:00
|
|
|
|
2011-03-14 21:44:30 -04:00
|
|
|
def setup_mongo():
|
2021-01-23 19:27:54 -05:00
|
|
|
MONGODB_VERSION = "3.4.24"
|
2016-11-03 17:30:24 -07:00
|
|
|
pull()
|
2017-03-14 14:59:25 -07:00
|
|
|
disable_thp()
|
|
|
|
sudo('systemctl enable rc-local.service') # Enable rc.local
|
2016-11-18 16:24:54 -08:00
|
|
|
sudo('echo "#!/bin/sh -e\n\nif test -f /sys/kernel/mm/transparent_hugepage/enabled; then\n\
|
|
|
|
echo never > /sys/kernel/mm/transparent_hugepage/enabled\n\
|
|
|
|
fi\n\
|
|
|
|
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then\n\
|
|
|
|
echo never > /sys/kernel/mm/transparent_hugepage/defrag\n\
|
|
|
|
fi\n\n\
|
|
|
|
exit 0" | sudo tee /etc/rc.local')
|
2021-01-23 19:27:54 -05:00
|
|
|
sudo('curl -fsSL https://www.mongodb.org/static/pgp/server-3.4.asc | sudo apt-key add -')
|
2016-11-10 17:43:25 -08:00
|
|
|
# sudo('echo "deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen" | sudo tee /etc/apt/sources.list.d/mongodb.list')
|
2016-11-03 13:23:14 -07:00
|
|
|
# sudo('echo "\ndeb http://downloads-distro.mongodb.org/repo/debian-sysvinit dist 10gen" | sudo tee -a /etc/apt/sources.list')
|
2021-01-04 09:07:42 -05:00
|
|
|
# sudo('echo "deb http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.2.list')
|
2021-01-23 19:27:54 -05:00
|
|
|
sudo('echo "deb http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list')
|
2011-03-15 10:02:13 -04:00
|
|
|
sudo('apt-get update')
|
2021-01-04 09:07:42 -05:00
|
|
|
sudo('apt-get install -y mongodb-org=%s mongodb-org-server=%s mongodb-org-shell=%s mongodb-org-mongos=%s mongodb-org-tools=%s' %
|
2016-11-03 13:23:14 -07:00
|
|
|
(MONGODB_VERSION, MONGODB_VERSION, MONGODB_VERSION, MONGODB_VERSION, MONGODB_VERSION))
|
2013-05-08 01:59:33 -07:00
|
|
|
put('config/mongodb.%s.conf' % ('prod' if env.user != 'ubuntu' else 'ec2'),
|
2016-12-14 14:05:40 -08:00
|
|
|
'/etc/mongodb.conf', use_sudo=True)
|
2016-12-14 14:52:01 -08:00
|
|
|
put('config/mongodb.service', '/etc/systemd/system/mongodb.service', use_sudo=True)
|
2013-06-02 18:35:26 -07:00
|
|
|
run('echo "ulimit -n 100000" > mongodb.defaults')
|
2016-11-03 17:30:24 -07:00
|
|
|
sudo('mv mongodb.defaults /etc/default/mongod')
|
2016-12-14 14:05:40 -08:00
|
|
|
sudo('mkdir -p /var/log/mongodb')
|
|
|
|
sudo('chown mongodb /var/log/mongodb')
|
2016-11-03 13:23:14 -07:00
|
|
|
put('config/logrotate.mongo.conf', '/etc/logrotate.d/mongod', use_sudo=True)
|
2016-12-14 14:52:01 -08:00
|
|
|
sudo('systemctl enable mongodb')
|
2016-11-09 06:54:49 -08:00
|
|
|
|
2015-02-11 17:30:15 -08:00
|
|
|
# Reclaim 5% disk space used for root logs. Set to 1%.
|
2015-05-06 22:36:43 -07:00
|
|
|
with settings(warn_only=True):
|
2016-11-11 12:58:02 -08:00
|
|
|
sudo('tune2fs -m 1 /dev/vda1')
|
2015-02-11 17:30:15 -08:00
|
|
|
|
2013-06-02 18:35:26 -07:00
|
|
|
def setup_mongo_configsvr():
|
|
|
|
sudo('mkdir -p /var/lib/mongodb_configsvr')
|
|
|
|
sudo('chown mongodb.mongodb /var/lib/mongodb_configsvr')
|
|
|
|
put('config/mongodb.configsvr.conf', '/etc/mongodb.configsvr.conf', use_sudo=True)
|
|
|
|
put('config/mongodb.configsvr-init', '/etc/init.d/mongodb-configsvr', use_sudo=True)
|
|
|
|
sudo('chmod u+x /etc/init.d/mongodb-configsvr')
|
|
|
|
run('echo "ulimit -n 100000" > mongodb_configsvr.defaults')
|
|
|
|
sudo('mv mongodb_configsvr.defaults /etc/default/mongodb_configsvr')
|
|
|
|
sudo('update-rc.d -f mongodb-configsvr defaults')
|
|
|
|
sudo('/etc/init.d/mongodb-configsvr start')
|
|
|
|
|
|
|
|
def setup_mongo_mongos():
|
|
|
|
put('config/mongodb.mongos.conf', '/etc/mongodb.mongos.conf', use_sudo=True)
|
|
|
|
put('config/mongodb.mongos-init', '/etc/init.d/mongodb-mongos', use_sudo=True)
|
|
|
|
sudo('chmod u+x /etc/init.d/mongodb-mongos')
|
|
|
|
run('echo "ulimit -n 100000" > mongodb_mongos.defaults')
|
|
|
|
sudo('mv mongodb_mongos.defaults /etc/default/mongodb_mongos')
|
|
|
|
sudo('update-rc.d -f mongodb-mongos defaults')
|
|
|
|
sudo('/etc/init.d/mongodb-mongos restart')
|
|
|
|
|
2013-03-29 11:04:46 -07:00
|
|
|
def setup_mongo_mms():
|
|
|
|
pull()
|
2014-05-30 12:01:04 -07:00
|
|
|
sudo('rm -f /etc/supervisor/conf.d/mongomms.conf')
|
2013-03-29 11:04:46 -07:00
|
|
|
sudo('supervisorctl reread')
|
|
|
|
sudo('supervisorctl update')
|
2014-05-30 12:01:04 -07:00
|
|
|
with cd(env.VENDOR_PATH):
|
|
|
|
sudo('apt-get remove -y mongodb-mms-monitoring-agent')
|
|
|
|
run('curl -OL https://mms.mongodb.com/download/agent/monitoring/mongodb-mms-monitoring-agent_2.2.0.70-1_amd64.deb')
|
|
|
|
sudo('dpkg -i mongodb-mms-monitoring-agent_2.2.0.70-1_amd64.deb')
|
|
|
|
run('rm mongodb-mms-monitoring-agent_2.2.0.70-1_amd64.deb')
|
|
|
|
put(os.path.join(env.SECRETS_PATH, 'settings/mongo_mms_config.txt'),
|
|
|
|
'mongo_mms_config.txt')
|
2015-08-03 12:23:49 -07:00
|
|
|
sudo("echo \"\n\" | sudo tee -a /etc/mongodb-mms/monitoring-agent.config")
|
|
|
|
sudo('cat mongo_mms_config.txt | sudo tee -a /etc/mongodb-mms/monitoring-agent.config')
|
2014-05-30 12:01:04 -07:00
|
|
|
sudo('start mongodb-mms-monitoring-agent')
|
2013-03-29 11:04:46 -07:00
|
|
|
|
2013-04-07 17:19:59 -07:00
|
|
|
def setup_redis(slave=False):
|
2017-01-11 20:13:04 -08:00
|
|
|
redis_version = '3.2.6'
|
2011-11-06 15:18:44 -08:00
|
|
|
with cd(env.VENDOR_PATH):
|
2013-10-01 14:19:12 -07:00
|
|
|
run('wget http://download.redis.io/releases/redis-%s.tar.gz' % redis_version)
|
2012-05-03 18:33:29 -07:00
|
|
|
run('tar -xzf redis-%s.tar.gz' % redis_version)
|
|
|
|
run('rm redis-%s.tar.gz' % redis_version)
|
|
|
|
with cd(os.path.join(env.VENDOR_PATH, 'redis-%s' % redis_version)):
|
2011-11-18 10:13:39 -08:00
|
|
|
sudo('make install')
|
2011-11-06 15:18:44 -08:00
|
|
|
put('config/redis-init', '/etc/init.d/redis', use_sudo=True)
|
|
|
|
sudo('chmod u+x /etc/init.d/redis')
|
|
|
|
put('config/redis.conf', '/etc/redis.conf', use_sudo=True)
|
2013-04-07 17:19:59 -07:00
|
|
|
if slave:
|
|
|
|
put('config/redis_slave.conf', '/etc/redis_server.conf', use_sudo=True)
|
|
|
|
else:
|
|
|
|
put('config/redis_master.conf', '/etc/redis_server.conf', use_sudo=True)
|
2013-06-18 13:22:31 -07:00
|
|
|
# sudo('chmod 666 /proc/sys/vm/overcommit_memory', pty=False)
|
|
|
|
# run('echo "1" > /proc/sys/vm/overcommit_memory', pty=False)
|
|
|
|
# sudo('chmod 644 /proc/sys/vm/overcommit_memory', pty=False)
|
2017-03-14 14:59:25 -07:00
|
|
|
disable_thp()
|
|
|
|
sudo('systemctl enable rc-local.service') # Enable rc.local
|
2017-01-12 16:17:59 -08:00
|
|
|
sudo('echo "#!/bin/sh -e\n\nif test -f /sys/kernel/mm/transparent_hugepage/enabled; then\n\
|
|
|
|
echo never > /sys/kernel/mm/transparent_hugepage/enabled\n\
|
|
|
|
fi\n\
|
|
|
|
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then\n\
|
|
|
|
echo never > /sys/kernel/mm/transparent_hugepage/defrag\n\
|
|
|
|
fi\n\n\
|
|
|
|
exit 0" | sudo tee /etc/rc.local')
|
2015-08-06 11:45:56 -07:00
|
|
|
sudo("echo 1 | sudo tee /proc/sys/vm/overcommit_memory")
|
2015-08-03 12:23:49 -07:00
|
|
|
sudo('echo "vm.overcommit_memory = 1" | sudo tee -a /etc/sysctl.conf')
|
2013-06-18 13:22:31 -07:00
|
|
|
sudo("sysctl vm.overcommit_memory=1")
|
2015-03-10 13:45:15 -07:00
|
|
|
put('config/redis_rclocal.txt', '/etc/rc.local', use_sudo=True)
|
2015-07-17 17:21:42 -07:00
|
|
|
sudo("chown root.root /etc/rc.local")
|
|
|
|
sudo("chmod a+x /etc/rc.local")
|
2015-08-03 12:23:49 -07:00
|
|
|
sudo('echo "never" | sudo tee /sys/kernel/mm/transparent_hugepage/enabled')
|
2015-08-11 18:13:50 -07:00
|
|
|
run('echo "\nnet.core.somaxconn=65535\n" | sudo tee -a /etc/sysctl.conf', pty=False)
|
2011-11-06 15:18:44 -08:00
|
|
|
sudo('mkdir -p /var/lib/redis')
|
|
|
|
sudo('update-rc.d redis defaults')
|
2012-05-03 18:33:29 -07:00
|
|
|
sudo('/etc/init.d/redis stop')
|
2011-11-18 10:13:39 -08:00
|
|
|
sudo('/etc/init.d/redis start')
|
2013-08-12 11:58:23 -07:00
|
|
|
setup_syncookies()
|
2013-09-17 15:56:16 -07:00
|
|
|
config_monit_redis()
|
2015-03-09 14:50:07 -07:00
|
|
|
|
2012-12-24 20:24:45 -08:00
|
|
|
def setup_munin():
|
2015-05-12 08:41:14 -07:00
|
|
|
sudo('apt-get update')
|
|
|
|
sudo('apt-get install -y munin munin-node munin-plugins-extra spawn-fcgi')
|
2021-02-01 02:26:56 -05:00
|
|
|
put('config/munin.conf', '/etc/munin/munin.conf', use_sudo=True) # Only use on main munin
|
2012-12-24 20:24:45 -08:00
|
|
|
put('config/spawn_fcgi_munin_graph.conf', '/etc/init.d/spawn_fcgi_munin_graph', use_sudo=True)
|
2013-03-28 11:16:43 -07:00
|
|
|
put('config/spawn_fcgi_munin_html.conf', '/etc/init.d/spawn_fcgi_munin_html', use_sudo=True)
|
2012-12-24 20:24:45 -08:00
|
|
|
sudo('chmod u+x /etc/init.d/spawn_fcgi_munin_graph')
|
2013-03-28 11:16:43 -07:00
|
|
|
sudo('chmod u+x /etc/init.d/spawn_fcgi_munin_html')
|
|
|
|
with settings(warn_only=True):
|
2013-06-16 08:16:14 -07:00
|
|
|
sudo('chown nginx.www-data /var/log/munin/munin-cgi*')
|
|
|
|
sudo('chown nginx.www-data /usr/lib/cgi-bin/munin-cgi*')
|
|
|
|
sudo('chown nginx.www-data /usr/lib/munin/cgi/munin-cgi*')
|
2013-03-28 11:16:43 -07:00
|
|
|
with settings(warn_only=True):
|
|
|
|
sudo('/etc/init.d/spawn_fcgi_munin_graph stop')
|
|
|
|
sudo('/etc/init.d/spawn_fcgi_munin_graph start')
|
|
|
|
sudo('update-rc.d spawn_fcgi_munin_graph defaults')
|
|
|
|
sudo('/etc/init.d/spawn_fcgi_munin_html stop')
|
|
|
|
sudo('/etc/init.d/spawn_fcgi_munin_html start')
|
|
|
|
sudo('update-rc.d spawn_fcgi_munin_html defaults')
|
2014-04-17 12:10:04 -07:00
|
|
|
sudo('/etc/init.d/munin-node stop')
|
|
|
|
time.sleep(2)
|
|
|
|
sudo('/etc/init.d/munin-node start')
|
2013-03-28 11:16:43 -07:00
|
|
|
with settings(warn_only=True):
|
2013-06-16 08:16:14 -07:00
|
|
|
sudo('chown nginx.www-data /var/log/munin/munin-cgi*')
|
|
|
|
sudo('chown nginx.www-data /usr/lib/cgi-bin/munin-cgi*')
|
|
|
|
sudo('chown nginx.www-data /usr/lib/munin/cgi/munin-cgi*')
|
2013-04-15 17:59:06 -07:00
|
|
|
sudo('chmod a+rw /var/log/munin/*')
|
2013-03-28 11:16:43 -07:00
|
|
|
with settings(warn_only=True):
|
|
|
|
sudo('/etc/init.d/spawn_fcgi_munin_graph start')
|
|
|
|
sudo('/etc/init.d/spawn_fcgi_munin_html start')
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2015-05-06 21:53:11 -07:00
|
|
|
def copy_munin_data(from_server):
|
|
|
|
put(os.path.join(env.SECRETS_PATH, 'keys/newsblur.key'), '~/.ssh/newsblur.key')
|
|
|
|
put(os.path.join(env.SECRETS_PATH, 'keys/newsblur.key.pub'), '~/.ssh/newsblur.key.pub')
|
|
|
|
run('chmod 600 ~/.ssh/newsblur*')
|
|
|
|
|
2018-02-20 16:36:22 -08:00
|
|
|
# put("config/munin.nginx.conf", "/usr/local/nginx/conf/sites-enabled/munin.conf", use_sudo=True)
|
2015-05-06 21:53:11 -07:00
|
|
|
sudo('/etc/init.d/nginx reload')
|
|
|
|
|
|
|
|
run("rsync -az -e \"ssh -i /home/sclay/.ssh/newsblur.key\" --stats --progress %s:/var/lib/munin/ /srv/munin" % from_server)
|
2016-08-01 19:59:08 -04:00
|
|
|
sudo('rm -fr /var/lib/bak-munin')
|
2015-05-06 21:53:11 -07:00
|
|
|
sudo("mv /var/lib/munin /var/lib/bak-munin")
|
|
|
|
sudo("mv /srv/munin /var/lib/")
|
|
|
|
sudo("chown munin.munin -R /var/lib/munin")
|
|
|
|
|
2016-08-01 19:59:08 -04:00
|
|
|
run("sudo rsync -az -e \"ssh -i /home/sclay/.ssh/newsblur.key\" --stats --progress %s:/etc/munin/ /srv/munin-etc" % from_server)
|
2017-01-12 17:13:51 -08:00
|
|
|
sudo('rm -fr /etc/munin')
|
2016-08-01 19:59:08 -04:00
|
|
|
sudo("mv /srv/munin-etc /etc/munin")
|
|
|
|
sudo("chown munin.munin -R /etc/munin")
|
2015-05-06 21:53:11 -07:00
|
|
|
|
2017-01-12 17:13:51 -08:00
|
|
|
run("sudo rsync -az -e \"ssh -i /home/sclay/.ssh/newsblur.key\" --stats --progress %s:/var/cache/munin/www/ /srv/munin-www" % from_server)
|
|
|
|
sudo('rm -fr /var/cache/munin/www')
|
|
|
|
sudo("mv /srv/munin-www /var/cache/munin/www")
|
|
|
|
sudo("chown munin.munin -R /var/cache/munin/www")
|
|
|
|
|
2015-05-06 21:53:11 -07:00
|
|
|
sudo("/etc/init.d/munin restart")
|
|
|
|
sudo("/etc/init.d/munin-node restart")
|
|
|
|
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2012-03-05 09:24:32 -08:00
|
|
|
def setup_db_munin():
|
2016-11-11 11:48:16 -08:00
|
|
|
sudo('rm -f /etc/munin/plugins/mongo*')
|
|
|
|
sudo('rm -f /etc/munin/plugins/pg_*')
|
|
|
|
sudo('rm -f /etc/munin/plugins/redis_*')
|
2012-07-20 08:19:44 -07:00
|
|
|
sudo('cp -frs %s/config/munin/mongo* /etc/munin/plugins/' % env.NEWSBLUR_PATH)
|
|
|
|
sudo('cp -frs %s/config/munin/pg_* /etc/munin/plugins/' % env.NEWSBLUR_PATH)
|
2013-06-24 00:12:10 -07:00
|
|
|
sudo('cp -frs %s/config/munin/redis_* /etc/munin/plugins/' % env.NEWSBLUR_PATH)
|
2014-04-17 12:10:04 -07:00
|
|
|
sudo('/etc/init.d/munin-node stop')
|
|
|
|
time.sleep(2)
|
|
|
|
sudo('/etc/init.d/munin-node start')
|
|
|
|
|
2012-03-05 09:24:32 -08:00
|
|
|
|
2012-07-17 00:06:41 -07:00
|
|
|
def enable_celerybeat():
|
2016-02-04 12:48:45 -08:00
|
|
|
with virtualenv():
|
2012-07-17 00:06:41 -07:00
|
|
|
run('mkdir -p data')
|
|
|
|
put('config/supervisor_celerybeat.conf', '/etc/supervisor/conf.d/celerybeat.conf', use_sudo=True)
|
2013-04-01 12:21:20 -07:00
|
|
|
put('config/supervisor_celeryd_work_queue.conf', '/etc/supervisor/conf.d/celeryd_work_queue.conf', use_sudo=True)
|
2012-07-17 00:06:41 -07:00
|
|
|
put('config/supervisor_celeryd_beat.conf', '/etc/supervisor/conf.d/celeryd_beat.conf', use_sudo=True)
|
2013-03-14 12:55:10 -07:00
|
|
|
put('config/supervisor_celeryd_beat_feeds.conf', '/etc/supervisor/conf.d/celeryd_beat_feeds.conf', use_sudo=True)
|
2012-07-17 00:06:41 -07:00
|
|
|
sudo('supervisorctl reread')
|
|
|
|
sudo('supervisorctl update')
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2012-09-19 12:00:41 -07:00
|
|
|
def setup_db_mdadm():
|
|
|
|
sudo('apt-get -y install xfsprogs mdadm')
|
|
|
|
sudo('yes | mdadm --create /dev/md0 --level=0 -c256 --raid-devices=4 /dev/xvdf /dev/xvdg /dev/xvdh /dev/xvdi')
|
|
|
|
sudo('mkfs.xfs /dev/md0')
|
|
|
|
sudo('mkdir -p /srv/db')
|
|
|
|
sudo('mount -t xfs -o rw,nobarrier,noatime,nodiratime /dev/md0 /srv/db')
|
|
|
|
sudo('mkdir -p /srv/db/mongodb')
|
|
|
|
sudo('chown mongodb.mongodb /srv/db/mongodb')
|
|
|
|
sudo("echo 'DEVICE /dev/xvdf /dev/xvdg /dev/xvdh /dev/xvdi' | sudo tee -a /etc/mdadm/mdadm.conf")
|
|
|
|
sudo("mdadm --examine --scan | sudo tee -a /etc/mdadm/mdadm.conf")
|
|
|
|
sudo("echo '/dev/md0 /srv/db xfs rw,nobarrier,noatime,nodiratime,noauto 0 0' | sudo tee -a /etc/fstab")
|
|
|
|
sudo("sudo update-initramfs -u -v -k `uname -r`")
|
2012-12-17 18:42:55 -08:00
|
|
|
|
|
|
|
def setup_original_page_server():
|
2013-06-23 13:47:19 -07:00
|
|
|
setup_node_app()
|
2013-01-07 11:16:52 -08:00
|
|
|
sudo('mkdir -p /srv/originals')
|
2013-05-08 01:59:33 -07:00
|
|
|
sudo('chown %s.%s -R /srv/originals' % (env.user, env.user)) # We assume that the group is the same name as the user. It's common on linux
|
2014-09-18 10:12:19 -07:00
|
|
|
config_monit_original()
|
2013-05-08 01:59:33 -07:00
|
|
|
put('config/supervisor_node_original.conf',
|
2012-12-17 18:42:55 -08:00
|
|
|
'/etc/supervisor/conf.d/node_original.conf', use_sudo=True)
|
|
|
|
sudo('supervisorctl reread')
|
|
|
|
sudo('supervisorctl reload')
|
|
|
|
|
2012-12-20 16:19:27 -08:00
|
|
|
def setup_elasticsearch():
|
2017-03-15 19:26:54 -07:00
|
|
|
ES_VERSION = "2.4.4"
|
2017-03-16 21:45:26 -07:00
|
|
|
sudo('add-apt-repository -y ppa:openjdk-r/ppa')
|
2012-12-20 16:19:27 -08:00
|
|
|
sudo('apt-get update')
|
2017-03-15 19:26:54 -07:00
|
|
|
sudo('apt-get install openjdk-7-jre -y')
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2012-12-20 16:19:27 -08:00
|
|
|
with cd(env.VENDOR_PATH):
|
2015-05-06 22:36:43 -07:00
|
|
|
run('mkdir -p elasticsearch-%s' % ES_VERSION)
|
2012-12-20 16:19:27 -08:00
|
|
|
with cd(os.path.join(env.VENDOR_PATH, 'elasticsearch-%s' % ES_VERSION)):
|
2017-03-15 19:26:54 -07:00
|
|
|
# run('wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-%s.deb' % ES_VERSION) # For v5+
|
|
|
|
run('wget http://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-%s.deb' % ES_VERSION) # For v1-v2
|
2012-12-20 16:19:27 -08:00
|
|
|
sudo('dpkg -i elasticsearch-%s.deb' % ES_VERSION)
|
2016-02-09 13:43:21 -08:00
|
|
|
if not files.exists('/usr/share/elasticsearch/plugins/head'):
|
2017-03-16 21:45:26 -07:00
|
|
|
sudo('/usr/share/elasticsearch/bin/plugin install mobz/elasticsearch-head')
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2014-04-22 15:19:11 -07:00
|
|
|
def setup_db_search():
|
|
|
|
put('config/supervisor_celeryd_search_indexer.conf', '/etc/supervisor/conf.d/celeryd_search_indexer.conf', use_sudo=True)
|
2014-04-22 18:33:08 -07:00
|
|
|
put('config/supervisor_celeryd_search_indexer_tasker.conf', '/etc/supervisor/conf.d/celeryd_search_indexer_tasker.conf', use_sudo=True)
|
2014-04-22 15:19:11 -07:00
|
|
|
sudo('supervisorctl reread')
|
|
|
|
sudo('supervisorctl update')
|
2015-02-11 17:30:15 -08:00
|
|
|
|
2019-12-25 19:08:22 -05:00
|
|
|
def setup_imageproxy(install_go=False):
|
2019-12-25 18:13:29 -05:00
|
|
|
# sudo('apt-get update')
|
|
|
|
# sudo('apt-get install -y golang')
|
2019-12-25 19:08:22 -05:00
|
|
|
if install_go:
|
|
|
|
with cd(env.VENDOR_PATH):
|
|
|
|
with settings(warn_only=True):
|
|
|
|
run('git clone https://github.com/willnorris/imageproxy.git')
|
|
|
|
run('wget https://dl.google.com/go/go1.13.3.linux-amd64.tar.gz')
|
|
|
|
run('tar -xzf go1.13.3.linux-amd64.tar.gz')
|
|
|
|
run('rm go1.13.3.linux-amd64.tar.gz')
|
|
|
|
sudo('rm /usr/bin/go')
|
|
|
|
sudo('ln -s /srv/code/go/bin/go /usr/bin/go')
|
|
|
|
with cd(os.path.join(env.VENDOR_PATH, 'imageproxy')):
|
|
|
|
run('go get willnorris.com/go/imageproxy/cmd/imageproxy')
|
2019-12-25 18:36:52 -05:00
|
|
|
put(os.path.join(env.SECRETS_PATH, 'settings/imageproxy.key'),
|
|
|
|
'/etc/imageproxy.key', use_sudo=True)
|
2020-06-15 19:23:59 -04:00
|
|
|
put(os.path.join(env.NEWSBLUR_PATH, 'config/supervisor_imageproxy.conf'), '/etc/supervisor/conf.d/supervisor_imageproxy.conf', use_sudo=True)
|
2019-12-25 18:13:29 -05:00
|
|
|
sudo('supervisorctl reread')
|
|
|
|
sudo('supervisorctl update')
|
2020-06-15 19:23:59 -04:00
|
|
|
sudo('ufw allow 443')
|
2021-01-11 18:46:24 -05:00
|
|
|
sudo('ufw allow 80')
|
|
|
|
put(os.path.join(env.NEWSBLUR_PATH, 'config/nginx.imageproxy.conf'), "/usr/local/nginx/conf/sites-enabled/imageproxy.conf", use_sudo=True)
|
2019-12-25 18:13:29 -05:00
|
|
|
sudo("/etc/init.d/nginx restart")
|
|
|
|
|
|
|
|
|
2019-12-25 18:36:52 -05:00
|
|
|
|
2015-02-12 11:51:08 -08:00
|
|
|
@parallel
|
2015-02-11 17:30:15 -08:00
|
|
|
def setup_usage_monitor():
|
2015-02-11 17:37:41 -08:00
|
|
|
sudo('ln -fs %s/utils/monitor_disk_usage.py /etc/cron.daily/monitor_disk_usage' % env.NEWSBLUR_PATH)
|
2015-02-12 11:51:08 -08:00
|
|
|
sudo('/etc/cron.daily/monitor_disk_usage')
|
2014-04-22 15:19:11 -07:00
|
|
|
|
2020-06-03 12:55:44 -04:00
|
|
|
@parallel
|
|
|
|
def setup_feeds_fetched_monitor():
|
|
|
|
sudo('ln -fs %s/utils/monitor_task_fetches.py /etc/cron.hourly/monitor_task_fetches' % env.NEWSBLUR_PATH)
|
|
|
|
sudo('/etc/cron.hourly/monitor_task_fetches')
|
|
|
|
|
|
|
|
@parallel
|
|
|
|
def setup_newsletter_monitor():
|
|
|
|
sudo('ln -fs %s/utils/monitor_newsletter_delivery.py /etc/cron.hourly/monitor_newsletter_delivery' % env.NEWSBLUR_PATH)
|
|
|
|
sudo('/etc/cron.hourly/monitor_newsletter_delivery')
|
|
|
|
|
2021-01-20 13:29:12 -05:00
|
|
|
@parallel
|
|
|
|
def setup_queue_monitor():
|
|
|
|
sudo('ln -fs %s/utils/monitor_work_queue.py /etc/cron.hourly/monitor_work_queue' % env.NEWSBLUR_PATH)
|
2021-01-20 13:32:47 -05:00
|
|
|
sudo('/etc/cron.hourly/monitor_work_queue')
|
2021-01-20 13:29:12 -05:00
|
|
|
|
2015-08-18 08:51:43 -07:00
|
|
|
@parallel
|
|
|
|
def setup_redis_monitor():
|
2017-01-11 20:13:04 -08:00
|
|
|
run('sleep 5') # Wait for redis to startup so the log file is there
|
2015-08-18 08:51:43 -07:00
|
|
|
sudo('ln -fs %s/utils/monitor_redis_bgsave.py /etc/cron.daily/monitor_redis_bgsave' % env.NEWSBLUR_PATH)
|
2017-02-20 18:40:20 -08:00
|
|
|
with settings(warn_only=True):
|
|
|
|
sudo('/etc/cron.daily/monitor_redis_bgsave')
|
2015-08-18 08:51:43 -07:00
|
|
|
|
2011-03-14 21:44:30 -04:00
|
|
|
# ================
|
|
|
|
# = Setup - Task =
|
|
|
|
# ================
|
|
|
|
|
2011-09-07 22:35:20 -07:00
|
|
|
def setup_task_firewall():
|
|
|
|
sudo('ufw default deny')
|
|
|
|
sudo('ufw allow ssh')
|
|
|
|
sudo('ufw allow 80')
|
|
|
|
sudo('ufw --force enable')
|
|
|
|
|
2015-05-06 19:22:53 -07:00
|
|
|
def setup_motd(role='app'):
|
|
|
|
motd = '/etc/update-motd.d/22-newsblur-motd'
|
|
|
|
put('config/motd_%s.txt' % role, motd, use_sudo=True)
|
|
|
|
sudo('chown root.root %s' % motd)
|
|
|
|
sudo('chmod a+x %s' % motd)
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2016-02-09 09:52:09 -08:00
|
|
|
def enable_celery_supervisor(queue=None, update=True):
|
2013-04-03 16:23:55 -07:00
|
|
|
if not queue:
|
|
|
|
put('config/supervisor_celeryd.conf', '/etc/supervisor/conf.d/celeryd.conf', use_sudo=True)
|
|
|
|
else:
|
|
|
|
put('config/supervisor_celeryd_%s.conf' % queue, '/etc/supervisor/conf.d/celeryd.conf', use_sudo=True)
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2012-12-26 02:41:13 -08:00
|
|
|
sudo('supervisorctl reread')
|
2016-02-09 09:52:09 -08:00
|
|
|
if update:
|
|
|
|
sudo('supervisorctl update')
|
2012-12-26 02:41:13 -08:00
|
|
|
|
2014-06-18 13:31:29 -07:00
|
|
|
@parallel
|
|
|
|
def copy_db_settings():
|
|
|
|
return copy_task_settings()
|
|
|
|
|
2013-03-18 13:14:37 -07:00
|
|
|
@parallel
|
2012-05-02 16:46:00 -07:00
|
|
|
def copy_task_settings():
|
2013-04-03 18:11:23 -07:00
|
|
|
server_hostname = run('hostname')
|
2016-12-14 13:17:58 -08:00
|
|
|
# if any([(n in server_hostname) for n in ['task', 'db', 'search', 'node', 'push']]):
|
|
|
|
host = server_hostname
|
|
|
|
# elif env.host:
|
|
|
|
# host = env.host.split('.', 2)[0]
|
|
|
|
# else:
|
|
|
|
# host = env.host_string.split('.', 2)[0]
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2012-07-06 20:53:27 -07:00
|
|
|
with settings(warn_only=True):
|
2020-11-12 20:27:25 -05:00
|
|
|
run('rm -f %s/local_settings.py' % env.NEWSBLUR_PATH)
|
2013-07-17 13:40:45 -07:00
|
|
|
put(os.path.join(env.SECRETS_PATH, 'settings/task_settings.py'),
|
2020-11-12 20:27:25 -05:00
|
|
|
'%s/newsblur/local_settings.py' % env.NEWSBLUR_PATH)
|
|
|
|
run('echo "\nSERVER_NAME = \\\\"%s\\\\"" >> %s/newsblur/local_settings.py' % (host, env.NEWSBLUR_PATH))
|
2012-05-02 16:46:00 -07:00
|
|
|
|
2014-10-16 17:17:35 -07:00
|
|
|
@parallel
|
|
|
|
def copy_spam():
|
|
|
|
put(os.path.join(env.SECRETS_PATH, 'spam/spam.py'), '%s/apps/social/spam.py' % env.NEWSBLUR_PATH)
|
|
|
|
|
2013-03-14 18:43:01 -07:00
|
|
|
# =========================
|
|
|
|
# = Setup - Digital Ocean =
|
|
|
|
# =========================
|
|
|
|
|
2018-02-15 17:22:33 -08:00
|
|
|
DO_SIZES = {
|
|
|
|
'1': 's-1vcpu-1gb',
|
2018-04-14 19:15:27 -07:00
|
|
|
'2': 's-1vcpu-2gb',
|
|
|
|
'4': 's-2vcpu-4gb',
|
|
|
|
'8': 's-4vcpu-8gb',
|
2018-02-15 17:22:33 -08:00
|
|
|
'16': 's-6vcpu-16gb',
|
|
|
|
'32': 's-8vcpu-32gb',
|
|
|
|
'48': 's-12vcpu-48gb',
|
|
|
|
'64': 's-16vcpu-64gb',
|
2018-02-27 19:34:29 -08:00
|
|
|
'32c': 'c-16',
|
2018-02-15 17:22:33 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
def setup_do(name, size=1, image=None):
|
|
|
|
instance_size = DO_SIZES[str(size)]
|
2015-09-21 16:13:09 -07:00
|
|
|
doapi = digitalocean.Manager(token=django_settings.DO_TOKEN_FABRIC)
|
2016-12-12 15:06:07 -08:00
|
|
|
# droplets = doapi.get_all_droplets()
|
2015-09-23 15:14:31 -07:00
|
|
|
# sizes = dict((s.slug, s.slug) for s in doapi.get_all_sizes())
|
|
|
|
ssh_key_ids = [k.id for k in doapi.get_all_sshkeys()]
|
2013-07-01 08:06:45 -07:00
|
|
|
if not image:
|
2020-12-02 19:22:06 -05:00
|
|
|
image = "ubuntu-20-04-x64"
|
2013-07-01 08:06:45 -07:00
|
|
|
else:
|
2015-09-23 15:14:31 -07:00
|
|
|
images = dict((s.name, s.id) for s in doapi.get_all_images())
|
2015-05-08 15:34:35 -07:00
|
|
|
if image == "task":
|
2018-02-27 17:01:51 -08:00
|
|
|
image = images["task-2018-02"]
|
2015-09-23 15:14:31 -07:00
|
|
|
elif image == "app":
|
2018-02-26 16:48:52 -08:00
|
|
|
image = images["app-2018-02"]
|
2015-09-23 15:14:31 -07:00
|
|
|
else:
|
|
|
|
images = dict((s.name, s.id) for s in doapi.get_all_images())
|
|
|
|
print images
|
|
|
|
|
2013-05-20 12:57:45 -07:00
|
|
|
name = do_name(name)
|
2014-01-28 15:14:23 -08:00
|
|
|
env.doname = name
|
|
|
|
print "Creating droplet: %s" % name
|
2015-09-23 15:14:31 -07:00
|
|
|
instance = digitalocean.Droplet(token=django_settings.DO_TOKEN_FABRIC,
|
|
|
|
name=name,
|
|
|
|
size_slug=instance_size,
|
|
|
|
image=image,
|
|
|
|
region='nyc1',
|
2018-02-13 11:23:49 -08:00
|
|
|
monitoring=True,
|
2018-02-15 17:22:33 -08:00
|
|
|
private_networking=True,
|
2015-09-23 15:14:31 -07:00
|
|
|
ssh_keys=ssh_key_ids)
|
|
|
|
instance.create()
|
2016-10-14 13:31:34 -07:00
|
|
|
time.sleep(2)
|
2015-09-23 15:14:31 -07:00
|
|
|
instance = digitalocean.Droplet.get_object(django_settings.DO_TOKEN_FABRIC, instance.id)
|
2016-09-07 18:40:41 -07:00
|
|
|
print "Booting droplet: %s / %s (size: %s)" % (instance.name, instance.ip_address, instance_size)
|
|
|
|
|
2013-03-14 18:43:01 -07:00
|
|
|
i = 0
|
|
|
|
while True:
|
|
|
|
if instance.status == 'active':
|
|
|
|
print "...booted: %s" % instance.ip_address
|
|
|
|
time.sleep(5)
|
|
|
|
break
|
|
|
|
elif instance.status == 'new':
|
|
|
|
print ".",
|
|
|
|
sys.stdout.flush()
|
2015-09-23 15:14:31 -07:00
|
|
|
instance = digitalocean.Droplet.get_object(django_settings.DO_TOKEN_FABRIC, instance.id)
|
2013-03-14 18:43:01 -07:00
|
|
|
i += 1
|
|
|
|
time.sleep(i)
|
|
|
|
else:
|
|
|
|
print "!!! Error: %s" % instance.status
|
|
|
|
return
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2013-03-14 18:43:01 -07:00
|
|
|
host = instance.ip_address
|
|
|
|
env.host_string = host
|
2015-02-23 13:31:05 -08:00
|
|
|
time.sleep(20)
|
2013-03-14 20:38:24 -07:00
|
|
|
add_user_to_do()
|
2016-01-23 18:00:44 -08:00
|
|
|
assign_digitalocean_roledefs()
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2013-05-20 12:57:45 -07:00
|
|
|
def do_name(name):
|
|
|
|
if re.search(r"[0-9]", name):
|
|
|
|
print " ---> Using %s as hostname" % name
|
|
|
|
return name
|
|
|
|
else:
|
2013-05-20 13:40:46 -07:00
|
|
|
hosts = do_roledefs(split=False)
|
2013-05-20 12:57:45 -07:00
|
|
|
hostnames = [host.name for host in hosts]
|
|
|
|
existing_hosts = [hostname for hostname in hostnames if name in hostname]
|
2014-01-28 15:14:23 -08:00
|
|
|
for i in range(1, 100):
|
2013-05-20 12:57:45 -07:00
|
|
|
try_host = "%s%02d" % (name, i)
|
|
|
|
if try_host not in existing_hosts:
|
|
|
|
print " ---> %s hosts in %s (%s). %s is unused." % (len(existing_hosts), name,
|
|
|
|
', '.join(existing_hosts), try_host)
|
|
|
|
return try_host
|
|
|
|
|
|
|
|
|
2013-03-14 20:38:24 -07:00
|
|
|
def add_user_to_do():
|
2013-03-14 18:43:01 -07:00
|
|
|
env.user = "root"
|
2013-05-09 01:27:53 -07:00
|
|
|
repo_user = "sclay"
|
2013-03-14 18:43:01 -07:00
|
|
|
with settings(warn_only=True):
|
2013-05-09 01:27:53 -07:00
|
|
|
run('useradd -m %s' % (repo_user))
|
|
|
|
setup_sudoers("%s" % (repo_user))
|
|
|
|
run('mkdir -p ~%s/.ssh && chmod 700 ~%s/.ssh' % (repo_user, repo_user))
|
|
|
|
run('rm -fr ~%s/.ssh/id_dsa*' % (repo_user))
|
2013-05-15 17:46:45 -07:00
|
|
|
run('ssh-keygen -t dsa -f ~%s/.ssh/id_dsa -N ""' % (repo_user))
|
|
|
|
run('touch ~%s/.ssh/authorized_keys' % (repo_user))
|
2013-07-17 13:40:45 -07:00
|
|
|
copy_ssh_keys()
|
2013-05-09 01:27:53 -07:00
|
|
|
run('chown %s.%s -R ~%s/.ssh' % (repo_user, repo_user, repo_user))
|
|
|
|
env.user = repo_user
|
2013-03-14 18:43:01 -07:00
|
|
|
|
2012-10-15 16:32:32 -07:00
|
|
|
# ===============
|
|
|
|
# = Setup - EC2 =
|
|
|
|
# ===============
|
2012-05-03 18:33:29 -07:00
|
|
|
|
2013-03-13 19:17:45 -07:00
|
|
|
def setup_ec2():
|
2013-05-08 01:59:33 -07:00
|
|
|
AMI_NAME = 'ami-834cf1ea' # Ubuntu 64-bit 12.04 LTS
|
2012-10-15 16:32:32 -07:00
|
|
|
# INSTANCE_TYPE = 'c1.medium'
|
2012-10-22 11:22:28 -07:00
|
|
|
INSTANCE_TYPE = 'c1.medium'
|
2012-10-15 16:32:32 -07:00
|
|
|
conn = EC2Connection(django_settings.AWS_ACCESS_KEY_ID, django_settings.AWS_SECRET_ACCESS_KEY)
|
|
|
|
reservation = conn.run_instances(AMI_NAME, instance_type=INSTANCE_TYPE,
|
2013-05-15 17:46:45 -07:00
|
|
|
key_name=env.user,
|
2012-10-15 16:32:32 -07:00
|
|
|
security_groups=['db-mongo'])
|
|
|
|
instance = reservation.instances[0]
|
|
|
|
print "Booting reservation: %s/%s (size: %s)" % (reservation, instance, INSTANCE_TYPE)
|
2012-10-22 16:25:36 -07:00
|
|
|
i = 0
|
2012-10-15 16:32:32 -07:00
|
|
|
while True:
|
|
|
|
if instance.state == 'pending':
|
|
|
|
print ".",
|
|
|
|
sys.stdout.flush()
|
|
|
|
instance.update()
|
2012-10-22 16:25:36 -07:00
|
|
|
i += 1
|
|
|
|
time.sleep(i)
|
2012-10-15 16:32:32 -07:00
|
|
|
elif instance.state == 'running':
|
|
|
|
print "...booted: %s" % instance.public_dns_name
|
|
|
|
time.sleep(5)
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
print "!!! Error: %s" % instance.state
|
|
|
|
return
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2012-10-15 16:32:32 -07:00
|
|
|
host = instance.public_dns_name
|
|
|
|
env.host_string = host
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2013-05-29 18:00:09 -07:00
|
|
|
# ==========
|
|
|
|
# = Deploy =
|
|
|
|
# ==========
|
|
|
|
|
|
|
|
@parallel
|
2020-12-05 14:42:20 -05:00
|
|
|
def pull(master=False):
|
2016-02-04 12:48:45 -08:00
|
|
|
with virtualenv():
|
2013-05-29 18:00:09 -07:00
|
|
|
run('git pull')
|
2020-12-05 14:42:20 -05:00
|
|
|
if master:
|
|
|
|
run('git checkout master')
|
|
|
|
run('git pull')
|
2013-05-29 18:00:09 -07:00
|
|
|
|
|
|
|
def pre_deploy():
|
|
|
|
compress_assets(bundle=True)
|
|
|
|
|
|
|
|
@serial
|
|
|
|
def post_deploy():
|
|
|
|
cleanup_assets()
|
|
|
|
|
2015-12-20 14:11:37 -08:00
|
|
|
def role_for_host():
|
|
|
|
for role, hosts in env.roledefs.items():
|
|
|
|
if env.host in hosts:
|
|
|
|
return role
|
|
|
|
|
2016-02-03 12:55:39 -08:00
|
|
|
@parallel
|
2014-12-30 14:40:06 -08:00
|
|
|
def deploy(fast=False, reload=False):
|
2015-12-20 14:11:37 -08:00
|
|
|
role = role_for_host()
|
2017-06-07 18:04:34 -07:00
|
|
|
if role in ['work', 'search', 'debug']:
|
2015-12-20 14:11:37 -08:00
|
|
|
deploy_code(copy_assets=False, fast=fast, reload=True)
|
|
|
|
else:
|
|
|
|
deploy_code(copy_assets=False, fast=fast, reload=reload)
|
2013-05-29 18:00:09 -07:00
|
|
|
|
|
|
|
@parallel
|
|
|
|
def deploy_web(fast=False):
|
2015-12-20 14:11:37 -08:00
|
|
|
role = role_for_host()
|
|
|
|
if role in ['work', 'search']:
|
|
|
|
deploy_code(copy_assets=True, fast=fast, reload=True)
|
|
|
|
else:
|
|
|
|
deploy_code(copy_assets=True, fast=fast)
|
2013-05-29 18:00:09 -07:00
|
|
|
|
|
|
|
@parallel
|
2015-12-20 14:11:37 -08:00
|
|
|
def deploy_rebuild(fast=False):
|
|
|
|
deploy_code(copy_assets=True, fast=fast, rebuild=True)
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2013-10-11 19:46:33 -07:00
|
|
|
@parallel
|
|
|
|
def kill_gunicorn():
|
2016-02-04 12:48:45 -08:00
|
|
|
with virtualenv():
|
2014-03-28 12:53:01 -07:00
|
|
|
sudo('pkill -9 -u %s -f gunicorn_django' % env.user)
|
2013-10-11 19:46:33 -07:00
|
|
|
|
2013-05-29 18:00:09 -07:00
|
|
|
@parallel
|
2015-12-20 14:11:37 -08:00
|
|
|
def deploy_code(copy_assets=False, rebuild=False, fast=False, reload=False):
|
2016-02-04 12:48:45 -08:00
|
|
|
with virtualenv():
|
2013-05-29 18:00:09 -07:00
|
|
|
run('git pull')
|
|
|
|
run('mkdir -p static')
|
2015-12-20 14:11:37 -08:00
|
|
|
if rebuild:
|
2013-05-29 18:00:09 -07:00
|
|
|
run('rm -fr static/*')
|
|
|
|
if copy_assets:
|
|
|
|
transfer_assets()
|
2015-05-06 19:22:53 -07:00
|
|
|
|
2018-02-26 18:07:13 -08:00
|
|
|
with virtualenv():
|
|
|
|
with settings(warn_only=True):
|
|
|
|
if reload:
|
|
|
|
sudo('supervisorctl reload')
|
|
|
|
elif fast:
|
|
|
|
kill_gunicorn()
|
|
|
|
else:
|
|
|
|
sudo('kill -HUP `cat /srv/newsblur/logs/gunicorn.pid`')
|
2013-05-29 18:00:09 -07:00
|
|
|
|
|
|
|
@parallel
|
|
|
|
def kill():
|
|
|
|
sudo('supervisorctl reload')
|
|
|
|
with settings(warn_only=True):
|
|
|
|
if env.user == 'ubuntu':
|
|
|
|
sudo('./utils/kill_gunicorn.sh')
|
|
|
|
else:
|
|
|
|
run('./utils/kill_gunicorn.sh')
|
|
|
|
|
2016-11-30 13:44:50 -08:00
|
|
|
@parallel
|
2013-05-29 18:00:09 -07:00
|
|
|
def deploy_node():
|
2016-11-30 13:44:50 -08:00
|
|
|
pull()
|
2016-02-04 12:48:45 -08:00
|
|
|
with virtualenv():
|
2013-05-29 18:00:09 -07:00
|
|
|
run('sudo supervisorctl restart node_unread')
|
2016-11-30 12:09:49 -08:00
|
|
|
run('sudo supervisorctl restart node_unread_ssl')
|
2013-05-29 18:00:09 -07:00
|
|
|
run('sudo supervisorctl restart node_favicons')
|
2019-04-13 19:48:17 -04:00
|
|
|
run('sudo supervisorctl restart node_text')
|
2013-05-29 18:00:09 -07:00
|
|
|
|
|
|
|
def gunicorn_restart():
|
|
|
|
restart_gunicorn()
|
|
|
|
|
|
|
|
def restart_gunicorn():
|
2016-02-04 12:48:45 -08:00
|
|
|
with virtualenv(), settings(warn_only=True):
|
2013-05-29 18:00:09 -07:00
|
|
|
run('sudo supervisorctl restart gunicorn')
|
|
|
|
|
|
|
|
def gunicorn_stop():
|
2016-02-04 12:48:45 -08:00
|
|
|
with virtualenv(), settings(warn_only=True):
|
2013-05-29 18:00:09 -07:00
|
|
|
run('sudo supervisorctl stop gunicorn')
|
|
|
|
|
|
|
|
def staging():
|
|
|
|
with cd('~/staging'):
|
|
|
|
run('git pull')
|
|
|
|
run('kill -HUP `cat logs/gunicorn.pid`')
|
|
|
|
run('curl -s http://dev.newsblur.com > /dev/null')
|
|
|
|
run('curl -s http://dev.newsblur.com/m/ > /dev/null')
|
|
|
|
|
2015-12-20 14:11:37 -08:00
|
|
|
def staging_build():
|
2013-05-29 18:00:09 -07:00
|
|
|
with cd('~/staging'):
|
|
|
|
run('git pull')
|
|
|
|
run('./manage.py migrate')
|
|
|
|
run('kill -HUP `cat logs/gunicorn.pid`')
|
|
|
|
run('curl -s http://dev.newsblur.com > /dev/null')
|
|
|
|
run('curl -s http://dev.newsblur.com/m/ > /dev/null')
|
|
|
|
|
2013-08-06 13:38:35 -07:00
|
|
|
@parallel
|
2013-05-29 18:00:09 -07:00
|
|
|
def celery():
|
|
|
|
celery_slow()
|
|
|
|
|
|
|
|
def celery_slow():
|
2016-02-04 12:48:45 -08:00
|
|
|
with virtualenv():
|
2013-05-29 18:00:09 -07:00
|
|
|
run('git pull')
|
|
|
|
celery_stop()
|
|
|
|
celery_start()
|
|
|
|
|
|
|
|
@parallel
|
|
|
|
def celery_fast():
|
2016-02-04 12:48:45 -08:00
|
|
|
with virtualenv():
|
2013-05-29 18:00:09 -07:00
|
|
|
run('git pull')
|
|
|
|
celery_reload()
|
|
|
|
|
|
|
|
@parallel
|
|
|
|
def celery_stop():
|
2016-02-04 12:48:45 -08:00
|
|
|
with virtualenv():
|
2013-05-29 18:00:09 -07:00
|
|
|
sudo('supervisorctl stop celery')
|
|
|
|
with settings(warn_only=True):
|
|
|
|
if env.user == 'ubuntu':
|
|
|
|
sudo('./utils/kill_celery.sh')
|
|
|
|
else:
|
|
|
|
run('./utils/kill_celery.sh')
|
|
|
|
|
|
|
|
@parallel
|
|
|
|
def celery_start():
|
2016-02-04 12:48:45 -08:00
|
|
|
with virtualenv():
|
2013-05-29 18:00:09 -07:00
|
|
|
run('sudo supervisorctl start celery')
|
|
|
|
run('tail logs/newsblur.log')
|
|
|
|
|
|
|
|
@parallel
|
|
|
|
def celery_reload():
|
2016-02-04 12:48:45 -08:00
|
|
|
with virtualenv():
|
2013-05-29 18:00:09 -07:00
|
|
|
run('sudo supervisorctl reload celery')
|
|
|
|
run('tail logs/newsblur.log')
|
|
|
|
|
|
|
|
def kill_celery():
|
2016-02-04 12:48:45 -08:00
|
|
|
with virtualenv():
|
2013-05-29 18:00:09 -07:00
|
|
|
with settings(warn_only=True):
|
|
|
|
if env.user == 'ubuntu':
|
|
|
|
sudo('./utils/kill_celery.sh')
|
|
|
|
else:
|
|
|
|
run('./utils/kill_celery.sh')
|
|
|
|
|
|
|
|
def compress_assets(bundle=False):
|
2020-11-13 11:02:27 -05:00
|
|
|
local('jammit -c newsblur/assets.yml --base-url https://www.newsblur.com --output static')
|
2013-05-29 18:00:09 -07:00
|
|
|
local('tar -czf static.tgz static/*')
|
2013-07-29 15:36:57 -07:00
|
|
|
|
|
|
|
tries_left = 5
|
|
|
|
while True:
|
|
|
|
try:
|
2013-07-30 17:20:13 -07:00
|
|
|
success = False
|
|
|
|
with settings(warn_only=True):
|
|
|
|
local('PYTHONPATH=/srv/newsblur python utils/backups/s3.py set static.tgz')
|
|
|
|
success = True
|
|
|
|
if not success:
|
|
|
|
raise Exception("Ack!")
|
2013-07-29 15:36:57 -07:00
|
|
|
break
|
|
|
|
except Exception, e:
|
|
|
|
print " ***> %s. Trying %s more time%s..." % (e, tries_left, '' if tries_left == 1 else 's')
|
|
|
|
tries_left -= 1
|
|
|
|
if tries_left <= 0: break
|
2013-06-11 19:58:21 -07:00
|
|
|
|
2013-05-29 18:00:09 -07:00
|
|
|
|
|
|
|
def transfer_assets():
|
2013-06-11 19:58:21 -07:00
|
|
|
# filename = "deploy_%s.tgz" % env.commit # Easy rollback? Eh, can just upload it again.
|
|
|
|
# run('PYTHONPATH=/srv/newsblur python s3.py get deploy_%s.tgz' % filename)
|
|
|
|
run('PYTHONPATH=/srv/newsblur python utils/backups/s3.py get static.tgz')
|
|
|
|
# run('mv %s static/static.tgz' % filename)
|
|
|
|
run('mv static.tgz static/static.tgz')
|
2013-05-29 18:00:09 -07:00
|
|
|
run('tar -xzf static/static.tgz')
|
|
|
|
run('rm -f static/static.tgz')
|
|
|
|
|
|
|
|
def cleanup_assets():
|
|
|
|
local('rm -f static.tgz')
|
|
|
|
|
|
|
|
# ===========
|
|
|
|
# = Backups =
|
|
|
|
# ===========
|
|
|
|
|
2015-03-09 14:50:07 -07:00
|
|
|
def setup_redis_backups(name=None):
|
2018-03-09 09:43:46 -08:00
|
|
|
# crontab for redis backups, name is either none, story, sessions, pubsub
|
2016-11-04 16:38:41 -07:00
|
|
|
crontab = ("0 4 * * * /srv/newsblur/venv/newsblur/bin/python /srv/newsblur/utils/backups/backup_redis%s.py" %
|
2015-03-09 14:50:07 -07:00
|
|
|
(("_%s"%name) if name else ""))
|
|
|
|
run('(crontab -l ; echo "%s") | sort - | uniq - | crontab -' % crontab)
|
|
|
|
run('crontab -l')
|
|
|
|
|
|
|
|
def setup_mongo_backups():
|
|
|
|
# crontab for mongo backups
|
2016-11-04 16:38:41 -07:00
|
|
|
crontab = "0 4 * * * /srv/newsblur/venv/newsblur/bin/python /srv/newsblur/utils/backups/backup_mongo.py"
|
2015-03-09 14:50:07 -07:00
|
|
|
run('(crontab -l ; echo "%s") | sort - | uniq - | crontab -' % crontab)
|
|
|
|
run('crontab -l')
|
|
|
|
|
|
|
|
def setup_postgres_backups():
|
|
|
|
# crontab for postgres backups
|
|
|
|
crontab = """
|
2016-11-04 16:38:41 -07:00
|
|
|
0 4 * * * /srv/newsblur/venv/newsblur/bin/python /srv/newsblur/utils/backups/backup_psql.py
|
2020-12-02 20:51:33 -05:00
|
|
|
0 * * * * sudo find /var/lib/postgresql/13/archive -mtime +1 -exec rm {} \;
|
|
|
|
0 * * * * sudo find /var/lib/postgresql/13/archive -type f -mmin +180 -delete"""
|
2015-03-09 14:50:07 -07:00
|
|
|
|
|
|
|
run('(crontab -l ; echo "%s") | sort - | uniq - | crontab -' % crontab)
|
|
|
|
run('crontab -l')
|
|
|
|
|
|
|
|
def backup_redis(name=None):
|
2016-11-04 16:38:41 -07:00
|
|
|
run('/srv/newsblur/venv/newsblur/bin/python /srv/newsblur/utils/backups/backup_redis%s.py' % (("_%s"%name) if name else ""))
|
2015-03-09 14:50:07 -07:00
|
|
|
|
2013-05-29 18:00:09 -07:00
|
|
|
def backup_mongo():
|
2016-11-04 16:38:41 -07:00
|
|
|
run('/srv/newsblur/venv/newsblur/bin/python /srv/newsblur/utils/backups/backup_mongo.py')
|
2013-05-29 18:00:09 -07:00
|
|
|
|
|
|
|
def backup_postgresql():
|
2016-11-04 16:38:41 -07:00
|
|
|
run('/srv/newsblur/venv/newsblur/bin/python /srv/newsblur/utils/backups/backup_psql.py')
|
2013-05-29 18:00:09 -07:00
|
|
|
|
|
|
|
# ===============
|
|
|
|
# = Calibration =
|
|
|
|
# ===============
|
|
|
|
|
|
|
|
def sync_time():
|
|
|
|
with settings(warn_only=True):
|
|
|
|
sudo("/etc/init.d/ntp stop")
|
|
|
|
sudo("ntpdate pool.ntp.org")
|
|
|
|
sudo("/etc/init.d/ntp start")
|
|
|
|
|
|
|
|
def setup_time_calibration():
|
|
|
|
sudo('apt-get -y install ntp')
|
|
|
|
put('config/ntpdate.cron', '%s/' % env.NEWSBLUR_PATH)
|
|
|
|
sudo('chown root.root %s/ntpdate.cron' % env.NEWSBLUR_PATH)
|
|
|
|
sudo('chmod 755 %s/ntpdate.cron' % env.NEWSBLUR_PATH)
|
|
|
|
sudo('mv %s/ntpdate.cron /etc/cron.hourly/ntpdate' % env.NEWSBLUR_PATH)
|
|
|
|
with settings(warn_only=True):
|
|
|
|
sudo('/etc/cron.hourly/ntpdate')
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2012-05-03 18:33:29 -07:00
|
|
|
# ==============
|
|
|
|
# = Tasks - DB =
|
|
|
|
# ==============
|
|
|
|
|
2020-12-02 20:51:33 -05:00
|
|
|
def restore_postgres(port=5432, download=False):
|
|
|
|
with virtualenv():
|
2020-12-02 22:19:11 -05:00
|
|
|
backup_date = '2020-12-03-02-51'
|
2020-12-02 20:51:33 -05:00
|
|
|
yes = prompt("Dropping and creating NewsBlur PGSQL db. Sure?")
|
|
|
|
if yes != 'y':
|
|
|
|
return
|
|
|
|
if download:
|
|
|
|
run('mkdir -p postgres')
|
|
|
|
run('PYTHONPATH=%s python utils/backups/s3.py get postgres/backup_postgresql_%s.sql.gz' % (env.NEWSBLUR_PATH, backup_date))
|
|
|
|
# sudo('su postgres -c "createuser -p %s -U newsblur"' % (port,))
|
|
|
|
with settings(warn_only=True):
|
|
|
|
# May not exist
|
|
|
|
run('dropdb newsblur -p %s -U newsblur' % (port,), pty=False)
|
|
|
|
run('sudo -u postgres createuser newsblur -s')
|
|
|
|
# May already exist
|
|
|
|
run('createdb newsblur -p %s -O newsblur -U newsblur' % (port,), pty=False)
|
|
|
|
run('pg_restore -U newsblur -p %s --role=newsblur --dbname=newsblur /srv/newsblur/postgres/backup_postgresql_%s.sql.gz' % (port, backup_date), pty=False)
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2020-11-12 10:11:56 -05:00
|
|
|
def restore_mongo(download=False):
|
|
|
|
backup_date = '2020-11-11-04-00'
|
|
|
|
if download:
|
|
|
|
run('PYTHONPATH=/srv/newsblur python utils/backups/s3.py get backup_mongo_%s.tgz' % (backup_date))
|
2012-07-24 23:36:20 -07:00
|
|
|
run('tar -xf backup_mongo_%s.tgz' % backup_date)
|
|
|
|
run('mongorestore backup_mongo_%s' % backup_date)
|
2013-05-08 01:59:33 -07:00
|
|
|
|
2010-12-15 22:26:05 -05:00
|
|
|
# ======
|
|
|
|
# = S3 =
|
|
|
|
# ======
|
2010-09-08 18:30:33 -07:00
|
|
|
|
2011-07-17 11:31:07 -07:00
|
|
|
if django_settings:
|
2011-07-17 15:30:25 -07:00
|
|
|
try:
|
|
|
|
ACCESS_KEY = django_settings.S3_ACCESS_KEY
|
|
|
|
SECRET = django_settings.S3_SECRET
|
|
|
|
BUCKET_NAME = django_settings.S3_BACKUP_BUCKET # Note that you need to create this bucket first
|
|
|
|
except:
|
|
|
|
print " ---> You need to fix django's settings. Enter python and type `import settings`."
|
2010-09-08 18:30:33 -07:00
|
|
|
|
2010-12-15 22:26:05 -05:00
|
|
|
def save_file_in_s3(filename):
|
|
|
|
conn = S3Connection(ACCESS_KEY, SECRET)
|
|
|
|
bucket = conn.get_bucket(BUCKET_NAME)
|
|
|
|
k = Key(bucket)
|
|
|
|
k.key = filename
|
2010-07-30 23:50:49 -04:00
|
|
|
|
2010-12-15 22:26:05 -05:00
|
|
|
k.set_contents_from_filename(filename)
|
2010-07-30 23:50:49 -04:00
|
|
|
|
2010-12-15 22:26:05 -05:00
|
|
|
def get_file_from_s3(filename):
|
|
|
|
conn = S3Connection(ACCESS_KEY, SECRET)
|
|
|
|
bucket = conn.get_bucket(BUCKET_NAME)
|
|
|
|
k = Key(bucket)
|
|
|
|
k.key = filename
|
2010-09-08 18:30:33 -07:00
|
|
|
|
2010-12-15 22:26:05 -05:00
|
|
|
k.get_contents_to_filename(filename)
|
2010-09-08 18:30:33 -07:00
|
|
|
|
2010-12-15 22:26:05 -05:00
|
|
|
def list_backup_in_s3():
|
|
|
|
conn = S3Connection(ACCESS_KEY, SECRET)
|
|
|
|
bucket = conn.get_bucket(BUCKET_NAME)
|
2010-09-08 18:30:33 -07:00
|
|
|
|
2010-12-15 22:26:05 -05:00
|
|
|
for i, key in enumerate(bucket.get_all_keys()):
|
|
|
|
print "[%s] %s" % (i, key.name)
|
2010-09-08 18:30:33 -07:00
|
|
|
|
2010-12-15 22:26:05 -05:00
|
|
|
def delete_all_backups():
|
|
|
|
#FIXME: validate filename exists
|
|
|
|
conn = S3Connection(ACCESS_KEY, SECRET)
|
|
|
|
bucket = conn.get_bucket(BUCKET_NAME)
|
2010-09-08 18:30:33 -07:00
|
|
|
|
2010-12-15 22:26:05 -05:00
|
|
|
for i, key in enumerate(bucket.get_all_keys()):
|
|
|
|
print "deleting %s" % (key.name)
|
2013-03-20 12:24:36 -07:00
|
|
|
key.delete()
|
|
|
|
|
|
|
|
def add_revsys_keys():
|
|
|
|
put("~/Downloads/revsys-keys.pub", "revsys_keys")
|
|
|
|
run('cat revsys_keys >> ~/.ssh/authorized_keys')
|
|
|
|
run('rm revsys_keys')
|
2016-02-05 16:58:08 -08:00
|
|
|
|
2016-02-09 09:52:09 -08:00
|
|
|
def upgrade_to_virtualenv(role=None):
|
|
|
|
if not role:
|
|
|
|
print " ---> You must specify a role!"
|
|
|
|
return
|
2016-02-05 17:35:12 -08:00
|
|
|
setup_virtualenv()
|
2016-02-09 13:43:21 -08:00
|
|
|
if role == "task" or role == "search":
|
2016-02-05 16:58:08 -08:00
|
|
|
celery_stop()
|
2016-02-05 18:27:06 -08:00
|
|
|
elif role == "app":
|
|
|
|
gunicorn_stop()
|
2016-11-03 17:30:24 -07:00
|
|
|
elif role == "node":
|
|
|
|
run('sudo supervisorctl stop node_unread')
|
|
|
|
run('sudo supervisorctl stop node_favicons')
|
2016-02-09 16:22:34 -08:00
|
|
|
elif role == "work":
|
|
|
|
sudo('/etc/init.d/supervisor stop')
|
2016-10-14 11:24:42 -07:00
|
|
|
kill_pgbouncer(bounce=False)
|
2016-02-05 16:58:08 -08:00
|
|
|
setup_installs()
|
|
|
|
pip()
|
|
|
|
if role == "task":
|
2016-02-09 09:52:09 -08:00
|
|
|
enable_celery_supervisor(update=False)
|
2016-02-05 18:27:06 -08:00
|
|
|
sudo('reboot')
|
|
|
|
elif role == "app":
|
2016-02-09 09:52:09 -08:00
|
|
|
setup_gunicorn(supervisor=True, restart=False)
|
2016-02-09 13:43:21 -08:00
|
|
|
sudo('reboot')
|
2016-11-03 17:30:24 -07:00
|
|
|
elif role == "node":
|
|
|
|
deploy_node()
|
2016-02-09 13:43:21 -08:00
|
|
|
elif role == "search":
|
2016-02-09 16:22:34 -08:00
|
|
|
setup_db_search()
|
|
|
|
elif role == "work":
|
|
|
|
enable_celerybeat()
|
2016-05-23 19:28:01 -07:00
|
|
|
sudo('reboot')
|
|
|
|
|
2016-10-09 09:50:52 -07:00
|
|
|
def benchmark():
|
2020-12-02 20:51:33 -05:00
|
|
|
run('curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.deb.sh | sudo bash')
|
2016-05-23 19:28:01 -07:00
|
|
|
sudo('apt-get install -y sysbench')
|
2020-12-02 20:51:33 -05:00
|
|
|
run('sysbench cpu --cpu-max-prime=20000 run')
|
|
|
|
run('sysbench fileio --file-total-size=150G prepare')
|
|
|
|
run('sysbench fileio --file-total-size=150G --file-test-mode=rndrw --time=300 --max-requests=0 run')
|
|
|
|
run('sysbench fileio --file-total-size=150G cleanup')
|