mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
287 lines
8.4 KiB
Python
287 lines
8.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""A Fabric fabfile with functionality to prepare, install, and configure
|
|
BigchainDB, including its storage backend (RethinkDB).
|
|
"""
|
|
|
|
from __future__ import with_statement, unicode_literals
|
|
|
|
from os import environ # a mapping (like a dict)
|
|
import sys
|
|
|
|
from fabric.api import sudo, env, hosts
|
|
from fabric.api import task, parallel
|
|
from fabric.contrib.files import sed
|
|
from fabric.operations import run, put
|
|
from fabric.context_managers import settings
|
|
|
|
from hostlist import public_dns_names
|
|
|
|
# Ignore known_hosts
|
|
# http://docs.fabfile.org/en/1.10/usage/env.html#disable-known-hosts
|
|
env.disable_known_hosts = True
|
|
|
|
# What remote servers should Fabric connect to? With what usernames?
|
|
env.user = 'ubuntu'
|
|
env.hosts = public_dns_names
|
|
|
|
# SSH key files to try when connecting:
|
|
# http://docs.fabfile.org/en/1.10/usage/env.html#key-filename
|
|
env.key_filename = 'pem/bigchaindb.pem'
|
|
|
|
|
|
######################################################################
|
|
|
|
# DON'T PUT @parallel
|
|
@task
|
|
def set_host(host_index):
|
|
"""A helper task to change env.hosts from the
|
|
command line. It will only "stick" for the duration
|
|
of the fab command that called it.
|
|
|
|
Args:
|
|
host_index (int): 0, 1, 2, 3, etc.
|
|
Example:
|
|
fab set_host:4 fab_task_A fab_task_B
|
|
will set env.hosts = [public_dns_names[4]]
|
|
but only for doing fab_task_A and fab_task_B
|
|
"""
|
|
env.hosts = [public_dns_names[int(host_index)]]
|
|
|
|
|
|
# Install base software
|
|
@task
|
|
@parallel
|
|
def install_base_software():
|
|
# new from Troy April 5, 2016. Why? See http://tinyurl.com/lccfrsj
|
|
# sudo('rm -rf /var/lib/apt/lists/*')
|
|
# sudo('apt-get -y clean')
|
|
# from before:
|
|
sudo('apt-get -y update')
|
|
sudo('dpkg --configure -a')
|
|
sudo('apt-get -y -f install')
|
|
sudo('apt-get -y install build-essential wget bzip2 ca-certificates \
|
|
libglib2.0-0 libxext6 libsm6 libxrender1 \
|
|
git gcc g++ python3-dev libboost-python-dev \
|
|
software-properties-common python-software-properties \
|
|
python3-setuptools ipython3 sysstat s3cmd')
|
|
sudo('easy_install3 pip')
|
|
sudo('pip3 install --upgrade pip wheel setuptools')
|
|
|
|
|
|
# Install RethinkDB
|
|
@task
|
|
@parallel
|
|
def install_rethinkdb():
|
|
"""Installation of RethinkDB"""
|
|
with settings(warn_only=True):
|
|
# preparing filesystem
|
|
sudo("mkdir -p /data")
|
|
# Locally mounted storage (m3.2xlarge, but also c3.xxx)
|
|
try:
|
|
sudo("umount /mnt")
|
|
sudo("mkfs -t ext4 /dev/xvdb")
|
|
sudo("mount /dev/xvdb /data")
|
|
except:
|
|
pass
|
|
|
|
# persist settings to fstab
|
|
sudo("rm -rf /etc/fstab")
|
|
sudo("echo 'LABEL=cloudimg-rootfs / ext4 defaults,discard 0 0' >> /etc/fstab")
|
|
sudo("echo '/dev/xvdb /data ext4 defaults,noatime 0 0' >> /etc/fstab")
|
|
# activate deadline scheduler
|
|
with settings(sudo_user='root'):
|
|
sudo("echo deadline > /sys/block/xvdb/queue/scheduler")
|
|
# install rethinkdb
|
|
sudo("echo 'deb http://download.rethinkdb.com/apt trusty main' | sudo tee /etc/apt/sources.list.d/rethinkdb.list")
|
|
sudo("wget -qO- http://download.rethinkdb.com/apt/pubkey.gpg | sudo apt-key add -")
|
|
sudo("apt-get update")
|
|
sudo("apt-get -y install rethinkdb")
|
|
# change fs to user
|
|
sudo('chown -R rethinkdb:rethinkdb /data')
|
|
# copy config file to target system
|
|
put('conf/rethinkdb.conf',
|
|
'/etc/rethinkdb/instances.d/instance1.conf',
|
|
mode=0600,
|
|
use_sudo=True)
|
|
# initialize data-dir
|
|
sudo('rm -rf /data/*')
|
|
# finally restart instance
|
|
sudo('/etc/init.d/rethinkdb restart')
|
|
|
|
|
|
# Install BigchainDB from PyPI
|
|
@task
|
|
@parallel
|
|
def install_bigchaindb_from_pypi():
|
|
sudo('pip3 install bigchaindb')
|
|
|
|
|
|
# Install BigchainDB from a Git archive file
|
|
# named bigchaindb-archive.tar.gz
|
|
@task
|
|
@parallel
|
|
def install_bigchaindb_from_git_archive():
|
|
put('bigchaindb-archive.tar.gz')
|
|
run('tar xvfz bigchaindb-archive.tar.gz')
|
|
sudo('pip3 install .')
|
|
# sudo('python3 setup.py install')
|
|
run('rm bigchaindb-archive.tar.gz')
|
|
|
|
|
|
# Configure BigchainDB
|
|
@task
|
|
@parallel
|
|
def configure_bigchaindb():
|
|
run('bigchaindb -y configure', pty=False)
|
|
|
|
|
|
# Send the specified configuration file to
|
|
# the remote host and save it there in
|
|
# ~/.bigchaindb
|
|
# Use in conjunction with set_host()
|
|
# No @parallel
|
|
@task
|
|
def send_confile(confile):
|
|
put('confiles/' + confile, 'tempfile')
|
|
run('mv tempfile ~/.bigchaindb')
|
|
print('For this node, bigchaindb show-config says:')
|
|
run('bigchaindb show-config')
|
|
|
|
|
|
@task
|
|
@parallel
|
|
def send_client_confile(confile):
|
|
put(confile, 'tempfile')
|
|
run('mv tempfile ~/.bigchaindb')
|
|
print('For this node, bigchaindb show-config says:')
|
|
run('bigchaindb show-config')
|
|
|
|
|
|
# Initialize BigchainDB
|
|
# i.e. create the database, the tables,
|
|
# the indexes, and the genesis block.
|
|
# (The @hosts decorator is used to make this
|
|
# task run on only one node. See http://tinyurl.com/h9qqf3t )
|
|
@task
|
|
@hosts(public_dns_names[0])
|
|
def init_bigchaindb():
|
|
run('bigchaindb init', pty=False)
|
|
|
|
|
|
# Set the number of shards (in the backlog and bigchain tables)
|
|
@task
|
|
@hosts(public_dns_names[0])
|
|
def set_shards(num_shards):
|
|
run('bigchaindb set-shards {}'.format(num_shards))
|
|
|
|
|
|
# Start BigchainDB using screen
|
|
@task
|
|
@parallel
|
|
def start_bigchaindb():
|
|
sudo('screen -d -m bigchaindb -y start &', pty=False)
|
|
|
|
|
|
@task
|
|
@parallel
|
|
def start_bigchaindb_load():
|
|
sudo('screen -d -m bigchaindb load &', pty=False)
|
|
|
|
|
|
# Install and run New Relic
|
|
@task
|
|
@parallel
|
|
def install_newrelic():
|
|
newrelic_license_key = environ.get('NEWRELIC_KEY')
|
|
if newrelic_license_key is None:
|
|
sys.exit('The NEWRELIC_KEY environment variable is not set')
|
|
else:
|
|
# Andreas had this "with settings(..." line, but I'm not sure why:
|
|
# with settings(warn_only=True):
|
|
# Use the installation instructions from NewRelic:
|
|
# http://tinyurl.com/q9kyrud
|
|
# ...with some modifications
|
|
sudo("echo 'deb http://apt.newrelic.com/debian/ newrelic non-free' >> "
|
|
"/etc/apt/sources.list.d/newrelic.list")
|
|
sudo('wget -O- https://download.newrelic.com/548C16BF.gpg | '
|
|
'apt-key add -')
|
|
sudo('apt-get update')
|
|
sudo('apt-get -y --force-yes install newrelic-sysmond')
|
|
sudo('nrsysmond-config --set license_key=' + newrelic_license_key)
|
|
sudo('/etc/init.d/newrelic-sysmond start')
|
|
|
|
|
|
###########################
|
|
# Security / Firewall Stuff
|
|
###########################
|
|
|
|
@task
|
|
def harden_sshd():
|
|
"""Security harden sshd.
|
|
"""
|
|
# Disable password authentication
|
|
sed('/etc/ssh/sshd_config',
|
|
'#PasswordAuthentication yes',
|
|
'PasswordAuthentication no',
|
|
use_sudo=True)
|
|
# Deny root login
|
|
sed('/etc/ssh/sshd_config',
|
|
'PermitRootLogin yes',
|
|
'PermitRootLogin no',
|
|
use_sudo=True)
|
|
|
|
|
|
@task
|
|
def disable_root_login():
|
|
"""Disable `root` login for even more security. Access to `root` account
|
|
is now possible by first connecting with your dedicated maintenance
|
|
account and then running ``sudo su -``.
|
|
"""
|
|
sudo('passwd --lock root')
|
|
|
|
|
|
@task
|
|
def set_fw():
|
|
# snmp
|
|
sudo('iptables -A INPUT -p tcp --dport 161 -j ACCEPT')
|
|
sudo('iptables -A INPUT -p udp --dport 161 -j ACCEPT')
|
|
# dns
|
|
sudo('iptables -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT')
|
|
sudo('iptables -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT')
|
|
# rethinkdb
|
|
sudo('iptables -A INPUT -p tcp --dport 28015 -j ACCEPT')
|
|
sudo('iptables -A INPUT -p udp --dport 28015 -j ACCEPT')
|
|
sudo('iptables -A INPUT -p tcp --dport 29015 -j ACCEPT')
|
|
sudo('iptables -A INPUT -p udp --dport 29015 -j ACCEPT')
|
|
sudo('iptables -A INPUT -p tcp --dport 8080 -j ACCEPT')
|
|
sudo('iptables -A INPUT -i eth0 -p tcp --dport 8080 -j DROP')
|
|
sudo('iptables -I INPUT -i eth0 -s 127.0.0.1 -p tcp --dport 8080 -j ACCEPT')
|
|
# save rules
|
|
sudo('iptables-save > /etc/sysconfig/iptables')
|
|
|
|
|
|
#########################################################
|
|
# Some helper-functions to handle bad behavior of cluster
|
|
#########################################################
|
|
|
|
# rebuild indexes
|
|
@task
|
|
@parallel
|
|
def rebuild_indexes():
|
|
run('rethinkdb index-rebuild -n 2')
|
|
|
|
|
|
@task
|
|
def stopdb():
|
|
sudo('service rethinkdb stop')
|
|
|
|
|
|
@task
|
|
def startdb():
|
|
sudo('service rethinkdb start')
|
|
|
|
|
|
@task
|
|
def restartdb():
|
|
sudo('/etc/init.d/rethinkdb restart')
|