diff --git a/docs/subsystems/dependencies.md b/docs/subsystems/dependencies.md index 350549224a..f0388fc416 100644 --- a/docs/subsystems/dependencies.md +++ b/docs/subsystems/dependencies.md @@ -184,8 +184,8 @@ highlighting. The system is largely managed by the code in amounts of disk over time. * **Scripts**. Often, we want a script running in production to use the Zulip virtualenv. To make that work without a lot of duplicated - code, we have a helpful library, - `scripts/lib/setup_path_on_import.py`, which on import will put the + code, we have a helpful function, + `scripts.lib.setup_path.setup_path`, which on import will put the currently running Python script into the Zulip virtualenv. This is called by `./manage.py` to ensure that our Django code always uses the correct virtualenv as well. diff --git a/manage.py b/manage.py index 496e6f2701..b36eb1abcf 100755 --- a/manage.py +++ b/manage.py @@ -10,7 +10,10 @@ if sys.version_info <= (3, 0): BASE_DIR = os.path.dirname(os.path.abspath(__file__)) sys.path.append(BASE_DIR) -import scripts.lib.setup_path_on_import +from scripts.lib.setup_path import setup_path + +setup_path() + from scripts.lib.zulip_tools import assert_not_running_as_root if __name__ == "__main__": 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 ad35733b98..e4cb514fe1 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 @@ -17,7 +17,9 @@ import os sys.path.append('.') sys.path.append('/home/zulip/deployments/current') -import scripts.lib.setup_path_on_import +from scripts.lib.setup_path import setup_path + +setup_path() import django 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 29c8b0eb54..8dafa5a1bb 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 @@ -6,7 +6,9 @@ Nagios plugin to check the length of the FTS update log. import sys sys.path.append('/home/zulip/deployments/current') try: - import scripts.lib.setup_path_on_import + from scripts.lib.setup_path import setup_path + + setup_path() except ImportError: pass diff --git a/puppet/zulip/files/postgresql/process_fts_updates b/puppet/zulip/files/postgresql/process_fts_updates index 5225ad9d6c..9518737748 100755 --- a/puppet/zulip/files/postgresql/process_fts_updates +++ b/puppet/zulip/files/postgresql/process_fts_updates @@ -9,14 +9,16 @@ 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. +# So we should add that path to sys.path and then call setup_path. # 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. +# So `from scripts.lib.setup_path import setup_path` 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 + from scripts.lib.setup_path import setup_path + + setup_path() except ImportError: pass diff --git a/puppet/zulip_ops/files/nagios_plugins/zulip_zephyr_mirror/check_user_zephyr_mirror_liveness b/puppet/zulip_ops/files/nagios_plugins/zulip_zephyr_mirror/check_user_zephyr_mirror_liveness index 81ba42d7ea..54902bd5f0 100755 --- a/puppet/zulip_ops/files/nagios_plugins/zulip_zephyr_mirror/check_user_zephyr_mirror_liveness +++ b/puppet/zulip_ops/files/nagios_plugins/zulip_zephyr_mirror/check_user_zephyr_mirror_liveness @@ -11,7 +11,9 @@ import os import sys sys.path.append('/home/zulip/deployments/current') -import scripts.lib.setup_path_on_import +from scripts.lib.setup_path import setup_path + +setup_path() import django from django.utils.timezone import now as timezone_now diff --git a/scripts/get-django-setting b/scripts/get-django-setting index 7933f22a8f..bdd28104a7 100755 --- a/scripts/get-django-setting +++ b/scripts/get-django-setting @@ -4,7 +4,9 @@ import sys BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) -import scripts.lib.setup_path_on_import +from scripts.lib.setup_path import setup_path + +setup_path() os.environ['DJANGO_SETTINGS_MODULE'] = 'zproject.settings' from django.conf import settings diff --git a/scripts/lib/queue_workers.py b/scripts/lib/queue_workers.py index 99dfa6f884..12de371992 100755 --- a/scripts/lib/queue_workers.py +++ b/scripts/lib/queue_workers.py @@ -6,7 +6,9 @@ import sys BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.path.append(BASE_DIR) -import scripts.lib.setup_path_on_import +from scripts.lib.setup_path import setup_path + +setup_path() os.environ['DJANGO_SETTINGS_MODULE'] = 'zproject.settings' diff --git a/scripts/lib/setup_path.py b/scripts/lib/setup_path.py new file mode 100644 index 0000000000..e9416c13a8 --- /dev/null +++ b/scripts/lib/setup_path.py @@ -0,0 +1,16 @@ +""" +Use libraries from a virtualenv (by modifying sys.path) in production. +""" + +import os +import sys + +def setup_path() -> None: + if os.path.basename(sys.prefix) != "zulip-py3-venv": + BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + venv = os.path.join(BASE_DIR, "zulip-py3-venv") + activate_this = os.path.join(venv, "bin", "activate_this.py") + activate_locals = dict(__file__=activate_this) + exec(open(activate_this).read(), activate_locals) + if not os.path.exists(activate_locals["site_packages"]): + raise RuntimeError(venv + " was not set up for this Python version") diff --git a/scripts/lib/setup_path_on_import.py b/scripts/lib/setup_path_on_import.py deleted file mode 100644 index d15ca2a2df..0000000000 --- a/scripts/lib/setup_path_on_import.py +++ /dev/null @@ -1,15 +0,0 @@ -""" -Use libraries from a virtualenv (by modifying sys.path) in production. -""" - -import os -import sys - -if os.path.basename(sys.prefix) != "zulip-py3-venv": - BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - venv = os.path.join(BASE_DIR, "zulip-py3-venv") - activate_this = os.path.join(venv, "bin", "activate_this.py") - activate_locals = dict(__file__=activate_this) - exec(open(activate_this).read(), activate_locals) - if not os.path.exists(activate_locals["site_packages"]): - raise RuntimeError(venv + " was not set up for this Python version") diff --git a/scripts/setup/flush-memcached b/scripts/setup/flush-memcached index 798bb8428e..6bd873fd72 100755 --- a/scripts/setup/flush-memcached +++ b/scripts/setup/flush-memcached @@ -6,7 +6,10 @@ import sys BASE_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../..") sys.path.append(BASE_DIR) -import scripts.lib.setup_path_on_import +from scripts.lib.setup_path import setup_path + +setup_path() + from zproject import settings import pylibmc diff --git a/scripts/setup/generate_secrets.py b/scripts/setup/generate_secrets.py index 72490a20c1..bd64d11f85 100755 --- a/scripts/setup/generate_secrets.py +++ b/scripts/setup/generate_secrets.py @@ -8,7 +8,9 @@ from typing import Dict, List BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.path.append(BASE_DIR) -import scripts.lib.setup_path_on_import +from scripts.lib.setup_path import setup_path + +setup_path() os.environ['DJANGO_SETTINGS_MODULE'] = 'zproject.settings' diff --git a/scripts/setup/restore-backup b/scripts/setup/restore-backup index 3c2b7ca029..028a9ffc5f 100755 --- a/scripts/setup/restore-backup +++ b/scripts/setup/restore-backup @@ -24,7 +24,9 @@ def restore_backup(tarball_file): su_to_zulip(save_suid=True) - import scripts.lib.setup_path_on_import + from scripts.lib.setup_path import setup_path + + setup_path() # First, we unpack the /etc/zulip configuration, so we know how # this server is supposed to be configured (and can import diff --git a/tools/linter_lib/pyflakes.py b/tools/linter_lib/pyflakes.py index c7ea6ecbde..40a8499e20 100644 --- a/tools/linter_lib/pyflakes.py +++ b/tools/linter_lib/pyflakes.py @@ -12,7 +12,6 @@ def check_pyflakes(files, options): # type: (List[str], argparse.Namespace) -> bool suppress_patterns = [ ("scripts/lib/pythonrc.py", "imported but unused"), - ('', "'scripts.lib.setup_path_on_import' imported but unused"), # Intentionally imported by zerver/lib/webhooks/common.py ('', "'zerver.lib.exceptions.UnexpectedWebhookEventType' imported but unused"), diff --git a/tools/update-prod-static b/tools/update-prod-static index c4b2c700a2..65800d15c1 100755 --- a/tools/update-prod-static +++ b/tools/update-prod-static @@ -9,7 +9,10 @@ import sys # We need settings so we can figure out where the prod-static directory is. sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) -import scripts.lib.setup_path_on_import +from scripts.lib.setup_path import setup_path + +setup_path() + os.environ['DJANGO_SETTINGS_MODULE'] = 'zproject.settings' from django.conf import settings from scripts.lib.node_cache import setup_node_modules diff --git a/zproject/wsgi.py b/zproject/wsgi.py index f2793b8d49..0d1253c779 100644 --- a/zproject/wsgi.py +++ b/zproject/wsgi.py @@ -18,7 +18,9 @@ import sys BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) -import scripts.lib.setup_path_on_import +from scripts.lib.setup_path import setup_path + +setup_path() os.environ.setdefault("DJANGO_SETTINGS_MODULE", "zproject.settings")