Import only specific values from project_settings into env.
Created by: qris
Prevents project_settings from accidentally stomping all over env, for example overwriting env.path with garbage.
On this Mac, the first remotely executed sudo
command fails:
[server.compume.qwirx.com:48001] sudo: mkdir -p /var/django/boxcastle
[server.compume.qwirx.com:48001] out: sudo password:
[server.compume.qwirx.com:48001] out: /bin/bash: module: No such file or directory
[server.compume.qwirx.com:48001] out:
Fatal error: sudo() received nonzero return code 1 while executing!
Requested: mkdir -p /var/django/boxcastle
Executed: sudo -S -p 'sudo password:' /bin/bash -l -c "export PATH=\"\$PATH:\"<module 'posixpath' from '/Users/chriswilson/projects/boxcastle/django/website/.ve/lib/python2.7/posixpath.pyc'>\"\" && mkdir -p /var/django/boxcastle"
Aborting.
The PATH statement added to the environment is clearly absurd (some Python internals instead of a list of directories).
Tracing through, I find that env.path is set wrongly here:
> /Users/chriswilson/projects/boxcastle/django/website/.ve/src/dye/dye/fablib.py(17)_setup_paths()
-> for setting in user_settings:
(Pdb) p user_settings
['repo_type', 'host_list', 'requirements_per_env', 'local_vcs_root', 'project_type', 'relative_ve_dir', 'local_requirements_file', 'project_name', 'server_project_home', 'repository', 'default_branch', 'test_cmd', 'webserver', 'user', 'path', 'local_deploy_dir', 'socket', 'use_virtualenv', 'server_home', 'relative_django_dir', 'django_apps', 'relative_django_settings_dir', 'os']
(Pdb) l
12
13
14 def _setup_paths(project_settings):
15 # first merge in variables from project_settings - but ignore __doc__ etc
16 user_settings = [x for x in vars(project_settings).keys() if not x.startswith('__')]
17 -> for setting in user_settings:
18 env[setting] = vars(project_settings)[setting]
19
20 # allow for project_settings having set up some of these differently
21 env.setdefault('verbose', False)
22 env.setdefault('use_sudo', True)
(Pdb) p vars(project_settings)['path']
<module 'posixpath' from '/Users/chriswilson/projects/boxcastle/django/website/.ve/lib/python2.7/posixpath.pyc'>
(Pdb) p vars
<built-in function vars>
(Pdb) p project_settings
<module 'project_settings' from '/Users/chriswilson/projects/boxcastle/deploy/project_settings.pyc'>
(Pdb) p project_settings.path
<module 'posixpath' from '/Users/chriswilson/projects/boxcastle/django/website/.ve/lib/python2.7/posixpath.pyc'>
It seems that fablib.py(17)_setup_paths()
tries to import every single variable defined in project_settings.py
directly into env
. And project_settings.py
does this:
from os import path
which means that project_settings.path
is defined (it points to the posixpath
module that we just imported), and it gets stuffed into env.path
.
We could work around this by undefining path
at the end of project_settings.py
. But I think it makes more sense not to wholesale blat the env
with whatever random crap happens to be in the project_settings
module.
Either we should be explicit about what we export from it, or simply place a reference to project_settings
in env
, so that we can access variables from it when needed, without having to constantly be wary of overwriting env
with anything we do in project_settings
.
This patch imports only certain specific settings from project_settings
into env
. The rest are accessible via env.project
in custom tasks. Lightly tested.