-
Notifications
You must be signed in to change notification settings - Fork 1
/
commands.py
169 lines (130 loc) · 5.01 KB
/
commands.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
import datetime
import os
import shutil
import tarfile
from runcommands import command
from runcommands.commands import copy_file, local, remote, show_config # noqa
from runcommands.util import abort, printer
from tangled.commands import *
# Deployment -----------------------------------------------------------
@command(env=True, config={
'defaults.remote.run_as': '${deploy.user}',
})
def deploy(config, version=None, overwrite=False, overwrite_venv=False, install=True, push=True,
link=True, reload=True):
# Setup ----------------------------------------------------------
if version:
config = config.copy(version=version)
elif config.get('version'):
printer.info('Using default version:', config.version)
else:
abort(1, 'Version must be specified via config or passed as an option')
# Local ----------------------------------------------------------
build_dir = config.build.dir
if overwrite and os.path.exists(build_dir):
shutil.rmtree(build_dir)
os.makedirs(build_dir, exist_ok=True)
# Add config files
copy_file(config, 'application.wsgi', build_dir, template=True)
copy_file(config, 'base.ini', build_dir)
copy_file(config, '{env}.ini', build_dir, template=True)
copy_file(config, 'commands.py', build_dir)
copy_file(config, 'commands.cfg', build_dir)
# Create source distributions
dist_dir = os.path.abspath(config.build.dist_dir)
sdist_command = ('python setup.py sdist --dist-dir', dist_dir)
local(config, sdist_command, hide='stdout')
for path in config.deploy.sdists:
local(config, sdist_command, hide='stdout', cd=path)
tarball_name = '{config.version}.tar.gz'.format(config=config)
tarball_path = os.path.join(build_dir, tarball_name)
with tarfile.open(tarball_path, 'w:gz') as tarball:
tarball.add(build_dir, config.version)
if push:
local(config, (
'rsync -rltvz',
'--rsync-path "sudo -u {deploy.user} rsync"',
tarball_path, '{remote.host}:{deploy.root}',
))
# Remote ----------------------------------------------------------
deploy_dir_exists = remote(config, 'test -d {deploy.dir}', abort_on_failure=False)
if deploy_dir_exists and overwrite:
remote(config, 'rm -r {deploy.dir}')
remote(config, ('tar -xvzf', tarball_name), cd='{deploy.root}')
# Create virtualenv for this version
venv_exists = remote(config, 'test -d {deploy.venv}', abort_on_failure=False)
if venv_exists and overwrite_venv:
remote(config, 'rm -r {deploy.venv}')
venv_exists = False
if not venv_exists:
remote(config, (
'python{python.version} -m venv {deploy.venv} &&',
'{deploy.pip.exe} install',
'--cache-dir {deploy.pip.cache_dir}',
'--upgrade setuptools pip wheel',
))
# Build source
if install:
remote(config, (
'{deploy.pip.exe}',
'install',
'--find-links {deploy.pip.find_links}',
'--cache-dir {deploy.pip.cache_dir}',
'--disable-pip-version-check',
'{package}',
), cd='{deploy.root}', timeout=120)
# Make this version the current version
if link:
remote(config, 'ln -sfn {deploy.dir} {deploy.link}')
# Set permissions
remote(config, 'chmod -R ug=rwX,o= {deploy.root}')
if reload:
reload_uwsgi(config)
@command(default_env='production')
def backup_db(config):
date = datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
path = '../tangled.website-{date}.db'.format(date=date)
local(config, (
'rsync',
'--rsync-path "sudo -u {deploy.user} rsync"',
'{remote.host}:{deploy.root}/site.db',
path,
))
printer.success('Saved copy of', config.env, 'database to', path)
# Services --------------------------------------------------------
@command(env=True, config={
'defaults.remote.run_as': None,
'defaults.remote.sudo': True,
})
def push_apache_config(config, enable=True):
local(config, (
'rsync -rltvz',
'--rsync-path "sudo rsync"',
'etc/apache2/', '{remote.host}:/etc/apache2',
))
if enable:
remote(config, 'a2ensite {domain_name}')
@command(env=True, config={
'defaults.remote.run_as': None,
'defaults.remote.sudo': True,
})
def push_uwsgi_config(config, enable=True):
"""Push uWSGI app config."""
file = config.deploy.uwsgi.config_file
link = config.deploy.uwsgi.config_link
local(config, (
'rsync -rltvz',
'--rsync-path "sudo rsync"',
file.lstrip('/'), ':'.join((config.remote.host, file)),
))
if enable:
remote(config, ('ln -sf', file, link), run_as=None, sudo=True)
@command(env=True, config={
'defaults.remote.run_as': '${deploy.user}',
})
def reload_uwsgi(config):
"""Restart uWSGI app process.
The uWSGI app process needs to be reloaded after deploying a new
version.
"""
remote(config, '/usr/bin/uwsgi --reload /run/uwsgi/app/tangled/pid')