2015-08-17 06:37:14 +02:00
|
|
|
import os
|
2015-08-20 02:46:50 +02:00
|
|
|
import sys
|
2015-08-19 04:18:08 +02:00
|
|
|
import logging
|
|
|
|
import platform
|
2015-08-17 06:37:14 +02:00
|
|
|
|
|
|
|
try:
|
|
|
|
import sh
|
|
|
|
except ImportError:
|
|
|
|
import pbs as sh
|
|
|
|
|
2015-08-19 04:18:08 +02:00
|
|
|
SUPPORTED_PLATFORMS = {
|
|
|
|
"Ubuntu": [
|
|
|
|
"trusty",
|
|
|
|
],
|
|
|
|
}
|
|
|
|
|
2015-08-17 06:37:14 +02:00
|
|
|
APT_DEPENDENCIES = {
|
|
|
|
"trusty": [
|
2015-09-21 00:01:49 +02:00
|
|
|
"closure-compiler",
|
2015-08-17 06:37:14 +02:00
|
|
|
"libffi-dev",
|
|
|
|
"memcached",
|
|
|
|
"rabbitmq-server",
|
|
|
|
"libldap2-dev",
|
|
|
|
"redis-server",
|
|
|
|
"postgresql-server-dev-all",
|
|
|
|
"libmemcached-dev",
|
|
|
|
"postgresql-9.3",
|
|
|
|
"python-dev",
|
|
|
|
"hunspell-en-us",
|
|
|
|
"nodejs",
|
|
|
|
"python-virtualenv",
|
2015-08-19 04:20:28 +02:00
|
|
|
"supervisor",
|
2015-08-17 06:37:14 +02:00
|
|
|
"git",
|
2015-08-20 22:40:06 +02:00
|
|
|
"npm",
|
|
|
|
"node-jquery",
|
2015-08-21 01:58:25 +02:00
|
|
|
"yui-compressor",
|
2015-08-24 06:34:44 +02:00
|
|
|
"puppet", # Used by lint-all
|
2015-08-20 22:40:06 +02:00
|
|
|
]
|
|
|
|
}
|
|
|
|
|
|
|
|
# TODO: backport node-{cssstyle,htmlparser2,nwmatcher} to trusty,
|
|
|
|
# so we can eliminate npm (above) and this section.
|
|
|
|
NPM_DEPENDENCIES = {
|
|
|
|
"trusty": [
|
|
|
|
"cssstyle",
|
|
|
|
"htmlparser2",
|
|
|
|
"nwmatcher",
|
2015-08-17 06:37:14 +02:00
|
|
|
]
|
|
|
|
}
|
|
|
|
|
2015-08-17 20:15:21 +02:00
|
|
|
VENV_PATH="/srv/zulip-venv"
|
|
|
|
ZULIP_PATH="/srv/zulip"
|
|
|
|
|
2015-10-14 01:18:49 +02:00
|
|
|
if not os.path.exists(os.path.join(os.path.dirname(__file__), ".git")):
|
|
|
|
print "Error: No Zulip git repository present at /srv/zulip!"
|
|
|
|
print "To setup the Zulip development environment, you should clone the code"
|
|
|
|
print "from GitHub, rather than using a Zulip production release tarball."
|
|
|
|
sys.exit(1)
|
|
|
|
|
2015-09-28 18:17:23 +02:00
|
|
|
# TODO: Parse arguments properly
|
|
|
|
if "--travis" in sys.argv:
|
|
|
|
ZULIP_PATH="."
|
|
|
|
|
2015-08-17 06:37:14 +02:00
|
|
|
# tsearch-extras is an extension to postgres's built-in full-text search.
|
|
|
|
# TODO: use a real APT repository
|
|
|
|
TSEARCH_URL_BASE = "https://dl.dropboxusercontent.com/u/283158365/zuliposs/"
|
|
|
|
TSEARCH_PACKAGE_NAME = {
|
|
|
|
"trusty": "postgresql-9.3-tsearch-extras"
|
|
|
|
}
|
|
|
|
TSEARCH_VERSION = "0.1.2"
|
|
|
|
# TODO: this path is platform-specific!
|
|
|
|
TSEARCH_STOPWORDS_PATH = "/usr/share/postgresql/9.3/tsearch_data/"
|
|
|
|
REPO_STOPWORDS_PATH = os.path.join(
|
|
|
|
ZULIP_PATH,
|
|
|
|
"puppet",
|
|
|
|
"zulip",
|
|
|
|
"files",
|
|
|
|
"postgresql",
|
|
|
|
"zulip_english.stop",
|
|
|
|
)
|
|
|
|
|
2015-08-21 03:06:18 +02:00
|
|
|
LOUD = dict(_out=sys.stdout, _err=sys.stderr)
|
|
|
|
|
2015-08-19 04:18:08 +02:00
|
|
|
|
2015-08-20 02:46:50 +02:00
|
|
|
def main():
|
|
|
|
log = logging.getLogger("zulip-provisioner")
|
|
|
|
# TODO: support other architectures
|
|
|
|
if platform.architecture()[0] == '64bit':
|
|
|
|
arch = 'amd64'
|
|
|
|
else:
|
|
|
|
log.critical("Only amd64 is supported.")
|
2015-08-19 04:18:08 +02:00
|
|
|
|
2015-08-20 02:46:50 +02:00
|
|
|
vendor, version, codename = platform.dist()
|
2015-08-17 06:37:14 +02:00
|
|
|
|
2015-08-20 02:46:50 +02:00
|
|
|
if not (vendor in SUPPORTED_PLATFORMS and codename in SUPPORTED_PLATFORMS[vendor]):
|
|
|
|
log.critical("Unsupported platform: {} {}".format(vendor, codename))
|
2015-08-17 06:37:14 +02:00
|
|
|
|
2015-08-20 02:46:50 +02:00
|
|
|
with sh.sudo:
|
2015-08-21 03:06:18 +02:00
|
|
|
sh.apt_get.update(**LOUD)
|
2015-08-17 06:37:14 +02:00
|
|
|
|
2015-08-21 03:06:18 +02:00
|
|
|
sh.apt_get.install(*APT_DEPENDENCIES["trusty"], assume_yes=True, **LOUD)
|
2015-08-17 06:37:14 +02:00
|
|
|
|
2015-08-20 02:46:50 +02:00
|
|
|
temp_deb_path = sh.mktemp("package_XXXXXX.deb", tmpdir=True)
|
|
|
|
|
|
|
|
sh.wget(
|
|
|
|
"{}/{}_{}_{}.deb".format(
|
|
|
|
TSEARCH_URL_BASE,
|
|
|
|
TSEARCH_PACKAGE_NAME["trusty"],
|
|
|
|
TSEARCH_VERSION,
|
|
|
|
arch,
|
|
|
|
),
|
|
|
|
output_document=temp_deb_path,
|
2015-08-21 03:06:18 +02:00
|
|
|
**LOUD
|
2015-08-20 02:46:50 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
with sh.sudo:
|
2015-08-21 03:06:18 +02:00
|
|
|
sh.dpkg("--install", temp_deb_path, **LOUD)
|
2015-08-17 06:37:14 +02:00
|
|
|
|
2015-08-21 22:28:07 +02:00
|
|
|
with sh.sudo:
|
|
|
|
PHANTOMJS_PATH = "/srv/phantomjs"
|
|
|
|
PHANTOMJS_TARBALL = os.path.join(PHANTOMJS_PATH, "phantomjs-1.9.8-linux-x86_64.tar.bz2")
|
|
|
|
sh.mkdir("-p", PHANTOMJS_PATH, **LOUD)
|
|
|
|
sh.wget("https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-1.9.8-linux-x86_64.tar.bz2",
|
|
|
|
output_document=PHANTOMJS_TARBALL, **LOUD)
|
|
|
|
sh.tar("xj", directory=PHANTOMJS_PATH, file=PHANTOMJS_TARBALL, **LOUD)
|
|
|
|
sh.ln("-sf", os.path.join(PHANTOMJS_PATH, "phantomjs-1.9.8-linux-x86_64", "bin", "phantomjs"),
|
|
|
|
"/usr/local/bin/phantomjs", **LOUD)
|
|
|
|
|
2015-08-20 02:46:50 +02:00
|
|
|
with sh.sudo:
|
2015-08-21 03:06:18 +02:00
|
|
|
sh.rm("-rf", VENV_PATH, **LOUD)
|
|
|
|
sh.mkdir("-p", VENV_PATH, **LOUD)
|
|
|
|
sh.chown("{}:{}".format(os.getuid(), os.getgid()), VENV_PATH, **LOUD)
|
2015-08-17 06:37:14 +02:00
|
|
|
|
2015-08-21 03:06:18 +02:00
|
|
|
sh.virtualenv(VENV_PATH, **LOUD)
|
2015-08-17 06:37:14 +02:00
|
|
|
|
2015-08-20 02:46:50 +02:00
|
|
|
# Add the ./tools and ./scripts/setup directories inside the repository root to
|
|
|
|
# the system path; we'll reference them later.
|
|
|
|
orig_path = os.environ["PATH"]
|
|
|
|
os.environ["PATH"] = os.pathsep.join((
|
|
|
|
os.path.join(ZULIP_PATH, "tools"),
|
|
|
|
os.path.join(ZULIP_PATH, "scripts", "setup"),
|
|
|
|
orig_path
|
|
|
|
))
|
2015-08-17 06:37:14 +02:00
|
|
|
|
|
|
|
|
2015-08-20 02:46:50 +02:00
|
|
|
# Put Python virtualenv activation in our .bash_profile.
|
|
|
|
with open(os.path.expanduser('~/.bash_profile'), 'w+') as bash_profile:
|
|
|
|
bash_profile.writelines([
|
|
|
|
"source .bashrc\n",
|
|
|
|
"source %s\n" % (os.path.join(VENV_PATH, "bin", "activate"),),
|
|
|
|
])
|
2015-08-20 22:40:06 +02:00
|
|
|
|
2015-08-20 02:46:50 +02:00
|
|
|
# Switch current Python context to the virtualenv.
|
|
|
|
activate_this = os.path.join(VENV_PATH, "bin", "activate_this.py")
|
|
|
|
execfile(activate_this, dict(__file__=activate_this))
|
2015-08-20 22:40:06 +02:00
|
|
|
|
2015-08-21 03:06:18 +02:00
|
|
|
sh.pip.install(requirement=os.path.join(ZULIP_PATH, "requirements.txt"), **LOUD)
|
2015-08-17 06:37:14 +02:00
|
|
|
|
2015-08-20 02:46:50 +02:00
|
|
|
with sh.sudo:
|
2015-08-21 03:06:18 +02:00
|
|
|
sh.cp(REPO_STOPWORDS_PATH, TSEARCH_STOPWORDS_PATH, **LOUD)
|
2015-08-20 22:40:06 +02:00
|
|
|
|
2015-08-20 02:46:50 +02:00
|
|
|
# Add additional node packages for test-js-with-node.
|
|
|
|
with sh.sudo:
|
2015-08-21 03:06:18 +02:00
|
|
|
sh.npm.install(*NPM_DEPENDENCIES["trusty"], g=True, prefix="/usr", **LOUD)
|
2015-08-17 06:37:14 +02:00
|
|
|
|
2015-08-20 02:46:50 +02:00
|
|
|
# Management commands expect to be run from the root of the project.
|
|
|
|
os.chdir(ZULIP_PATH)
|
2015-08-20 22:40:06 +02:00
|
|
|
|
2015-09-25 10:19:04 +02:00
|
|
|
os.system("tools/download-zxcvbn")
|
2015-09-25 08:56:36 +02:00
|
|
|
os.system("tools/emoji_dump/build_emoji")
|
2015-08-21 18:18:18 +02:00
|
|
|
os.system("generate_secrets.py -d")
|
2015-09-28 18:17:23 +02:00
|
|
|
if "--travis" in sys.argv:
|
|
|
|
os.system("sudo service rabbitmq-server restart")
|
|
|
|
os.system("sudo service redis-server restart")
|
|
|
|
os.system("sudo service memcached restart")
|
2015-08-21 03:06:18 +02:00
|
|
|
sh.configure_rabbitmq(**LOUD)
|
|
|
|
sh.postgres_init_db(**LOUD)
|
|
|
|
sh.do_destroy_rebuild_database(**LOUD)
|
|
|
|
sh.postgres_init_test_db(**LOUD)
|
|
|
|
sh.do_destroy_rebuild_test_database(**LOUD)
|
2015-08-17 06:37:14 +02:00
|
|
|
|
2015-08-20 02:46:50 +02:00
|
|
|
if __name__ == "__main__":
|
|
|
|
sys.exit(main())
|