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

ansible: env vars set in vars plugin not present in play for localhost #297

Closed
manicminer opened this issue Jul 10, 2018 · 5 comments
Closed

Comments

@manicminer
Copy link

@manicminer manicminer commented Jul 10, 2018

This might sound strange, and may even be an unexpected behavior of Ansible to begin with.

I have a vars plugin which sets some environment variables in-process. When I use the stock linear strategy, these vars are visible for plays running on localhost. When I use Mitogen, the vars are not visible.

Reproducing

# vars_plugins/test.py

from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

from ansible.plugins.vars import BaseVarsPlugin
import os

class VarsModule(BaseVarsPlugin):
    def __init__(self, *args):
        super(VarsModule, self).__init__(*args)
        os.environ['FOO'] = 'bar'

    def get_vars(self, loader, path, entities, cache=True):
        super(VarsModule, self).get_vars(loader, path, entities)
        return {}
---
# playbook.yml

- hosts: localhost
  strategy: linear
  connection: local
  tasks:
    - shell: "env | grep FOO"

- hosts: localhost
  connection: local
  tasks:
    - shell: "env | grep FOO"

I fully admit this is abuse of a vars plugin, but I use it to set context-specific AWS_* variables, so that the correct AWS account is chosen based on some runtime logic.

Look forward to any feedback on this scenario! Is this sane? Fixable in Mitogen or antithetical to Mitogen's design? Thanks!

@manicminer
Copy link
Author

@manicminer manicminer commented Jul 10, 2018

I just noticed that the above doesn't reproduce, but this does:

---

- hosts: localhost
  strategy: mitogen_linear
  connection: local
  tasks:
    - debug:
        msg: noop

- hosts: localhost
  strategy: linear
  connection: local
  tasks:
    - shell: "env | grep FOO"

- hosts: localhost
  strategy: mitogen_linear
  connection: local
  tasks:
    - shell: "env | grep FOO"

When I remove the first play, the env var is visible to the second shell task.

@dw dw added user-reported ansible bug and removed ansible bug labels Jul 10, 2018
@dw
Copy link
Owner

@dw dw commented Jul 10, 2018

Funsies! So I guess this is because the vars plugin executes in the top-level process, and in vanilla Ansible that process is repeatedly forked for every new task. Environment variable modifications will make it into the forked children, which local actions execute as a subprocess of.

With Mitogen the local context is started once, as a subprocess of a fork of the top-level process, and that fork happens long before any vars evaluation would have a chance to run.

This is reminiscent of another annoying bug I've only seen once -- #122


As for a fix, we must preserve vanilla's semantics everywhere so this should be made to work.

The environment variables will propagate to new WorkerProcesses running under Mitogen just like they did in vanilla, so there needs to be a mechanism to ship them to the long-lived local worker.

Give me a few hours to think about this one! There is an obvious "special case localhost" option, but I'd prefer to avoid that.

Thanks for reporting!

dw added a commit that referenced this issue Jul 10, 2018
Local actions must execute in the the parent directory of the playbook
that defines the action.
dw added a commit that referenced this issue Jul 10, 2018
dw added a commit that referenced this issue Jul 10, 2018
dw added a commit that referenced this issue Jul 10, 2018
@dw dw mentioned this issue Jul 10, 2018
Merged
@dw dw closed this in #298 Jul 10, 2018
@manicminer
Copy link
Author

@manicminer manicminer commented Jul 11, 2018

Wow! Can confirm this fixes the underlying issue. Great stuff, thanks!

@manicminer
Copy link
Author

@manicminer manicminer commented Jul 11, 2018

Would also like to add that it's great you are striving to meet vanilla Ansible behavior (good or bad), it really boosts confidence for using Mitogen as a drop in replacement.

@dw
Copy link
Owner

@dw dw commented Jul 11, 2018

Code isn't the customer -- people are. Wish more people understood that!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.