2015-11-01 17:11:06 +01:00
|
|
|
from __future__ import print_function
|
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-10-15 00:35:18 +02:00
|
|
|
"libfreetype6-dev",
|
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",
|
2015-10-26 17:12:07 +01:00
|
|
|
"nodejs-legacy",
|
2015-08-17 06:37:14 +02:00
|
|
|
"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",
|
2015-08-21 01:58:25 +02:00
|
|
|
"yui-compressor",
|
2016-02-18 04:39:52 +01:00
|
|
|
"wget",
|
|
|
|
"ca-certificates", # Explicit dependency in case e.g. wget is already installed
|
2015-08-24 06:34:44 +02:00
|
|
|
"puppet", # Used by lint-all
|
2015-11-04 10:22:24 +01:00
|
|
|
"gettext", # Used by makemessages i18n
|
2016-03-23 01:17:32 +01:00
|
|
|
"curl", # Used for fetching PhantomJS as wget occasionally fails on redirects
|
2015-08-20 22:40:06 +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")):
|
2015-11-01 17:11:06 +01:00
|
|
|
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.")
|
2015-10-14 01:18:49 +02:00
|
|
|
sys.exit(1)
|
|
|
|
|
2015-09-28 18:17:23 +02:00
|
|
|
# TODO: Parse arguments properly
|
2015-12-12 14:17:30 +01:00
|
|
|
if "--travis" in sys.argv or "--docker" in sys.argv:
|
2015-09-28 18:17:23 +02:00
|
|
|
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"
|
|
|
|
}
|
2016-03-11 07:38:00 +01:00
|
|
|
TSEARCH_VERSION = "0.1.3"
|
2015-08-17 06:37:14 +02:00
|
|
|
# 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")
|
2016-03-11 07:38:00 +01:00
|
|
|
|
2015-08-20 02:46:50 +02:00
|
|
|
if platform.architecture()[0] == '64bit':
|
|
|
|
arch = 'amd64'
|
2016-03-11 07:38:00 +01:00
|
|
|
phantomjs_arch = 'x86_64'
|
|
|
|
elif platform.architecture()[0] == '32bit':
|
|
|
|
arch = "i386"
|
|
|
|
phantomjs_arch = 'i686'
|
2015-08-20 02:46:50 +02:00
|
|
|
else:
|
2016-03-11 07:38:00 +01:00
|
|
|
log.critical("Only x86 is supported; ping zulip-devel@googlegroups.com if you want another architecture.")
|
|
|
|
sys.exit(1)
|
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"
|
2016-03-11 07:38:00 +01:00
|
|
|
PHANTOMJS_BASENAME = "phantomjs-1.9.8-linux-%s" % (phantomjs_arch,)
|
|
|
|
PHANTOMJS_TARBALL_BASENAME = PHANTOMJS_BASENAME + ".tar.bz2"
|
|
|
|
PHANTOMJS_TARBALL = os.path.join(PHANTOMJS_PATH, PHANTOMJS_TARBALL_BASENAME)
|
|
|
|
PHANTOMJS_URL = "https://bitbucket.org/ariya/phantomjs/downloads/%s" % (PHANTOMJS_TARBALL_BASENAME,)
|
2015-08-21 22:28:07 +02:00
|
|
|
sh.mkdir("-p", PHANTOMJS_PATH, **LOUD)
|
2015-12-26 18:16:29 +01:00
|
|
|
if not os.path.exists(PHANTOMJS_TARBALL):
|
2016-03-23 01:17:32 +01:00
|
|
|
sh.curl('-J', '-L', PHANTOMJS_URL, o=PHANTOMJS_TARBALL, **LOUD)
|
2015-08-21 22:28:07 +02:00
|
|
|
sh.tar("xj", directory=PHANTOMJS_PATH, file=PHANTOMJS_TARBALL, **LOUD)
|
2016-03-11 07:38:00 +01:00
|
|
|
sh.ln("-sf", os.path.join(PHANTOMJS_PATH, PHANTOMJS_BASENAME, "bin", "phantomjs"),
|
2015-08-21 22:28:07 +02:00
|
|
|
"/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-10-26 17:16:26 +01:00
|
|
|
# npm install and management commands expect to be run from the root of the project.
|
2015-08-20 02:46:50 +02:00
|
|
|
os.chdir(ZULIP_PATH)
|
2015-08-20 22:40:06 +02:00
|
|
|
|
2015-10-26 17:16:26 +01:00
|
|
|
sh.npm.install(**LOUD)
|
|
|
|
|
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-12-12 14:17:30 +01:00
|
|
|
elif "--docker" in sys.argv:
|
|
|
|
os.system("sudo service rabbitmq-server restart")
|
|
|
|
os.system("sudo pg_dropcluster --stop 9.3 main")
|
|
|
|
os.system("sudo pg_createcluster -e utf8 --start 9.3 main")
|
|
|
|
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)
|
2015-10-14 00:54:17 +02:00
|
|
|
sh.postgres_init_dev_db(**LOUD)
|
2015-08-21 03:06:18 +02:00
|
|
|
sh.do_destroy_rebuild_database(**LOUD)
|
|
|
|
sh.postgres_init_test_db(**LOUD)
|
|
|
|
sh.do_destroy_rebuild_test_database(**LOUD)
|
2016-01-26 02:59:30 +01:00
|
|
|
return 0
|
2015-08-17 06:37:14 +02:00
|
|
|
|
2015-08-20 02:46:50 +02:00
|
|
|
if __name__ == "__main__":
|
|
|
|
sys.exit(main())
|