forked from adsabs/adsabs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
shell.py
202 lines (166 loc) · 6.67 KB
/
shell.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
# -*- coding: utf-8 -*-
import os
import sys
import tempfile
import subprocess
from time import sleep
from flask.ext.script import Manager, Command, prompt, prompt_pass, prompt_bool
from flask import render_template
from adsabs import create_app
from config import config
config.LOGGING_LOG_TO_FILE = False
config.LOGGING_LOG_TO_CONSOLE = True
config.LOGGING_LOG_LEVEL = 'INFO'
if not getattr(config, 'SECRET_KEY', None):
# set a fake one to keep the create_app from barfing
config.SECRET_KEY = "foo"
app = create_app(config)
manager = Manager(app)#, with_default_commands=False)
tools_manager = Manager("Tools commands")#, with_default_commands=False)
@manager.command
def run(port=5000):
"""Run server that can be reached from anywhere."""
app.run(host='0.0.0.0', port=int(port))
@manager.command
def create_local_config():
"""Generate a local_config.py with necessary settings"""
local_config_path = os.path.join(app.root_path, '../config/local_config.py')
if os.path.exists(local_config_path):
app.logger.info("local_config.py exists")
if not prompt_bool("Overwrite"):
return
config_items = {}
if prompt_bool("Generate SECRET_KEY", True):
config_items['SECRET_KEY'] = os.urandom(24).encode('hex')
config_items['ACCOUNT_VERIFICATION_SECRET'] = os.urandom(24).encode('hex')
else:
app.logger.warn("OK. You'll need to include a SECRET_KEY in local_config.py for the app to run.")
output = render_template('config/local_config.py.tmpl', config_items=config_items)
with open(local_config_path, 'w') as lc:
print >>lc, output
app.logger.info("local_config.py created")
@manager.command
def generate_secret_key():
"""Generate a random string suitable for using a the SECRET_KEY value"""
app.logger.info("SECRET_KEY = '%s'" % os.urandom(24).encode('hex'))
app.logger.info("ACCOUNT_VERIFICATION_SECRET = '%s'" % os.urandom(24).encode('hex'))
@manager.command
def start_beaver():
"""
starts a beaver daemon for transmitting log files to the redis/logstash
"""
pid_path = os.path.join(app.root_path, '../.beaver.pid')
if os.path.exists(pid_path):
with open(pid_path, 'r') as pid:
raise Exception("looks like another beaver process is running: %s" % pid.read())
config_path = os.path.join(app.root_path, '../config/beaver.conf')
if not os.path.exists(config_path):
raise Exception("no config file found at %s" % config_path)
beaver_log = os.path.join(app.root_path, '../logs/beaver.log')
p = subprocess.Popen(["beaver",
"-D", # daemonize
"-c", config_path,
"-P", pid_path,
"-l", beaver_log
])
sleep(1)
with open(pid_path, 'r') as pid:
app.logger.info("beaver daemon started with pid %s" % pid.read())
@manager.command
def stop_beaver():
"""
stops a running beaver daemon identified by the pid in app.root_path/.beaver.pid
"""
import signal
pid_path = os.path.join(app.root_path, '../.beaver.pid')
if not os.path.exists(pid_path):
raise Exception("There doesn't appear to be a pid file for a running beaver instance")
pid = int(open(pid_path,'r').read())
os.kill(pid, signal.SIGTERM)
sleep(1)
# Check that we really killed it
try:
os.kill(pid, 0)
raise Exception("""wasn't able to kill the process
HINT:use signal.SIGKILL or signal.SIGABORT""")
except OSError:
app.logger.info("killed beaver process with pid %d" % pid)
@tools_manager.command
def tools():
"""
download and setup of extras in the ./tools directory
TODO: we should really move this kind of stuff into a deployment/config-management
tool, like fabric or maybe hudson
"""
tools_dir = app.root_path + '/../tools'
if os.environ.has_key('VIRTUAL_ENV'):
activate = ". %s/bin/activate" % os.environ['VIRTUAL_ENV']
else:
activate = ""
temp = tempfile.NamedTemporaryFile(delete=False)
print >>temp, """#!/bin/bash
%s
cd %s
pip install django
git clone https://github.com/adsabs/mongoadmin.git
cd mongoadmin
cp mongoadmin_project/settings.py.dist mongoadmin_project/settings.py
perl -p -i -e 's/django\.db\.backends\.mysql/django.db.backends.sqlite3/' mongoadmin_project/settings.py
%s manage.py syncdb --noinput
""" % (activate, tools_dir, sys.executable)
temp.close()
subprocess.call(["chmod", "755", temp.name])
subprocess.call(["bash", temp.name])
temp.unlink(temp.name)
print """
mongoadmin install is complete.
Run by typing...
cd tools/mongoadmin
python manage.py runserver
"""
mongo_manager = Manager("Mongo operations", with_default_commands=False)
@mongo_manager.command
def init():
pass
@mongo_manager.command
def dump(outdir=None):
if outdir is None:
from datetime import datetime
outdir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'dumps', datetime.today().isoformat())
outdir = prompt("Output directory", outdir)
app.logger.info("Dumping %s database to %s" % (config.MONGOALCHEMY_DATABASE, outdir))
subprocess.call(["mongodump",
"-d", config.MONGOALCHEMY_DATABASE,
"-u", config.MONGOALCHEMY_USER,
"-p", config.MONGOALCHEMY_PASSWORD,
"-o", outdir])
@mongo_manager.command
def restore(indir=None):
if indir is None:
indir = prompt("Input database directory")
app.logger.info("Restoring %s database from %s" % (config.MONGOALCHEMY_DATABASE, indir))
subprocess.call(["mongorestore",
"-d", config.MONGOALCHEMY_DATABASE,
"-u", config.MONGOALCHEMY_USER,
"-p", config.MONGOALCHEMY_PASSWORD,
os.path.join(indir, config.MONGOALCHEMY_DATABASE)])
@mongo_manager.command
def migrate(migration_id):
def import_migration():
package_path = 'migrations.migrate_%s' % migration_id
m = __import__(package_path)
# traverse the package path
for n in package_path.split(".")[1:]:
m = getattr(m, n)
return m
m = import_migration()
m.migrate()
manager.add_command('mongo', mongo_manager)
# register sub-managers
from adsabs.modules.api import manager as api_manager
manager.add_command('api', api_manager)
manager.add_command('tools', tools_manager)
from adsabs.modules.pages import manager as pages_manager
manager.add_command('pages', pages_manager)
if __name__ == "__main__":
manager.run()