Skip to content

Instantly share code, notes, and snippets.

@hiczlf
Last active August 29, 2015 14:17
Show Gist options
  • Save hiczlf/517b2f9082d08afc5c4c to your computer and use it in GitHub Desktop.
Save hiczlf/517b2f9082d08afc5c4c to your computer and use it in GitHub Desktop.
fabric django uwsgi nginx
#!/usr/bin/env python
# -*-coding: utf-8 -*-
import os
import uuid
import re
from os import stat
from pwd import getpwuid
from fabric.api import env, local, run, sudo, cd, put, get, parallel
from fabric.colors import green
from fabric.contrib.files import exists
# ################# 设置 #########################
# 阿里云的机器
host_dict = {
'ip1': 'hostname1',
'ip2': 'hostname1',
}
env.hosts = host_dict.keys()
# 用户名密码, 应该专门设置DC专用用户,不再使用root
env.user = 'username'
env.password = 'password'
svn_auth = '--username username --password password'
APT_GET_PACKAGES = [
'build-essential',
'python-dev',
'python-pip',
'subversion',
'vim',
'nginx',
# MySQL-python 依赖该包
'libmysqlclient-dev',
'memcached',
]
SYS_PYTHON_PACKAGES = [
'virtualenv',
]
# 部署路径
PROJECT_NAME = 'dc'
PROJECT_PATH = '/var/www/{0}'.format(PROJECT_NAME)
# ################# 程序 #######################
def replace_or_append_in_file(file, search_exp, replace):
if not os.path.exists(file):
fp = open(file, 'w')
fp.close()
with open(file, "r") as f_read:
contents = f_read.read()
if re.search(search_exp, contents):
contents = re.sub(search_exp, replace, contents, 1)
else:
contents += replace
with open(file, 'w') as f_write:
f_write.write(contents)
def find_owner(filename):
return getpwuid(stat(filename).st_uid).pw_name
def _get_public_key():
"""
生成ssh key 到指定机器上,不再需要用密码登陆
"""
id_ras_pub_path = os.path.expanduser('~/.ssh/id_rsa.pub')
# 如果是不存在rsa pub key, 则创建
if not os.path.exists(id_ras_pub_path):
print('need create id_rsa_pub')
local('ssh-keygen -t rsa')
with open(id_ras_pub_path) as fd:
key = fd.readline().strip()
return key
def add_key():
print(green("set ssh key"))
current_user = find_owner(__file__)
command = "sudo -H -u %s bash -c 'ssh-keygen -R %s'" % (
current_user, host_dict[env.host])
local(command)
SSH_HOME = "~/.ssh"
AUTH_KEYS_PATH = "~/.ssh/authorized_keys"
run("mkdir -p %s" % SSH_HOME)
run("chmod 700 %s" % SSH_HOME)
run("grep '%s' %s && echo 'success' || echo '%s' >> %s;" % (
_get_public_key(), AUTH_KEYS_PATH,
_get_public_key(), AUTH_KEYS_PATH)
)
run("chmod 644 %s" % AUTH_KEYS_PATH)
def set_hostname():
print(green("set hostname"))
hostname_new = host_dict[env.host]
# 更改远程机器的/etc/hosts, 域名解析
hostname_old = run("hostname").strip()
remote_hosts_path = '/etc/hosts'
local_hosts_path = '/tmp/' + str(uuid.uuid4())
get(remote_hosts_path, local_hosts_path)
with open(local_hosts_path, "r") as f_read:
contents = f_read.read()
contents = contents.replace(hostname_old, hostname_new)
with open(local_hosts_path, 'w') as f_write:
f_write.write(contents)
put(local_hosts_path, '/tmp/hosts')
sudo("mv /tmp/hosts /etc/hosts")
# 更改远程机器hostname
sudo("hostname {0}".format(hostname_new))
sudo('echo {0} > /etc/hostname'.format(hostname_new))
# 更改本地域名解析
# local('echo "{0} {1}" | sudo tee -a /etc/hosts > /dev/null'.format(
# env.host, hostname_new), capture=True)
hosts_search_exp = re.compile(r'[^\n]*\s%s\s*\n' % hostname_new)
replace_or_append_in_file('/etc/hosts', hosts_search_exp,
'%s %s\n' % (env.host, hostname_new))
replace_or_append_in_file(os.path.expanduser('~/.ssh/config'),
r'HOST\s+%s\n\s+USER root' % hostname_new,
'HOST %s\n USER root\n' % hostname_new)
# 默认使用root连接所配置的机器, 每次少打几个字, 以后在考虑不用root问题吧
# local('echo "HOST {0}; USER root;" | tr ";" "\n" | sudo tee -a ~/.ssh/config > /dev/null'.format(hostname_new))
def install_sys_software():
"""为dc安装默认软件"""
print(green("Install sys software"))
sudo("apt-get update")
sudo("apt-get -y install " + " ".join(APT_GET_PACKAGES))
sudo("pip install -U " + " ".join(SYS_PYTHON_PACKAGES))
def create_project_structure():
print(green("Creating directory structure in %s" % PROJECT_PATH))
sudo("mkdir -p {0}".format(PROJECT_PATH))
with cd(PROJECT_PATH):
sudo("mkdir -p conf src logs/nginx logs/uwsgi run")
sudo("rm -rf icbase")
run("svn checkout --non-interactive {0} svn:repository icbase".format(svn_auth))
sudo("chown -R {0} {1}".format('www-data:www-data', PROJECT_PATH))
def create_virtualenv():
print(green("Creating virtualenv"))
with cd(PROJECT_PATH):
if not exists("virtualenv"):
run("mkdir -p virtualenv")
run("virtualenv ./virtualenv")
def install_requirements():
print(green("install requirements in virtualenv"))
with cd(PROJECT_PATH):
run("virtualenv/bin/pip install -r icbase/requirements.txt", shell=False)
def collect_static():
with cd(PROJECT_PATH):
with cd('icbase'):
run("../virtualenv/bin/python manage.py collectstatic --noinput")
sudo("chown -R {0} {1}".format('www-data:www-data', PROJECT_PATH))
def configure_nginx():
print(green("Configure nginx"))
# 如果是阿里转发主机,额外设置nginx配置文件
if host_dict[env.host] == 'ali-master':
put("deploy/conf/ali_master_dc.conf", "/tmp/master_dc.conf")
sudo("mv /tmp/master_dc.conf {0}/conf/master_dc.conf".format(PROJECT_PATH))
sudo("rm -f /etc/nginx/sites-enabled/master_dc.conf")
sudo("ln -s {0}/conf/master_dc.conf /etc/nginx/sites-enabled/master_dc.conf".format(PROJECT_PATH))
put("deploy/conf/dc.conf", "/tmp/dc.conf")
put("deploy/conf/nginx.conf", "/tmp/nginx.conf")
sudo("mv /tmp/nginx.conf {0}/conf/nginx.conf".format(PROJECT_PATH))
sudo("mv /tmp/dc.conf {0}/conf/dc.conf".format(PROJECT_PATH))
sudo("rm -f /etc/nginx/sites-enabled/dc.conf")
sudo("rm -f /etc/nginx/nginx.conf")
sudo("ln -s {0}/conf/nginx.conf /etc/nginx/nginx.conf".format(PROJECT_PATH))
sudo("ln -s {0}/conf/dc.conf /etc/nginx/sites-enabled/dc.conf".format(PROJECT_PATH))
sudo("service nginx restart")
def configure_uwsgi():
print(green("Configure uwsgi"))
put("deploy/conf/uwsgi.conf", "/tmp/uwsgi.conf")
sudo("mv /tmp/uwsgi.conf /etc/init/")
with cd(PROJECT_PATH):
run('virtualenv/bin/pip install uwsgi', shell=False)
run('touch {0}/run/uwsgi.pid'.format(PROJECT_PATH))
sudo("service uwsgi restart")
def remove_memcache():
sudo("apt-get -y remove memcached")
# 如果并行的话, 有多个线程写同一文件风险,
# 次处很少执行, 故没有处理该问题, 只是不并发执行
def setup():
add_key()
set_hostname()
# install_sys_software()
# create_project_structure()
# create_virtualenv()
# install_requirements()
# collect_static()
# configure_nginx()
# configure_uwsgi()
@parallel
def update():
with cd(PROJECT_PATH):
with cd('icbase'):
sudo("svn revert {0} --non-interactive -R .".format(svn_auth))
sudo("svn update {0} --non-interactive".format(svn_auth))
run("../virtualenv/bin/python manage.py collectstatic --noinput")
sudo("service uwsgi reload")
sudo("service nginx reload")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment