Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Variables sent via 'environment' when using 'django_manage' and 'become_user' are not present in host #5374

Closed
1 task done
jsabater opened this issue Oct 16, 2022 · 28 comments
Labels
bug This issue/PR relates to a bug has_pr module module plugins plugin (any type) traceback web_infrastructure

Comments

@jsabater
Copy link

Summary

have a file with a list of variables and their values, originally templated but now static as I try to debug this issue. It contains a number of variables that are required by Django, such as DJANGO_SECRET_KEY, DJANGO_SITE_NAME, and so on.

I use ansible.builtin.include_vars to load these variables into a variable in the playbook.

I use community.general.django_manage to run the migrate command, using the environment: option to pass the previously loaded variables, but Django complains that it cannot find them.

I've checked with ansible-playbook -vvv and, apparently, they are being sent to the host.

I am not sure whether it has to do with environment: or with using such directive when also using become, become_user and become_method. I have tried with become_method: sudo and the end result is the same.

I've found issue 2568 [1] from 2013 where the proposed solution was using the environment: directive, which is also backed by [the docs](name: envvars), if I've read correctly.

[1] ansible/ansible#2568

Thanks in advance.

Issue Type

Bug Report

Component Name

community.general.django_manage

Ansible Version

$ ansible --version
ansible [core 2.12.9]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.9.2 (default, Feb 28 2021, 17:03:44) [GCC 10.2.1 20210110]
  jinja version = 2.11.3
  libyaml = True

Community.general Version

$ ansible-galaxy collection list community.general
# /usr/lib/python3/dist-packages/ansible_collections
Collection        Version
----------------- -------
community.general 4.8.3  

# /root/.ansible/collections/ansible_collections
Collection        Version
----------------- -------
community.general 5.2.0

Configuration

$ ansible-config dump --only-changed
ANSIBLE_PIPELINING(/etc/ansible/ansible.cfg) = True
CACHE_PLUGIN(/etc/ansible/ansible.cfg) = jsonfile
CACHE_PLUGIN_CONNECTION(/etc/ansible/ansible.cfg) = /var/cache/ansible
DEFAULT_HOST_LIST(/etc/ansible/ansible.cfg) = ['/etc/ansible/hosts']
DEFAULT_PRIVATE_KEY_FILE(/etc/ansible/ansible.cfg) = /root/.ssh/ansible
DEFAULT_REMOTE_PORT(/etc/ansible/ansible.cfg) = 22
DEFAULT_REMOTE_USER(/etc/ansible/ansible.cfg) = root
HOST_KEY_CHECKING(/etc/ansible/ansible.cfg) = False

BECOME:
======

CACHE:
=====

jsonfile:
________
_uri(/etc/ansible/ansible.cfg) = /var/cache/ansible

CALLBACK:
========

CLICONF:
=======

CONNECTION:
==========

local:
_____
pipelining(/etc/ansible/ansible.cfg) = True

paramiko_ssh:
____________
host_key_checking(/etc/ansible/ansible.cfg) = False
remote_user(/etc/ansible/ansible.cfg) = root

psrp:
____
pipelining(/etc/ansible/ansible.cfg) = True

ssh:
___
host_key_checking(/etc/ansible/ansible.cfg) = False
port(/etc/ansible/ansible.cfg) = 22
private_key_file(/etc/ansible/ansible.cfg) = /root/.ssh/ansible
remote_user(/etc/ansible/ansible.cfg) = root
ssh_args(/etc/ansible/ansible.cfg) = -o ControlMaster=auto -o ControlPersist=60s

winrm:
_____
pipelining(/etc/ansible/ansible.cfg) = True

HTTPAPI:
=======

INVENTORY:
=========

LOOKUP:
======

NETCONF:
=======

SHELL:
=====

VARS:
====


### OS / Environment

Debian 11 Bullseye x86_64 running inside a LXC on the latest version of Proxmox 7. The container was created using Proxmox's Debian 11 template, then updated and configured with locales and so on.

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
This is my `host_vars/django1.yml` file:

