-
Notifications
You must be signed in to change notification settings - Fork 1
/
start.py
254 lines (207 loc) · 8.42 KB
/
start.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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
import argparse
import subprocess
import requests
import time
import sys
sys.path.insert(1, 'app/')
import platform
import shlex
from pathlib import Path
def __run_bash_command(command):
process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
output, error = process.communicate()
if error:
print(error)
return output
def start(args):
__start_docker(args)
if not args.docker:
print('Waiting for Flask Server...')
__start_pyro_server()
stop(args)
def __start_docker(args):
print('Starting Flask Server')
__correct_env()
bashCommand = "docker-compose up -d"
if args.build:
bashCommand = f'{bashCommand} --build'
print('Rebuilding Containers')
__run_bash_command(bashCommand)
print('Docker is running')
def __start_pyro_server():
import server.pyro_server as pyro_server
print('Starting Pyro4 Server')
pyro_server.start()
def ping_flask_server(args):
try:
if platform.system().lower() == 'windows':
command = 'docker-machine ip'.split()
result = subprocess.Popen(command, stdout=subprocess.PIPE)
result = result.stdout.read().decode().strip()
result = 'http://' + result + ':5000/ping'
r = requests.get(result)
else:
r = requests.get('http://127.0.0.1:5000/ping')
if r.status_code == 200:
print('Flask Server is Ready')
else:
print('Server not ready')
except:
print('Server could not be reached')
def __setup_db():
try:
if platform.system().lower() == 'windows':
command = 'docker-machine ip'.split()
result = subprocess.Popen(command, stdout=subprocess.PIPE)
result = result.stdout.read().decode().strip()
result = 'http://' + result + ':5000/setup_db'
r = requests.get(result)
else:
r = requests.get('http://127.0.0.1:5000/setup_db')
print("requested setup_db")
if r.status_code == 200:
print('Database is Ready')
else:
print('Server not ready')
except Exception as e:
print(e)
print('Server could not be reached. Ensure that docker is running and try again.')
def stop(args):
__run_bash_command("docker-compose down")
def db(args):
if args.db_operation == 'setup':
__setup_db()
elif args.db_operation == 'rebuild':
__rebuild_db(args)
def __rebuild_db(args):
print('WARNING: This will delete all data in the database.')
res = input("Before running this method, all files in app/migrations/versions need to be deleted. Has this been done? (y/N)\n>")
if res.lower().strip() != "y" and res.lower().strip() != 'yes':
print('Please delete all files in app/migrations/versions')
sys.exit()
__run_bash_command("docker volume rm practicum_flask_db")
print('Volume Deleted')
print('Starting Docker...')
__start_docker(args)
time.sleep(5)
__run_bash_command("docker exec -it flask_app python manage.py db migrate")
__run_bash_command("docker exec -it flask_app python manage.py db upgrade")
print("Setting up database")
__setup_db()
if not args.up:
print('Shutting down docker')
stop(args)
__check_network()
print('Rebuild complete')
def check_req(args):
reqs = ['Pyro4', 'python-vagrant', 'guacapy', 'requests']
if ('python 2.7' in __run_bash_command('pip --version').decode()):
output = __run_bash_command('pip3 freeze').decode()
else:
output = __run_bash_command('pip freeze').decode()
for req in reqs:
if req in output:
print(f'{req} Installed')
else:
print(f'{req} not installed!')
output = __run_bash_command('docker -v').decode()
if output.startswith('Docker version'):
print('Docker Installed')
else:
print('Docker not Installed!')
output = __run_bash_command('vagrant -v').decode()
if output.startswith('Vagrant'):
print('Vagrant Installed')
else:
print('Vagrant not Installed!')
def __correct_env():
try:
env_file = 'debug_mode.env'
vbox_ip = 'VBOX_IP'
windows_ip = '192.168.99.1'
mac_ip = '192.168.33.1'
new_env = ''
with open(env_file) as f:
data = f.readlines()
for line in data:
if vbox_ip in line:
ip = line.split('=')[1]
if platform.system().lower() == 'windows' and not ip is windows_ip:
line = vbox_ip + '=' + windows_ip + '\n'
if not platform.system().lower() == 'windows' and ip is windows_ip:
line = vbox_ip + '=' + mac_ip + '\n'
new_env = new_env + line
data = ''.join(data)
if new_env != data:
with open(env_file, 'w') as f:
f.write(new_env)
except IOError:
print('Failed to correct debug_mode.env file.')
def __check_network():
if Path('existing_network').is_file() and not Path('existing_network').stat().st_size == 0:
with open('existing_network') as f:
network = f.readline()
print (network)
__check_network_settings(network)
else:
__create_new()
def __check_network_settings(network):
command = 'VBoxManage list hostonlyifs'
output = __run_bash_command(command).decode()
ip = '10.10.0.1'
ip_exists = __check_ip_in_use()
output = output.split(network)
network_exists = len(output) > 1
if (network_exists and ip in output[1]):
print('network set correctly')
elif (network_exists and ip_exists):
print('ERROR: Network Does Exist but required Network ip(10.10.0.1) vbox host only adapter in use by other hostonlyifs')
elif (network_exists and not ip_exists):
print('network %s not configured correctly needs to be 10.10.0.1/16, configuring now' % network)
__config_net(network)
else:
print('Network %s does not exist, creating new network')
__create_new()
def __check_ip_in_use():
command = 'VBoxManage list hostonlyifs'
output = __run_bash_command(command).decode()
ip = '10.10.0.1'
return (ip in output)
def __create_new():
if __check_ip_in_use():
print('ERROR: Network ip(10.10.0.1) vbox host only adapter in use by other hostonlyifs')
network = __make_new()
__config_net(network)
with open('existing_network', 'w') as f:
f.write(network)
def __make_new():
output = __run_bash_command('VBoxManage hostonlyif create').decode()
network = output.split("'")[1].strip("'")
return network
def __config_net(network):
configure_network = "VBoxManage hostonlyif ipconfig '%s' --ip 10.10.0.1 --netmask 255.255.0.0" % network
__run_bash_command(configure_network)
def __remove_net():
with open('existing_network') as f:
network = f.readline()
a = "VBoxManage hostonlyif remove '%s'" % network
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Manage the system')
subparsers = parser.add_subparsers(help='What operation would you like to take.')
start_parser = subparsers.add_parser('start', help='Starts the system')
start_parser.add_argument('--build', help='Rebuilds the docker containers', action='store_true')
start_parser.add_argument('--docker', help='Starts only Docker without starting the pyro server', action='store_true')
start_parser.set_defaults(func=start)
stop_parser = subparsers.add_parser('stop', help='Stops the system')
stop_parser.set_defaults(func=stop)
ping_parser = subparsers.add_parser('ping', help='Ping the Flask Server')
ping_parser.set_defaults(func=ping_flask_server)
db_parser = subparsers.add_parser('db', help='Basic database operations')
db_parser.add_argument('db_operation', help='Database operations', choices=['rebuild', 'setup'], default='setup')
db_parser.add_argument('--build', help='Rebuilds the docker containers after deleting the database volume. Only used during rebuild.', action='store_true')
db_parser.add_argument('--up', help='Leaves docker running after rebuilding the database. Only used during rebuild.', action='store_true')
db_parser.set_defaults(func=db)
req_parser = subparsers.add_parser('check_req', help='Check if the needed requirements are installed')
req_parser.set_defaults(func=check_req)
args = parser.parse_args()
args.func(args)