· 8 years ago · Nov 26, 2017, 12:12 AM
1from fabric.contrib.files import append, exists, sed, put
2from fabric.api import env, local, run, sudo
3import random
4import os
5import json
6
7PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))#settings ê°€ 있는 í´ë”
8# PROJECT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)),'fbtest')
9# PROJECT_DIR = './fbtest' # settingsê°€ 있는 í´ë”
10
11with open(os.path.join(PROJECT_DIR, "deploy.json")) as f:
12 envs = json.loads(f.read())
13
14def get_env(setting, envs):
15 return envs[setting]
16
17# TODO: Required Fields: REPO_URL, PROJECT_NAME, REMOTE_HOST, REMOTE_PASSWORD, REMOTE_USER @ deploy.json
18
19# developer: chagne this!
20REPO_URL = get_env('REPO_URL', envs)
21PROJECT_NAME = get_env('PROJECT_NAME', envs)
22REMOTE_HOST = get_env('REMOTE_HOST', envs)
23REMOTE_HOST_SSH = get_env('REMOTE_HOST_SSH', envs)
24REMOTE_USER = get_env('REMOTE_USER', envs)
25REMOTE_PASSWORD = get_env('REMOTE_PASSWORD', envs)
26STATIC_ROOT_NAME = 'static' #---------------------------- ìˆ˜ì •
27STATIC_URL_NAME = 'static' #---------------------------- ìˆ˜ì •
28MEDIA_ROOT = 'media' #---------------------------- ìˆ˜ì •
29
30# TODO: Server Engineer: you should add env.user as sudo user and NOT be root
31env.user = REMOTE_USER
32username = REMOTE_USER
33# Option: env.password
34env.hosts = [
35 REMOTE_HOST_SSH,
36]
37env.password = REMOTE_PASSWORD
38project_folder = '/home/{}/{}'.format(env.user, PROJECT_NAME)
39apt_requirements = [
40 'curl',
41 'git',
42 'python3-dev',
43 'python3-pip',
44 'build-essential',
45 'libpq-dev',
46 'postgresql',
47 'postgresql-contrib',
48 'apache2',
49 'libapache2-mod-wsgi-py3',
50 'python3-setuptools',
51 'libssl-dev',
52 'libffi-dev',
53]
54
55def new_server():
56 setup()
57 deploy()
58
59def setup():
60 #_mkdir_ssh()
61 #_register_ssh_key()
62 _get_latest_apt()
63 _install_apt_requirements(apt_requirements)
64 _make_virtualenv()
65 #_ufw_allow()
66
67def deploy():
68 _get_latest_source()
69 _put_envs()
70 _update_settings()
71 _update_virtualenv()
72 _update_static_files()
73 _update_database()
74 #_ufw_allow()
75 _make_virtualhost()
76 _grant_apache2()
77 _restart_apache2()
78
79
80def create_superuser():
81 virtualenv_folder = project_folder + '/../.virtualenvs/{}'.format(PROJECT_NAME)
82 run('cd %s && %s/bin/python3 manage.py createsuperuser' % (
83 project_folder, virtualenv_folder
84 ))
85
86def _mkdir_ssh():
87 USER_HOME = os.path.expanduser('~')
88 if not os.path.exists(os.path.join(USER_HOME, '.ssh/')):
89 local("mkdir {}".format(os.path.join(USER_HOME, '.ssh')))
90
91def _register_ssh_key():
92 local("ssh-keyscan -H {} >> {}".format(REMOTE_HOST, os.path.expanduser('~/.ssh/known_hosts')))
93
94
95def migrate():
96 _put_envs()
97 _update_settings()
98 _update_virtualenv()
99 _update_static_files()
100 _update_database()
101 _make_virtualhost()
102 _grant_apache2()
103 _restart_apache2()
104
105def _put_envs():
106 put('envs.json', '~/{}/envs.json'.format(PROJECT_NAME))
107 #put('bank_envs.json', '~/{}/bank_envs.json'.format(PROJECT_NAME))
108
109def _get_latest_apt():
110 update_or_not = input('would you update?: [y/n]')
111 if update_or_not=='y':
112 sudo('sudo apt-get update && sudo apt-get -y upgrade')
113
114def _install_apt_requirements(apt_requirements):
115 reqs = ''
116 for req in apt_requirements:
117 reqs += (' ' + req)
118 sudo('sudo apt-get -y install {}'.format(reqs))
119
120def _make_virtualenv():
121 if not exists('~/.virtualenvs'):
122 script = '''"# python virtualenv settings
123 export WORKON_HOME=~/.virtualenvs
124 export VIRTUALENVWRAPPER_PYTHON="$(command \which python3)" # location of python3
125 source /usr/local/bin/virtualenvwrapper.sh"'''
126 run('mkdir ~/.virtualenvs')
127 sudo('sudo pip3 install virtualenv virtualenvwrapper')
128 run('echo {} >> ~/.bashrc'.format(script))
129
130def _get_latest_source():
131 if exists(project_folder + '/.git'):
132 run('cd %s && git fetch' % (project_folder,))
133 else:
134 run('git clone %s %s' % (REPO_URL, project_folder))
135 current_commit = local("git log -n 1 --format=%H", capture=True)
136 run('cd %s && git reset --hard %s' % (project_folder, current_commit))
137
138def _update_settings():
139 settings_path = project_folder + '/{}/settings.py'.format(PROJECT_NAME)
140
141 sed(settings_path, "DEBUG = True", "DEBUG = False")
142 # sed(settings_path, "DEBUG = True", "DEBUG = True")
143
144 sed(settings_path,
145 'ALLOWED_HOSTS = .+$',
146 'ALLOWED_HOSTS = ["%s"]' % (REMOTE_HOST,)
147 )
148 secret_key_file = project_folder + '/{}/secret_key.py'.format(PROJECT_NAME)
149
150 if not exists(secret_key_file):
151 chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'
152 key = ''.join(random.SystemRandom().choice(chars) for _ in range(50))
153 append(secret_key_file, "SECRET_KEY = '%s'" % (key,))
154 append(settings_path, '\nfrom .secret_key import SECRET_KEY')
155
156def _update_virtualenv():
157 virtualenv_folder = project_folder + '/../.virtualenvs/{}'.format(PROJECT_NAME)
158 if not exists(virtualenv_folder + '/bin/pip'):
159 run('cd /home/%s/.virtualenvs && virtualenv %s' % (env.user, PROJECT_NAME))
160 run('%s/bin/pip install -r %s/requirements.txt' % (
161 virtualenv_folder, project_folder
162 ))
163
164def _update_static_files():
165 virtualenv_folder = project_folder + '/../.virtualenvs/{}'.format(PROJECT_NAME)
166 run('cd %s && %s/bin/python3 manage.py collectstatic --noinput' % (
167 project_folder, virtualenv_folder
168 ))
169
170def _update_database():
171 virtualenv_folder = project_folder + '/../.virtualenvs/{}'.format(PROJECT_NAME)
172 run('cd %s && %s/bin/python3 manage.py migrate --noinput' % (
173 project_folder, virtualenv_folder
174 ))
175
176def _ufw_allow():
177 sudo("ufw allow 'Apache Full'")
178 sudo("ufw reload")
179
180def _make_virtualhost():
181 script = """'<VirtualHost *:80>
182 ServerName {servername}
183 Alias /{static_url} /home/{username}/{project_name}/{static_root}
184 Alias /{media_url} /home/{username}/{project_name}/{media_url}
185 <Directory /home/{username}/{project_name}/{media_url}>
186 Require all granted
187 </Directory>
188 <Directory /home/{username}/{project_name}/{static_root}>
189 Require all granted
190 </Directory>
191 <Directory /home/{username}/{project_name}/{project_name}>
192 <Files wsgi.py>
193 Require all granted
194 </Files>
195 </Directory>
196 WSGIDaemonProcess {project_name} python-home=/home/{username}/.virtualenvs/{project_name} python-path=/home/{username}/{project_name}
197 WSGIProcessGroup {project_name}
198 WSGIScriptAlias / /home/{username}/{project_name}/{project_name}/wsgi.py
199 ErrorLog ${{APACHE_LOG_DIR}}/error.log
200 CustomLog ${{APACHE_LOG_DIR}}/access.log combined
201 </VirtualHost>'""".format(
202 static_root=STATIC_ROOT_NAME,
203 username=env.user,
204 project_name=PROJECT_NAME,
205 static_url=STATIC_URL_NAME,
206 servername=REMOTE_HOST,
207 media_url=MEDIA_ROOT
208 )
209 sudo('echo {} > /etc/apache2/sites-available/{}.conf'.format(script, PROJECT_NAME))
210 sudo('a2ensite {}.conf'.format(PROJECT_NAME))
211
212def _grant_apache2():
213 sudo('chown :www-data ~/{}'.format(PROJECT_NAME))
214 # enable below if use sqlite3
215 sudo('chmod 775 ~/{}/db.sqlite3'.format(PROJECT_NAME))
216 # sudo('chmod a+w ~/{}/db.sqlite3'.format(PROJECT_NAME))
217def _restart_apache2():
218 sudo('sudo service apache2 restart')