```yaml
---
# Host variables to be set as environment variables in tasks that need it
POSTGRES_PASSWORD: "<password>"
POSTGRES_USER: "dbuser"
POSTGRES_DB: "dbname"
POSTGRES_HOST: "dbhost"
POSTGRES_PORT: 5432
POSTGRES_SSLMODE: "verify-full"
POSTGRES_SSLCA: "/etc/ssl/certs/ISRG_Root_X1.pem"
POSTGRES_APPNAME: "myproject"
DJANGO_SITE_NAME: "mysite"
DJANGO_SITE_PASSWORD: "mypassword"
DJANGO_SITE_USER: "myuser"
DJANGO_SITE_ID: 2
DJANGO_SECRET_KEY: "<very-long-and-random-secret>"
[..]

This is my playbook:

---
- hosts: django
  tasks:

  - name: builtin | include_vars | load host vars
    ansible.builtin.include_vars:
      file: "host_vars/{{ inventory_hostname_short }}.yml"
      name: envvars

  - name: community.general | django_manage | update database schema
    community.general.django_manage:
      command: migrate
      settings: myproject.settings
      project_path: "/opt/django/src"
      virtualenv: "/opt/django/venv"
    become: true
    become_user: django
    become_method: su
    environment: "{{ envvars }}"

django is a group of hosts, defined in the /etc/ansible/hosts as:

[all]
ansible[1:1].domain.com ansible_connection=local
django[1:3].domain.com

[django]
django1.domain.com ansible_host=192.168.0.112
django2.domain.com ansible_host=192.168.0.119
django3.domain.com ansible_host=192.168.0.120

The playbook is being executed like this:

ansible-playbook django-test.yml --limit django1.domain.com

Expected Results

I expected the command to execute without issues, finding the environment variables sent to do its job.

Actual Results

root@ansible1:~/ansible/playbooks# ansible-playbook django-test.yml --limit django1.domain.com

PLAY [django] ***************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************
ok: [django1.domain.com]

TASK [builtin | include_vars | load host vars] ******************************************************************************
ok: [django1.domain.com]

TASK [community.general | django_manage | update database schema] ***********************************************************
fatal: [django1.domain.com]: FAILED! => {"changed": false, "cmd": ["./manage.py", "migrate", "--noinput", "--settings=myproject.settings"], "msg": "\n:stderr: Traceback (most recent call last):\n  File \"/opt/django/src/./manage.py\", line 22, in <module>\n    execute_from_command_line(sys.argv)\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/core/management/__init__.py\", line 381, in execute_from_command_line\n    utility.execute()\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/core/management/__init__.py\", line 375, in execute\n    self.fetch_command(subcommand).run_from_argv(self.argv)\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/core/management/__init__.py\", line 224, in fetch_command\n    klass = load_command_class(app_name, subcommand)\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/core/management/__init__.py\", line 36, in load_command_class\n    module = import_module('%s.management.commands.%s' % (app_name, name))\n  File \"/usr/lib/python3.9/importlib/__init__.py\", line 127, in import_module\n    return _bootstrap._gcd_import(name[level:], package, level)\n  File \"<frozen importlib._bootstrap>\", line 1030, in _gcd_import\n  File \"<frozen importlib._bootstrap>\", line 1007, in _find_and_load\n  File \"<frozen importlib._bootstrap>\", line 986, in _find_and_load_unlocked\n  File \"<frozen importlib._bootstrap>\", line 680, in _load_unlocked\n  File \"<frozen importlib._bootstrap_external>\", line 790, in exec_module\n  File \"<frozen importlib._bootstrap>\", line 228, in _call_with_frames_removed\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/core/management/commands/migrate.py\", line 14, in <module>\n    from django.db.migrations.autodetector import MigrationAutodetector\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/db/migrations/autodetector.py\", line 11, in <module>\n    from django.db.migrations.questioner import MigrationQuestioner\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/db/migrations/questioner.py\", line 9, in <module>\n    from .loader import MigrationLoader\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/db/migrations/loader.py\", line 8, in <module>\n    from django.db.migrations.recorder import MigrationRecorder\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/db/migrations/recorder.py\", line 9, in <module>\n    class MigrationRecorder:\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/db/migrations/recorder.py\", line 22, in MigrationRecorder\n    class Migration(models.Model):\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/db/models/base.py\", line 87, in __new__\n    app_config = apps.get_containing_app_config(module)\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/apps/registry.py\", line 249, in get_containing_app_config\n    self.check_apps_ready()\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/apps/registry.py\", line 131, in check_apps_ready\n    settings.INSTALLED_APPS\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/conf/__init__.py\", line 57, in __getattr__\n    self._setup(name)\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/conf/__init__.py\", line 44, in _setup\n    self._wrapped = Settings(settings_module)\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/conf/__init__.py\", line 126, in __init__\n    raise ImproperlyConfigured(\"The SECRET_KEY setting must not be empty.\")\ndjango.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.\n", "path": "/opt/django/venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "syspath": ["/tmp/ansible_community.general.django_manage_payload_73j09wsy/ansible_community.general.django_manage_payload.zip", "/usr/lib/python39.zip", "/usr/lib/python3.9", "/usr/lib/python3.9/lib-dynload", "/usr/local/lib/python3.9/dist-packages", "/usr/lib/python3/dist-packages"]}

PLAY RECAP ******************************************************************************************************************
django1.domain.com    : ok=2    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

This is an excerpt of the output using -vvv:

<192.168.0.112> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.0.112> SSH: EXEC ssh -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/root/.ssh/ansible"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostmysited,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o 'ControlPath="/root/.ansible/cp/c2c620c89f"' 192.168.0.112 '/bin/sh -c '"'"'chmod u+x /var/tmp/ansible-tmp-1665912071.0601845-67543-122560791410458/ /var/tmp/ansible-tmp-1665912071.0601845-67543-122560791410458/AnsiballZ_django_manage.py && sleep 0'"'"''
<192.168.0.112> (0, b'', b'')
<192.168.0.112> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.0.112> SSH: EXEC ssh -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/root/.ssh/ansible"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostmysited,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o 'ControlPath="/root/.ansible/cp/c2c620c89f"' 192.168.0.112 '/bin/sh -c '"'"'chown django /var/tmp/ansible-tmp-1665912071.0601845-67543-122560791410458/ /var/tmp/ansible-tmp-1665912071.0601845-67543-122560791410458/AnsiballZ_django_manage.py && sleep 0'"'"''
<192.168.0.112> (0, b'', b'')
<192.168.0.112> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.0.112> SSH: EXEC ssh -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/root/.ssh/ansible"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostmysited,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o 'ControlPath="/root/.ansible/cp/c2c620c89f"' -tt 192.168.0.112 '/bin/sh -c '"'"'su  django -c '"'"'"'"'"'"'"'"'/bin/sh -c '"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'echo BECOME-SUCCESS-ptxrsvpoyqfxqmgdubcktnnnaljwmagj ; POSTGRES_PASSWORD=<password> POSTGRES_USER=django_mysite POSTGRES_DB=django_mysite POSTGRES_HOST=dbhost.domain.com POSTGRES_PORT=5432 POSTGRES_SSLMODE=verify-full POSTGRES_SSLCA=/etc/ssl/certs/ISRG_Root_X1.pem POSTGRES_APPNAME=myproject DJANGO_SITE_NAME=mysite DJANGO_SITE_PASSWORD=mysite DJANGO_SITE_USER=mysite DJANGO_SITE_ID=2 DJANGO_SECRET_KEY='"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'<very-long-and-random-secret>'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"' META_SITE_PROTOCOL=https PUBLIC_URL=https://mysite.customer.com GOOGLE_MAPS_API_KEY=<api-key> RECAPTCHA_PUBLIC_KEY=<recaptcha-api-key> RECAPTCHA_PRIVATE_KEY=<recaptcha-private-key> RECAPTCHA_SCORE_THRESHOLD=0.6 PREFIX_DEFAULT_LANGUAGE=1 INSTALLED_CUSTOM_APPS=None INSTALLED_CUSTOM_REPOS=None DJANGO_DEBUG=0 DJANGO_SETTINGS_MODULE=myproject.settings.production DJANGO_LOGS_DIR=/opt/django/logs DJANGO_STATIC_mysite=/opt/django/static DJANGO_MEDIA_mysite=/opt/django/media /usr/bin/python3 /var/tmp/ansible-tmp-1665912071.0601845-67543-122560791410458/AnsiballZ_django_manage.py'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"''"'"'"'"'"'"'"'"' && sleep 0'"'"''
Escalation succeeded
<192.168.0.112> (1, b'\r\n{"cmd": ["./manage.py", "migrate", "--noinput", "--settings=myproject.settings"], "path": "/opt/django/venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "syspath": ["/tmp/ansible_community.general.django_manage_payload_tjoxkqd3/ansible_community.general.django_manage_payload.zip", "/usr/lib/python39.zip", "/usr/lib/python3.9", "/usr/lib/python3.9/lib-dynload", "/usr/local/lib/python3.9/dist-packages", "/usr/lib/python3/dist-packages"], "failed": true, "msg": "\\n:stderr: Traceback (most recent call last):\\n  File \\"/opt/django/src/./manage.py\\", line 22, in <module>\\n    execute_from_command_line(sys.argv)\\n  File \\"/opt/django/venv/lib/python3.9/site-packages/django/core/management/__init__.py\\", line 381, in execute_from_command_line\\n    utility.execute()\\n  File \\"/opt/django/venv/lib/python3.9/site-packages/django/core/management/__init__.py\\", line 375, in execute\\n    self.fetch_command(subcommand).run_from_argv(self.argv)\\n  File \\"/opt/django/venv/lib/python3.9/site-packages/django/core/management/__init__.py\\", line 224, in fetch_command\\n    klass = load_command_class(app_name, subcommand)\\n  File \\"/opt/django/venv/lib/python3.9/site-packages/django/core/management/__init__.py\\", line 36, in load_command_class\\n    module = import_module(\'%s.management.commands.%s\' % (app_name, name))\\n  File \\"/usr/lib/python3.9/importlib/__init__.py\\", line 127, in import_module\\n    return _bootstrap._gcd_import(name[level:], package, level)\\n  File \\"<frozen importlib._bootstrap>\\", line 1030, in _gcd_import\\n  File \\"<frozen importlib._bootstrap>\\", line 1007, in _find_and_load\\n  File \\"<frozen importlib._bootstrap>\\", line 986, in _find_and_load_unlocked\\n  File \\"<frozen importlib._bootstrap>\\", line 680, in _load_unlocked\\n  File \\"<frozen importlib._bootstrap_external>\\", line 790, in exec_module\\n  File \\"<frozen importlib._bootstrap>\\", line 228, in _call_with_frames_removed\\n  File \\"/opt/django/venv/lib/python3.9/site-packages/django/core/management/commands/migrate.py\\", line 14, in <module>\\n    from django.db.migrations.autodetector import MigrationAutodetector\\n  File \\"/opt/django/venv/lib/python3.9/site-packages/django/db/migrations/autodetector.py\\", line 11, in <module>\\n    from django.db.migrations.questioner import MigrationQuestioner\\n  File \\"/opt/django/venv/lib/python3.9/site-packages/django/db/migrations/questioner.py\\", line 9, in <module>\\n    from .loader import MigrationLoader\\n  File \\"/opt/django/venv/lib/python3.9/site-packages/django/db/migrations/loader.py\\", line 8, in <module>\\n    from django.db.migrations.recorder import MigrationRecorder\\n  File \\"/opt/django/venv/lib/python3.9/site-packages/django/db/migrations/recorder.py\\", line 9, in <module>\\n    class MigrationRecorder:\\n  File \\"/opt/django/venv/lib/python3.9/site-packages/django/db/migrations/recorder.py\\", line 22, in MigrationRecorder\\n    class Migration(models.Model):\\n  File \\"/opt/django/venv/lib/python3.9/site-packages/django/db/models/mysite.py\\", line 87, in __new__\\n    app_config = apps.get_containing_app_config(module)\\n  File \\"/opt/django/venv/lib/python3.9/site-packages/django/apps/registry.py\\", line 249, in get_containing_app_config\\n    self.check_apps_ready()\\n  File \\"/opt/django/venv/lib/python3.9/site-packages/django/apps/registry.py\\", line 131, in check_apps_ready\\n    settings.INSTALLED_APPS\\n  File \\"/opt/django/venv/lib/python3.9/site-packages/django/conf/__init__.py\\", line 57, in __getattr__\\n    self._setup(name)\\n  File \\"/opt/django/venv/lib/python3.9/site-packages/django/conf/__init__.py\\", line 44, in _setup\\n    self._wrapped = Settings(settings_module)\\n  File \\"/opt/django/venv/lib/python3.9/site-packages/django/conf/__init__.py\\", line 126, in __init__\\n    raise ImproperlyConfigured(\\"The SECRET_KEY setting must not be empty.\\")\\ndjango.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.\\n", "invocation": {"module_args": {"command": "migrate", "settings": "myproject.settings", "project_path": "/opt/django/src", "virtualenv": "/opt/django/venv", "clear": false, "failfast": false, "pythonpath": null, "apps": null, "cache_table": null, "datamysite": null, "fixtures": null, "testrunner": null, "skip": null, "merge": null, "link": null}}}\r\n', b'Shared connection to 192.168.0.112 closed.\r\n')
<192.168.0.112> Failed to connect to the host via ssh: Shared connection to 192.168.0.112 closed.
<192.168.0.112> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.0.112> SSH: EXEC ssh -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/root/.ssh/ansible"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostmysited,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o 'ControlPath="/root/.ansible/cp/c2c620c89f"' 192.168.0.112 '/bin/sh -c '"'"'rm -f -r /var/tmp/ansible-tmp-1665912071.0601845-67543-122560791410458/ > /dev/null 2>&1 && sleep 0'"'"''
<192.168.0.112> (0, b'', b'')
fatal: [django1.domain.com]: FAILED! => {
    "changed": false,
    "cmd": [
        "./manage.py",
        "migrate",
        "--noinput",
        "--settings=myproject.settings"
    ],
    "invocation": {
        "module_args": {
            "apps": null,
            "cache_table": null,
            "clear": false,
            "command": "migrate",
            "datamysite": null,
            "failfast": false,
            "fixtures": null,
            "link": null,
            "merge": null,
            "project_path": "/opt/django/src",
            "pythonpath": null,
            "settings": "myproject.settings",
            "skip": null,
            "testrunner": null,
            "virtualenv": "/opt/django/venv"
        }
    },
    "msg": "\n:stderr: Traceback (most recent call last):\n  File \"/opt/django/src/./manage.py\", line 22, in <module>\n    execute_from_command_line(sys.argv)\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/core/management/__init__.py\", line 381, in execute_from_command_line\n    utility.execute()\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/core/management/__init__.py\", line 375, in execute\n    self.fetch_command(subcommand).run_from_argv(self.argv)\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/core/management/__init__.py\", line 224, in fetch_command\n    klass = load_command_class(app_name, subcommand)\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/core/management/__init__.py\", line 36, in load_command_class\n    module = import_module('%s.management.commands.%s' % (app_name, name))\n  File \"/usr/lib/python3.9/importlib/__init__.py\", line 127, in import_module\n    return _bootstrap._gcd_import(name[level:], package, level)\n  File \"<frozen importlib._bootstrap>\", line 1030, in _gcd_import\n  File \"<frozen importlib._bootstrap>\", line 1007, in _find_and_load\n  File \"<frozen importlib._bootstrap>\", line 986, in _find_and_load_unlocked\n  File \"<frozen importlib._bootstrap>\", line 680, in _load_unlocked\n  File \"<frozen importlib._bootstrap_external>\", line 790, in exec_module\n  File \"<frozen importlib._bootstrap>\", line 228, in _call_with_frames_removed\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/core/management/commands/migrate.py\", line 14, in <module>\n    from django.db.migrations.autodetector import MigrationAutodetector\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/db/migrations/autodetector.py\", line 11, in <module>\n    from django.db.migrations.questioner import MigrationQuestioner\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/db/migrations/questioner.py\", line 9, in <module>\n    from .loader import MigrationLoader\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/db/migrations/loader.py\", line 8, in <module>\n    from django.db.migrations.recorder import MigrationRecorder\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/db/migrations/recorder.py\", line 9, in <module>\n    class MigrationRecorder:\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/db/migrations/recorder.py\", line 22, in MigrationRecorder\n    class Migration(models.Model):\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/db/models/mysite.py\", line 87, in __new__\n    app_config = apps.get_containing_app_config(module)\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/apps/registry.py\", line 249, in get_containing_app_config\n    self.check_apps_ready()\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/apps/registry.py\", line 131, in check_apps_ready\n    settings.INSTALLED_APPS\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/conf/__init__.py\", line 57, in __getattr__\n    self._setup(name)\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/conf/__init__.py\", line 44, in _setup\n    self._wrapped = Settings(settings_module)\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/conf/__init__.py\", line 126, in __init__\n    raise ImproperlyConfigured(\"The SECRET_KEY setting must not be empty.\")\ndjango.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.\n",
    "path": "/opt/django/venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
    "syspath": [
        "/tmp/ansible_community.general.django_manage_payload_tjoxkqd3/ansible_community.general.django_manage_payload.zip",
        "/usr/lib/python39.zip",
        "/usr/lib/python3.9",
        "/usr/lib/python3.9/lib-dynload",
        "/usr/local/lib/python3.9/dist-packages",
        "/usr/lib/python3/dist-packages"
    ]
}

Code of Conduct

  • I agree to follow the Ansible Code of Conduct
@ansibullbot
Copy link
Collaborator

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help

@ansibullbot
Copy link
Collaborator

cc @russoz
click here for bot help

@ansibullbot ansibullbot added bug This issue/PR relates to a bug module module plugins plugin (any type) traceback web_infrastructure labels Oct 16, 2022
@jsabater
Copy link
Author

I just realised of this bit in the documentation of django_manage:

The below requirements are needed on the host that executes this module.

  • virtualenv
  • django

Later, in the notes section, there is this:

virtualenv (http://www.virtualenv.org/) must be installed on the remote host if the virtualenv parameter is specified.

I just realised that I forgot to mention that my virtual environment was created using Python 3 venv:

python3 -m venv ~/venv
python -m pip install --trusted-host pypi.org --upgrade pip

Does django_manage support Python 3 venv as well as virtualenv?

@jsabater
Copy link
Author

I just checked the code and, if I am not mistaken, I see that it's checking for the existence of bin/activate but it's not sourcing it.

Not that it has anything to do with this issue, but I had hoped to export the necessary Django variables inside the bin/activate script as a workaround...

@jsabater
Copy link
Author

jsabater commented Oct 17, 2022

This is a modified playbook I am running now, to try and see what is happening.

  1. django-setup.yml playbook:
---
- hosts: django
  tasks:
  - ansible.builtin.import_tasks: tasks/django/manage.yml
  1. tasks/django/manage.yml:
- name: builtin | template | template host variables file
  ansible.builtin.template:
    src: templates/django/hostvars.j2
    dest: "host_vars/{{ inventory_hostname_short }}.yml"
    mode: 0640
    output_encoding: "utf-8"
  delegate_to: localhost

- name: builtin | include_vars | load host vars into the 'envvars' variable
  ansible.builtin.include_vars:
    file: "host_vars/{{ inventory_hostname_short }}.yml"
    name: envvars
  1. The contents of host_vars/django1.yml have not changed and include the list of variables:
---
# Host variables to be set as environment variables in tasks that need it
POSTGRES_PASSWORD: "<password>"
POSTGRES_USER: "dbuser"
POSTGRES_DB: "dbname"
POSTGRES_HOST: "dbhost"
POSTGRES_PORT: 5432
POSTGRES_SSLMODE: "verify-full"
POSTGRES_SSLCA: "/etc/ssl/certs/ISRG_Root_X1.pem"
POSTGRES_APPNAME: "myproject"
DJANGO_SITE_NAME: "mysite"
DJANGO_SITE_PASSWORD: "mypassword"
DJANGO_SITE_USER: "myuser"
DJANGO_SITE_ID: 2
DJANGO_SECRET_KEY: "<very-long-and-random-secret>"
[..]
  1. The tasks/django/manage.yml tasks file:
- name: builtin | shell | capture DJANGO_ environment variables
  debugger: on_failed
  ansible.builtin.shell:
    cmd: "env | grep DJANGO_"
  register: out
  environment: "{{ envvars }}"
  become: true
  become_user: django
  become_method: su

- name: builtin | debug | pinrt content of out.stdout
  ansible.builtin.debug:
    var: out.stdout

- name: builtin | debug | print variable 'envvars'
  ansible.builtin.debug:
    var: envvars

- name: community.general | django_manage | populate the static subdirectory
  community.general.django_manage:
    command: collectstatic
    clear: yes
    project_path: "/opt/django/src"
    virtualenv: "/opt/django/venv"
  become: true
  become_user: django
  become_method: su
  environment: "{{ envvars }}"

Only the last task is failing. Here is the output:

TASK [builtin | shell | capture DJANGO_ environment variables] *************************************************************************************************************
changed: [django1.donmain.com]

TASK [builtin | debug | pinrt content of out.stdout] ***********************************************************************************************************************
ok: [django1.django.com] => {
    "out.stdout": "DJANGO_SITE_USER=mysite\nDJANGO_MEDIA_BASE=/opt/django/media\nDJANGO_SITE_NAME=mysite\nDJANGO_SITE_ID=2\nDJANGO_SECRET_KEY=<very-secret-key>\nDJANGO_LOGS_DIR=/opt/django/logs\nDJANGO_SETTINGS_MODULE=myproject.settings.production\nDJANGO_DEBUG=0\nDJANGO_STATIC_BASE=/opt/django/static\nDJANGO_SITE_PASSWORD=mypassword\nDJANGO_SITE_VERSION=57a2f3c168d86243f03809e5d02a0f50a8fa892e"
}

TASK [builtin | debug | print variable 'envvars'] **************************************************************************************************************************
ok: [django1.domain.com] => {
    "envvars": {
        "DJANGO_DEBUG": 0,
        "DJANGO_LOGS_DIR": "/opt/django/logs",
        "DJANGO_MEDIA_BASE": "/opt/django/media",
        "DJANGO_SECRET_KEY": "<very-secret-key>",
        "DJANGO_SETTINGS_MODULE": "myproject.settings.production",
        "DJANGO_SITE_ID": 2,
        "DJANGO_SITE_NAME": "mysite",
        "DJANGO_SITE_PASSWORD": "mypassword",
        "DJANGO_SITE_USER": "myuser",
        [..]
    }
}

TASK [community.general | django_manage | populate the static subdirectory] ************************************************************************************************
fatal: [django1.domain.com]: FAILED! => {"changed": false, "cmd": ["./manage.py", "collectstatic", "--noinput", "--clear"], "msg": "\n:stderr: Traceback (most recent call last):\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/core/management/__init__.py\", line 204, in fetch_command\n    app_name = commands[subcommand]\nKeyError: 'collectstatic'\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n  File \"/opt/django/src/./manage.py\", line 22, in <module>\n    execute_from_command_line(sys.argv)\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/core/management/__init__.py\", line 381, in execute_from_command_line\n    utility.execute()\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/core/management/__init__.py\", line 375, in execute\n    self.fetch_command(subcommand).run_from_argv(self.argv)\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/core/management/__init__.py\", line 211, in fetch_command\n    settings.INSTALLED_APPS\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/conf/__init__.py\", line 57, in __getattr__\n    self._setup(name)\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/conf/__init__.py\", line 44, in _setup\n    self._wrapped = Settings(settings_module)\n  File \"/opt/django/venv/lib/python3.9/site-packages/django/conf/__init__.py\", line 107, in __init__\n    mod = importlib.import_module(self.SETTINGS_MODULE)\n  File \"/usr/lib/python3.9/importlib/__init__.py\", line 127, in import_module\n    return _bootstrap._gcd_import(name[level:], package, level)\n  File \"<frozen importlib._bootstrap>\", line 1030, in _gcd_import\n  File \"<frozen importlib._bootstrap>\", line 1007, in _find_and_load\n  File \"<frozen importlib._bootstrap>\", line 986, in _find_and_load_unlocked\n  File \"<frozen importlib._bootstrap>\", line 680, in _load_unlocked\n  File \"<frozen importlib._bootstrap_external>\", line 790, in exec_module\n  File \"<frozen importlib._bootstrap>\", line 228, in _call_with_frames_removed\n  File \"/opt/django/src/black_pearl/settings/production.py\", line 3, in <module>\n    from black_pearl.settings.common import *\n  File \"/opt/django/src/black_pearl/settings/common.py\", line 301, in <module>\n    path_app = import_module(app).__path__\n  File \"/usr/lib/python3.9/importlib/__init__.py\", line 127, in import_module\n    return _bootstrap._gcd_import(name[level:], package, level)\nModuleNotFoundError: No module named 'None'\n", "path": "/opt/django/venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "syspath": ["/tmp/ansible_community.general.django_manage_payload_l53eeo4g/ansible_community.general.django_manage_payload.zip", "/usr/lib/python39.zip", "/usr/lib/python3.9", "/usr/lib/python3.9/lib-dynload", "/usr/local/lib/python3.9/dist-packages", "/usr/lib/python3/dist-packages"]}

PLAY RECAP *****************************************************************************************************************************************************************
django1.domain.com    : ok=14   changed=1    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

This is being executed as:

ansible-playbook django-setup.yml --limit django1.domain.com

May it be happening that, when django_manage runs manage.py --clear [..] the environment variables are not being "passed over"?

@russoz
Copy link
Collaborator

russoz commented Oct 18, 2022

Hi @jsabater thanks for your detailed report. I will be taking a look at it throughout this week.

@russoz
Copy link
Collaborator

russoz commented Oct 18, 2022

Hi @jsabater I am glancing over this right now, couple of answers and thoughts:

  • No, it does not look like the code uses python -m venv at all. This is something easily fixed. It must be noticed that this command is only executed if the virtual env does not exist yet.
  • It does not run the activate script, but if you follow a couple of lines down the code you'll see it changes the PATH variable and sets the VIRTUAL_ENV variable. I have not tested this aspect of the module much, since I took over it, so it is definitely something we should write a test for.
  • I know that sudo, by default, will clean up env variables before calling the privileged command. Any chance that is your case? Not sure if su does the same thing, but it's not too far off a possibility.

@jsabater
Copy link
Author

Dear @russoz,

  • The virtual environment already exists by the time django_manage is used. I can see this being a common situation, but I agree that adding support for Python 3's venv would be useful and easy to do.

  • Yes, I noticed the VIRTUAL_ENV and PATH variables being set. That is necessary before executing manage.py, and seems the correct thing to do in my opinion, but I think that the ~/venv/bin/activate script often does (or could do, generally speaking) more than setting the VIRTUAL_ENV variable (e.g. setting environment variables), hence the reason of my comment. However, this is just a side comment, not the main reason of the issue.

  • I tried adding the become_flags:option, both with --login and --login --shell=/bin/bash, for the become_method: su, without success. I use su as method because I connect as root. I even tried adding the variables in the ~/.profile file of the django user, and they are there when I su - django inside the container, but for some reason they don't seem to be present or passed over to migrate.py when Ansible is executing the task.

Also, for your information, I forgot to mention that I also tried passing the variables explicitly, without success:

- name: community.general | django_manage | populate the static subdirectory
  community.general.django_manage:
    command: collectstatic
    clear: yes
    project_path: "/opt/django/src"
    virtualenv: "/opt/django/venv"
  become: true
  become_user: django
  become_method: su
  environment:
    DJANGO_DEBUG: 0,
    DJANGO_LOGS_DIR: "/opt/django/logs",
    DJANGO_MEDIA_BASE: "/opt/django/media",
    DJANGO_SECRET_KEY: "<very-secret-key>",
    DJANGO_SETTINGS_MODULE: "myproject.settings.production",
    DJANGO_SITE_ID: 2,
    DJANGO_SITE_NAME: "mysite",
    DJANGO_SITE_PASSWORD: "mypassword",
    DJANGO_SITE_USER: "myuser",
    [..]

I tried both as it appears here (a dictionary, if I am not mistaken), and using scores (a list of very small dictionaries, if I am not mistaken).

@jsabater
Copy link
Author

I gave the playbook a try using these options:

become: true
become_user: django
become_method: sudo
become_flags: "--login"

But no success either. I went to the container and, as root, executed the following command:

~# sudo --login -u django env

The output of the command was correct, as it included all the environment variables that are being set at the ~/.profile file (DJANGO_SITE_NAME, DJANGO_SITE_USER, and so on).

@russoz
Copy link
Collaborator

russoz commented Oct 18, 2022

Hi @jsabater

Thanks for the further examples. I expect to have more time for this on Friday this week, but will try to make some progress before that.

@russoz
Copy link
Collaborator

russoz commented Oct 18, 2022

Ah, @jsabater probably not going to affect anything, but just for the sake of completeness when I reproduce the error, what version of Django are you using?

@jsabater
Copy link
Author

Right now the requirements file says Django==2.1.15, but I see lots of dependencies that the devs are using:

~# grep -i django requirements.txt 
Django==2.1.15
django-cms==3.7.4
djangocms-installer==1.2.3
djangocms-admin-style==1.5
django-treebeard==4.3.1
django-parler==2.1
djangocms-bootstrap4==1.6.0 # bootsrap4 cms plugins
djangocms-text-ckeditor==3.10.0 # rich text areas
djangocms-link==2.6.1 # for link cms plugins, required by bootsrap4
djangocms-style==2.3.0
djangocms-googlemap==1.4.0
djangocms-snippet==2.3.0
djangocms-video==2.3.0
djangocms-column==1.11.0
djangocms-file==2.4.0
djangocms-picture==2.4.0
djangocms-page-meta==1.0.1
djangocms-page-sitemap==0.8.1
djangocms-redirect==0.5.0
djangocms-blog==1.2.3
djangocms-transfer
django-admin-sortable==2.2.3
django-classy-tags==1.0.0
django-colorfield==0.3.2
django-compressor==2.4
django-enumchoicefield==2.0.0
django-filer==1.7.1
django-meta==2.0.0
django-privacy-mgmt==0.0.20
djangorestframework==3.11.2
django-recaptcha3==0.2.0
django-robots==4.0
django-sass-processor==0.8
django-sekizai==1.1.0
django-solo==1.1.3
django-flatpickr==1.0.1
django-payments==0.13.0
django-payments-redsys==0.3.post1
django-pwa==1.0.10

@jsabater
Copy link
Author

jsabater commented Oct 18, 2022

Also, for your information, for the time being I've resorted to this in order to have a working playbook:

  1. Template a ~/.environment file with all the exports of the environment variables.
  2. Use ansible.builtin.blockinfile to load that file from ~/.profile.
  3. Use ansible.builtin.shell to source the ~/venv/bin/activate and run ./manage.py.

The environment variables set by the ~/.profile are there and the shell execution of manage.py is working fine:

- name: builtin | shell | run 'manage.py migrate'
  ansible.builtin.shell:
    cmd: ". /opt/django/venv/bin/activate; /opt/django/src/manage.py migrate"
    chdir: /opt/django/src/
  become: true
  become_user: django
  become_method: su
  become_flags: '--login'

- name: builtin | shell | run 'manage.py collectstatic'
  ansible.builtin.shell:
    cmd: ". /opt/django/venv/bin/activate; /opt/django/src/manage.py collectstatic --clear --no-input"
    chdir: /opt/django/src/
  become: true
  become_user: django
  become_method: su
  become_flags: '--login'

[..]

Hopefully we'll be able to resolve this issue and be able to use django_manage. Incidenally, out of curiosity, does django_manage achieve idempotence or does manage.py get executed every time, passing the responsibility to detect what needs to be done onto it?

Please let me know if you require anything else. I can provide the full playbook, if needed, and even the source code of the project.

@jsabater
Copy link
Author

I just realised how old the version is and I've requested them to update to the latest. I'll try and run the same playbook on the latest version of Django as soon as possible, just in case the source of the error could be there, and get back to you.

@russoz
Copy link
Collaborator

russoz commented Oct 18, 2022

I very much doubt that will fix the issue, but yeah, upgrading that is definitely a good idea.

@russoz
Copy link
Collaborator

russoz commented Oct 20, 2022

As to your idempotency question, I believe it does indeed delegate that aspect to manage.py. As a matter of fact, I reckon that it would be quite a challenge to provide idempotency to all manage.py subcommands.

@russoz
Copy link
Collaborator

russoz commented Oct 21, 2022

@jsabater I am looking for examples show Django using env vars and the ones I found[1] seem to point to:

  • Use pip install django-environ
  • And then one can use something like:
    SECRET_KEY = env("SECRET_KEY")
    inside the settings.py file.

However, I do not see that package in your requirements, nor have you shown exactly how the env vars are being used. On top of that, I could not help noticing that in the error message on the output of the playbook presented above the reported problem is a failed import in Python. Could you please paste an excerpt of your settings.py showing the use of env vars, and particularly how it is causing an import error?

I am thinking of adding your case to test files under tests/integration/targets/django_manage/files so that we can reproduce the error in the automated tests.

[1] https://djangocentral.com/environment-variables-in-django/

@jsabater
Copy link
Author

Dear, @russoz! I just went through all the files inside the myproject/settings/ directory. I have also browsed through the source code of the django-environ project.

While I have to admit that loading the environment variables (a.k.a. settings) from a file rather than the shell environment is (and always has been, generally speaking) my preferred solution, it is just one way to do things, and should not alter the issue at hand.

Nonetheless, I've taken the chance to convince the devs of the Django application to change the way variables are loaded so that:

  • They first look for a settings.env file and try to load each variable from there (ala django-environ [1]).
  • If it is not available, then they will use os.getenv() to load the value, which is what they are doing right now. All the currently deployed websites will follow that pattern until they are migrated to the new cluster (Docker -> LXC).
  • Finally, they will provide a default value, which they already do, when possible, e.g. LOGS_DIR = os.getenv('DJANGO_LOGS_DIR', '/opt/django/logs').

So, answering your question, they way env vars are being used right now is:

  1. env_file directive in a docker-compose.yml file loads a file of KEY=value lines and sets the environment variables when starting the container.
  2. gunicorn is executed and given a myproject.wsgi file, which imports myproject/settings/production.py, which imports myproject/settings/common.py.
  3. Environment variables are being loaded in both production.py and common.py via sentences like:
SECRET_KEY = os.getenv('DJANGO_SECRET_KEY')
SITE_ID = int(os.getenv("DJANGO_SITE_ID", 1))
SITE_NAME = os.getenv('DJANGO_SITE_NAME') or os.getenv('USER')
LOGS_DIR = os.getenv('DJANGO_LOGS_DIR', '/opt/django/logs')

And used or altered, then used, as the devs see fit.

When running commands such as ./manage.py migrate from the console, the environment variables are already there (running docker exec or via docker-compose), so everything works fine.

[1] Incidentally, I've instructed them not to use django-environ because I think it's one more dependency to add to the project just for that simple open-a-file-read-lines task, but that is just my preferred way of working (no pun intended).

@jsabater
Copy link
Author

Regarding the exception being thrown (failed import), it made me wonder whether django_manage was not being able to load the project settings approriately, so:

  1. I checked the community.general.django_manage documentation regarding the setttings parametre and this is what it says:

The Python path to the application’s settings module, such as myapp.settings

My playbook has this value, as you can see in this thread: settings: myproject.settings

Then I opened the manage.py file of the project and found this code:

#!/usr/bin/env python
import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "black_pearl.settings.development")
    try:
        from django.core.management import execute_from_command_line
[..]

Then I checked the environment variables:

$ env | grep DJANGO_SETTINGS_MODULE
DJANGO_SETTINGS_MODULE=myproject.settings.production

So when you use the console to run the command ./manage.py migrate, it takes the value from the environment variable and performs correctly, both in development and production environments. But since the variable is apparently not there (a.k.a. the reason for this issue), it fails.

Finally, just out of curiosity, I changed the value of the settings directive from myproject.settings to myproject.settings.production in the following, small-version-of-the-real-thing playbook:

---
- hosts: django1.domain.com
  tasks:

  - name: builtin | include_vars | load host vars
    ansible.builtin.include_vars:
      file: "host_vars/{{ inventory_hostname_short }}.yml"
      name: envvars

  - name: community.general | django_manage | update database schema
    community.general.django_manage:
      command: migrate
      settings: black_pearl.settings.production
      project_path: "/opt/django/src"
      virtualenv: "/opt/django/venv"
    become: true
    become_user: django
    become_method: su
    become_flags: '--login'
    environment: "{{ envvars }}"

And got the following error:

# ansible-playbook django-test.yml 

PLAY [django1.domain.com] ********************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************************************************************************************************************
ok: [django1.domain.com]

TASK [builtin | include_vars | load host vars] ****************************************************************************************************************************************************************************************************
ok: [django1.domain.com]

TASK [community.general | django_manage | update database schema] *********************************************************************************************************************************************************************************
fatal: [django1.domain.com]: FAILED! => {"changed": false, "msg": "Failed to find required executable \"virtualenv\" in paths: /usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/sbin:/usr/sbin:/usr/local/sbin"}

PLAY RECAP ****************************************************************************************************************************************************************************************************************************************
django1.domain.com    : ok=2    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

I hope that it provides a hint or helps somehow :-)

@jsabater
Copy link
Author

Incidentally, since this thread is becoming fairly dense in terms of information and details, I provided the latest test bed and error (Failed to find required executable "virtualenv" in paths) because, as stated across the thread, the Python virtual environment was not created using virtualenv but rather python3 -m venv, as follows:

---
- name: builtin | pip | create virtual environment and upgrade pip
  ansible.builtin.pip:
    name: pip
    state: latest
    virtualenv: /opt/django/venv
    virtualenv_command: /usr/bin/python3 -m venv
    extra_args: "--quiet --no-cache-dir --trusted-host pypi.org"
  become: true
  become_user: django
  become_method: su
  environment:
    https_proxy: "{{ http_proxy_url }}"

@russoz
Copy link
Collaborator

russoz commented Oct 21, 2022

Hi @jsabater I wrote a Python3-version of the code to ensure a virtual environment is built, and I started wondering why I was having a bad gut feeling about it. And I noted that:

  1. In the spirit of "small specialized tools" from "Unix philosophy", we are trying to solve the problem "build a virtualenv" inside the module that is supposed to "manage django apps", so that sounds like a bad idea from the start.
  2. Suppose we have a pristine server where we run this module. No venv exists, so this module will ensure one is there. However, at a bare minimum, a virtualenv used to run ./manage.py should have Django installed in it, and the new virtualenv does not!!! Now, if we decide to "solve" that by, hey, installing django in that venv from within this module, not only we make problem 1 above worse, but we also create further problems: which version should be installed? what other packages must be installed in that venv?

Given that, I think we should deprecate the behaviour "create venv if one does not exist". The responsibility for creating and populating correctly the venv does not belong to this module. Additionally that would remove the dependency with virtualenv and ditch the debate on python -m venv.

What do you think?

@jsabater
Copy link
Author

jsabater commented Oct 22, 2022 via email

@jsabater
Copy link
Author

jsabater commented Nov 5, 2022

Just a heads up that the dev team ended up importing variables from a settings.env file in the myproject/settings/production.py, so now django_manage is running without issues.

How did those tests go? Any news on why the environment variables are not reaching the final ./manage.py command?

I saw that the pull request was merged into the next version of community.general. Thanks for your work.

@ansibullbot
Copy link
Collaborator

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help

@russoz
Copy link
Collaborator

russoz commented Nov 6, 2022

hi @jsabater thanks for following up. The PR was about tidying up some things we identified in the module, but I haven't had the time to work on those tests yet. I intend to write the automated tests that will verify the environment variables work.

My expectation is that they work fine - it is not a feature of this module, but one of Ansible core itself - so any problems with that feature would likely trigger many complaints in many different contexts. I suspect the problem you experienced derived from the particular deployment setup.

@russoz
Copy link
Collaborator

russoz commented Nov 6, 2022

@jsabater there you have it - environment variables arriving safely at settings.py, as I suspected.

@jsabater
Copy link
Author

jsabater commented Nov 7, 2022

I'll show the test to the devs and try to get some feedback. Feel free to close the issue if you consider it solved and thank you very much for your time and feedback.

@russoz
Copy link
Collaborator

russoz commented Nov 7, 2022

Thank you for reporting. I will close as per your comment, but feel free to reopen if you believe that we did not covered some angle of that problem.

@russoz russoz closed this as completed Nov 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue/PR relates to a bug has_pr module module plugins plugin (any type) traceback web_infrastructure
Projects
None yet
Development

No branches or pull requests

3 participants