diff --git a/manage.py b/manage.py index 3146a599f8..2423c81943 100755 --- a/manage.py +++ b/manage.py @@ -4,17 +4,21 @@ import sys import logging import subprocess +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +sys.path.append(BASE_DIR) +import scripts.lib.setup_path_on_import + if __name__ == "__main__": if 'posix' in os.name and os.geteuid() == 0: from django.core.management.base import CommandError raise CommandError("manage.py should not be run as root.") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "zproject.settings") - os.environ.setdefault("PYTHONSTARTUP", os.path.join(os.path.dirname(__file__), "scripts/lib/pythonrc.py")) + os.environ.setdefault("PYTHONSTARTUP", os.path.join(BASE_DIR, "scripts/lib/pythonrc.py")) from django.conf import settings logger = logging.getLogger("zulip.management") - subprocess.check_call([os.path.join(os.path.dirname(__file__), "scripts", "lib", "log-management-command"), + subprocess.check_call([os.path.join(BASE_DIR, "scripts", "lib", "log-management-command"), " ".join(sys.argv)]) if "--no-traceback" not in sys.argv and len(sys.argv) > 1: diff --git a/puppet/zulip/files/nagios_plugins/zulip_app_frontend/check_queue_worker_errors b/puppet/zulip/files/nagios_plugins/zulip_app_frontend/check_queue_worker_errors index 821b1fdd26..cdf9c98090 100755 --- a/puppet/zulip/files/nagios_plugins/zulip_app_frontend/check_queue_worker_errors +++ b/puppet/zulip/files/nagios_plugins/zulip_app_frontend/check_queue_worker_errors @@ -7,6 +7,8 @@ from __future__ import print_function import sys sys.path.append('/home/zulip/deployments/current') +import scripts.lib.setup_path_on_import + from zproject import settings import glob diff --git a/puppet/zulip/files/nagios_plugins/zulip_app_frontend/check_send_receive_time b/puppet/zulip/files/nagios_plugins/zulip_app_frontend/check_send_receive_time index de03780924..b3ab4fee18 100755 --- a/puppet/zulip/files/nagios_plugins/zulip_app_frontend/check_send_receive_time +++ b/puppet/zulip/files/nagios_plugins/zulip_app_frontend/check_send_receive_time @@ -18,6 +18,9 @@ import random import traceback import os +sys.path.append('/home/zulip/deployments/current') +import scripts.lib.setup_path_on_import + import django def total_seconds(timedelta): diff --git a/puppet/zulip/files/nagios_plugins/zulip_postgres_appdb/check_fts_update_log b/puppet/zulip/files/nagios_plugins/zulip_postgres_appdb/check_fts_update_log index 02bdfdc4f1..bc308274bd 100755 --- a/puppet/zulip/files/nagios_plugins/zulip_postgres_appdb/check_fts_update_log +++ b/puppet/zulip/files/nagios_plugins/zulip_postgres_appdb/check_fts_update_log @@ -5,6 +5,10 @@ Nagios plugin to check the length of the FTS update log. """ from __future__ import print_function +import sys +sys.path.append('/home/zulip/deployments/current') +import scripts.lib.setup_path_on_import + import psycopg2 states = { diff --git a/puppet/zulip/files/nagios_plugins/zulip_postgres_common/check_postgres_backup b/puppet/zulip/files/nagios_plugins/zulip_postgres_common/check_postgres_backup index 59e445b008..e65a1edaa4 100755 --- a/puppet/zulip/files/nagios_plugins/zulip_postgres_common/check_postgres_backup +++ b/puppet/zulip/files/nagios_plugins/zulip_postgres_common/check_postgres_backup @@ -1,11 +1,16 @@ #!/usr/bin/env python from __future__ import print_function -import dateutil.parser -import pytz import subprocess from datetime import datetime, timedelta +import sys +sys.path.append('/home/zulip/deployments/current') +import scripts.lib.setup_path_on_import + +import dateutil.parser +import pytz + states = { "OK": 0, "WARNING": 1, diff --git a/puppet/zulip/files/postgresql/process_fts_updates b/puppet/zulip/files/postgresql/process_fts_updates index 7943802052..ac84aa285c 100755 --- a/puppet/zulip/files/postgresql/process_fts_updates +++ b/puppet/zulip/files/postgresql/process_fts_updates @@ -8,6 +8,20 @@ # search column search_tsvector in the main zerver_message. from __future__ import print_function +import sys + +# We want to use a virtualenv in production, which will be in /home/zulip/deployments/current. +# So we should add that path to sys.path and then import scripts.lib.setup_path_on_import. +# But this file is also used in development, where the above path will not exist. +# So `import scripts.lib.setup_path_on_import` will raise an ImportError. +# In development, we just want to skip this step since we know that virtualenv will already be in use. +# So catch the ImportError and do nothing. +sys.path.append('/home/zulip/deployments/current') +try: + import scripts.lib.setup_path_on_import +except ImportError: + pass + import psycopg2 import psycopg2.extensions import select diff --git a/puppet/zulip_internal/files/nagios_plugins/zulip_zephyr_mirror/check_user_zephyr_mirror_liveness b/puppet/zulip_internal/files/nagios_plugins/zulip_zephyr_mirror/check_user_zephyr_mirror_liveness index bd5e35bf46..2a64e03ea0 100755 --- a/puppet/zulip_internal/files/nagios_plugins/zulip_zephyr_mirror/check_user_zephyr_mirror_liveness +++ b/puppet/zulip_internal/files/nagios_plugins/zulip_zephyr_mirror/check_user_zephyr_mirror_liveness @@ -13,6 +13,10 @@ import datetime import os import sys +import sys +sys.path.append('/home/zulip/deployments/current') +import scripts.lib.setup_path_on_import + import django os.environ['DJANGO_SETTINGS_MODULE'] = "zproject.settings" diff --git a/puppet/zulip_internal/files/postgresql/pg_backup_and_purge.py b/puppet/zulip_internal/files/postgresql/pg_backup_and_purge.py index 4b884042fa..1cde564439 100644 --- a/puppet/zulip_internal/files/postgresql/pg_backup_and_purge.py +++ b/puppet/zulip_internal/files/postgresql/pg_backup_and_purge.py @@ -1,6 +1,11 @@ #!/usr/bin/env python from __future__ import print_function + +import sys +sys.path.append('/home/zulip/deployments/current') +import scripts.lib.setup_path_on_import + import subprocess import sys import logging diff --git a/puppet/zulip_internal/files/zulip-ec2-configure-interfaces b/puppet/zulip_internal/files/zulip-ec2-configure-interfaces index 6e33d675f1..47210fdcf7 100755 --- a/puppet/zulip_internal/files/zulip-ec2-configure-interfaces +++ b/puppet/zulip_internal/files/zulip-ec2-configure-interfaces @@ -49,6 +49,10 @@ import logging.handlers import subprocess import re +import sys +sys.path.append('/home/zulip/deployments/current') +import scripts.lib.setup_path_on_import + import boto.utils import netifaces from six.moves import range diff --git a/scripts/get-django-setting b/scripts/get-django-setting index 58eaecff6c..1f623b06ef 100755 --- a/scripts/get-django-setting +++ b/scripts/get-django-setting @@ -3,9 +3,13 @@ from __future__ import absolute_import from __future__ import print_function import os +from os.path import dirname, abspath import sys -sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) +BASE_DIR = dirname(dirname(abspath(__file__))) +sys.path.append(BASE_DIR) +import scripts.lib.setup_path_on_import + os.environ['DJANGO_SETTINGS_MODULE'] = 'zproject.settings' from django.conf import settings diff --git a/scripts/lib/log-management-command b/scripts/lib/log-management-command index 3296ad3f69..26615a152b 100755 --- a/scripts/lib/log-management-command +++ b/scripts/lib/log-management-command @@ -2,7 +2,12 @@ import sys import logging import os -sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..")) +from os.path import dirname, abspath + +BASE_DIR = dirname(dirname(dirname(abspath(__file__)))) +sys.path.append(BASE_DIR) +import scripts.lib.setup_path_on_import + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "zproject.settings") from django.conf import settings diff --git a/scripts/lib/setup_path_on_import.py b/scripts/lib/setup_path_on_import.py new file mode 100644 index 0000000000..a843dc2129 --- /dev/null +++ b/scripts/lib/setup_path_on_import.py @@ -0,0 +1,15 @@ +""" +Use libraries from a virtualenv (by modifying sys.path) in production. +Also add Zulip's root directory to sys.path +""" + +import os +from os.path import dirname, abspath +import sys + +BASE_DIR = dirname(dirname(dirname(abspath(__file__)))) +activate_this = os.path.join(BASE_DIR, "zulip-venv", "bin", "activate_this.py") +if os.path.exists(activate_this): + # this file will exist in production + exec(open(activate_this).read(), {}, dict(__file__=activate_this)) # type: ignore # https://github.com/python/mypy/issues/1577 +sys.path.append(BASE_DIR) diff --git a/scripts/setup/generate_secrets.py b/scripts/setup/generate_secrets.py index 6f40419eb7..308dd11e38 100755 --- a/scripts/setup/generate_secrets.py +++ b/scripts/setup/generate_secrets.py @@ -3,8 +3,12 @@ from __future__ import print_function import sys, os, os.path +from os.path import dirname, abspath + +BASE_DIR = dirname(dirname(dirname(abspath(__file__)))) +sys.path.append(BASE_DIR) +import scripts.lib.setup_path_on_import -sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) os.environ['DJANGO_SETTINGS_MODULE'] = 'zproject.settings' from django.utils.crypto import get_random_string diff --git a/zproject/wsgi.py b/zproject/wsgi.py index 2e849f027e..d32a46e5fd 100644 --- a/zproject/wsgi.py +++ b/zproject/wsgi.py @@ -14,6 +14,12 @@ framework. """ import os +from os.path import dirname, abspath +import sys + +BASE_DIR = dirname(dirname(abspath(__file__))) +sys.path.append(BASE_DIR) +import scripts.lib.setup_path_on_import os.environ.setdefault("DJANGO_SETTINGS_MODULE", "zproject.settings")