-
Notifications
You must be signed in to change notification settings - Fork 2
/
fabfile.py
206 lines (162 loc) · 4.74 KB
/
fabfile.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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
"""
Install and deploy projects on Opalstack (and others). Uses Fabric 2+.
See https://github.com/fabric/fabric
"""
from invoke import Collection
from fabric import task, Connection
from tasks._constants import *
from tasks import (control, server, user, application, python, supervisor,
virtual_env, project, database, redis, config)
DEFAULT_CONFIG = {
'inline_ssh_env': True,
'run': {
'env': {
'PATH': '$HOME/bin:$PATH',
}
},
'project': {
'name': 'project',
'local': '.',
},
'data': {},
'archive_excludes': ['__pycache__', '.DS_Store'],
}
def execute_tasks(c, tasks):
# note: this seems silly, fabric has a tasks executor, but what about 'c'?
# also: instead of 'return' (exit on error) use 'continue' (on error)? use command-arg?
for t in tasks:
try:
print(f'\n------------------------------------------------------')
print(f'{YELLOW}Executing {t.__module__}.{t.__name__}{COL_END}\n')
result = t(c)
except Exception as e:
print(f'{RED}{e}{COL_END}')
return
else:
if not result:
return
elif isinstance(result, Connection):
c = result
return c
def pretty_print(c):
import json
print(f'{GREEN}Successfully installed {c.config.project.name}!{COL_END}')
print(f'--------------------------------------------')
print(json.dumps(c.config.data._config, sort_keys=True, indent=4))
print(f'--------------------------------------------')
@task
def env(c):
# TODO: figure out how to pass arguments to this task
# to make it possible to get/set/del env vars on remote
# list remote env vars
c = user.update_ssh(c)
application.get_info(c)
config.env(c, 'list')
@task
def rollback(c):
tasks = [
# get fresh api token
control.login,
# plug into ssh config
user.update_ssh,
# gather redis info
redis.find_bin,
redis.get_id,
redis.get_info,
# gather main app info
application.get_id,
application.get_info,
# restore project
project.restore_db,
project.restore_project,
# update app config & restart
supervisor.update_configs,
supervisor.restart,
]
execute_tasks(c, tasks)
@task
def deploy(c):
tasks = [
# get fresh api token
control.login,
# plug into ssh config
user.update_ssh,
# gather redis info
redis.find_bin,
redis.get_id,
redis.get_info,
# gather main app info
application.get_id,
application.get_info,
# backup
project.backup_db,
project.backup_project,
# update code / requirements / statics / db
project.upload,
project.install_requirements,
project.update_static_files,
project.migrate_db,
# update app config & restart
supervisor.update_configs,
supervisor.restart,
]
execute_tasks(c, tasks)
@task
def install(c):
tasks = [
# get fresh api token
control.login,
# info needed for creates
server.get_id,
# create user in control panel and new ssh config
user.get_id,
user.create,
user.get_info,
user.update_ssh,
# install python
python.install_bin,
python.find_bin,
# install redis and create redis app in control panel
redis.install_bin,
redis.find_bin,
redis.get_id,
redis.create,
redis.get_info,
# create main app in control panel
application.get_id,
application.create,
application.get_info,
# install env, project, requirements, files and db
virtual_env.create,
project.upload,
project.install_requirements,
project.update_static_files,
# create database
database.get_id,
database.create,
# skipping upload/restore of db - do this manually
# install & start superuser
supervisor.install_bin,
supervisor.get_id,
supervisor.create,
supervisor.create_configs,
supervisor.start,
# TODO: create domain and site-routes
# ...
# print all retrieved info (db pass, etc)
pretty_print,
]
execute_tasks(c, tasks)
@task
def test(c):
tasks = [
control.login,
user.update_ssh,
application.get_id,
application.get_info,
virtual_env.create,
]
execute_tasks(c, tasks)
# set default config (will be picked up by fabric/invoke)
ns = Collection(install, deploy, rollback, env, test)
ns.configure(DEFAULT_CONFIG)