Molecule: Molecule files in /tmp collide in multi-user environment

Created on 9 May 2018  路  10Comments  路  Source: ansible-community/molecule

Issue Type

  • Bug report

Molecule and Ansible details

 molecule --version
molecule, version 2.13.1
ansible --version
ansible 2.5.2
  config file = None
  configured module search path = [u'/home/myusername/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /home/myusername/.virtualenvs/moleculeVENV/lib/python2.7/site-packages/ansible
  executable location = /home/myusername/.virtualenvs/moleculeVENV/bin/ansible
  python version = 2.7.5 (default, Feb 20 2018, 09:19:12) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]

Molecule installation method (one of):

  • pip

Ansible installation method (one of):

  • pip

Desired Behavior

User1 has checked out a role from version control and performs a molecule test on it.
Later, User2 checks out the same role and also performs a molecule test run.
Both users are able to execute molecule on the role, with normal results through the molecule workflow.
Temporary files written to /tmp/molecule are distinguished by a UUID or username in order to prevent I/O permission errors, or are cleaned out after testing.

Actual Behaviour (Bug report only)

Molecule working files are written to /tmp/molecule/ and belong to the user/group of whoever tests that role first. In a multi-user server environment this causes conflict if multiple engineers are trying to test/debug a role, or if you have a service like Jenkins that is also running molecule tests. Other users are blocked until someone can remove the conflicting directory or open up permissions on it.

(moleculeVENV) [myusername@servername torque]$ ls
defaults  files  handlers  molecule  tasks  templates  vars
(moleculeVENV) [zswanson@servername torque]$ molecule test
--> Validating schema /home/myusername/project/roles/torque/molecule/default/molecule.yml.
Traceback (most recent call last):
  File "/home/myusername/.virtualenvs/moleculeVENV/bin/molecule", line 11, in <module>
    sys.exit(main())
  File "/home/myusername/.virtualenvs/moleculeVENV/lib/python2.7/site-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/home/myusername/.virtualenvs/moleculeVENV/lib/python2.7/site-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/home/myusername/.virtualenvs/moleculeVENV/lib/python2.7/site-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/myusername/.virtualenvs/moleculeVENV/lib/python2.7/site-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/myusername/.virtualenvs/moleculeVENV/lib/python2.7/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/home/myusername/.virtualenvs/moleculeVENV/lib/python2.7/site-packages/click/decorators.py", line 17, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/home/myusername/.virtualenvs/moleculeVENV/lib/python2.7/site-packages/molecule/command/test.py", line 109, in test
    base.get_configs(args, command_args), scenario_name)
  File "/home/myusername/.virtualenvs/moleculeVENV/lib/python2.7/site-packages/molecule/command/base.py", line 120, in get_configs
    ) for c in glob.glob(MOLECULE_GLOB)
  File "/home/myusername/.virtualenvs/moleculeVENV/lib/python2.7/site-packages/molecule/config.py", line 96, in __init__
    self._validate()
  File "/home/myusername/.virtualenvs/moleculeVENV/lib/python2.7/site-packages/molecule/config.py", line 387, in _validate
    self.config['driver']['name'] = self.driver.name
  File "/home/myusername/.virtualenvs/moleculeVENV/lib/python2.7/site-packages/molecule/util.py", line 304, in wrapper
    rv = function(*args, **kwargs)
  File "/home/myusername/.virtualenvs/moleculeVENV/lib/python2.7/site-packages/molecule/config.py", line 136, in driver
    driver_name = self._get_driver_name()
  File "/home/myusername/.virtualenvs/moleculeVENV/lib/python2.7/site-packages/molecule/config.py", line 229, in _get_driver_name
    driver_from_state_file = self.state.driver
  File "/home/myusername/.virtualenvs/moleculeVENV/lib/python2.7/site-packages/molecule/util.py", line 304, in wrapper
    rv = function(*args, **kwargs)
  File "/home/myusername/.virtualenvs/moleculeVENV/lib/python2.7/site-packages/molecule/config.py", line 210, in state
    return state.State(self)
  File "/home/myusername/.virtualenvs/moleculeVENV/lib/python2.7/site-packages/molecule/state.py", line 69, in __init__
    self._write_state_file()
  File "/home/myusername/.virtualenvs/moleculeVENV/lib/python2.7/site-packages/molecule/state.py", line 135, in _write_state_file
    util.write_file(self.state_file, util.safe_dump(self._data))
  File "/home/myusername/.virtualenvs/moleculeVENV/lib/python2.7/site-packages/molecule/util.py", line 132, in write_file
    with open_file(filename, 'w') as f:
  File "/usr/lib64/python2.7/contextlib.py", line 17, in __enter__
    return self.gen.next()
  File "/home/myusername/.virtualenvs/moleculeVENV/lib/python2.7/site-packages/molecule/util.py", line 200, in open_file
    with open(filename, mode) as stream:
IOError: [Errno 13] Permission denied: '/tmp/molecule/torque/default/state.yml'

All 10 comments

Molecule is intended to run on the developers desktop, not on a shared development system.

I am hitting this same problem after upgrading from molecule 2.5.0 to 2.16.0

We have a shared machine where we do our development and also run our CI (CI runs with different user account) and our CI executions are failing since the upgrade

Is there any workaround?

I have noticed that molecule is using $TMPDIR so to fix our setup I have added this profile file and now it's working fine:

$ cat /etc/profile.d/tmpdir.sh 
[ -d /tmp/$USER ] || mkdir /tmp/$USER
export TMPDIR=/tmp/$USER

I faced the same bug with latest version, the bug is valid and must be fixed without any hacks.

either create a common temp file function or just:
```diff --git a/molecule/shell.py b/molecule/shell.py
index 0637ba47..72780f8f 100644
--- a/molecule/shell.py
+++ b/molecule/shell.py
@@ -35,6 +35,8 @@
LOCAL_CONFIG = os.path.expanduser('~/.config/molecule/config.yml')
ENV_FILE = '.env.yml'

+os.environ['TMPDIR'] = os.path.join([os.environ.get('TMPDIR', os.environ.get('TEMP', os.environ.get('TMP', '/tmp'))), '-'.join(['-molecule', os.getuid(), os.getpid()])])
+

@click.group()
@click.option(```

My original suggestion was to use /tmp/-molecule so that each user gets their own molecule path.

Hi. Also got issues with using /tmp/molecule, but in my case because by default /tmp uses tmpfs, so if reboot system, then all molecule configs get flushed and I cannot connect to vagrant boxes with molecule. This can be fixed only by manual removing all vagrant boxes and volumes and start from scratch.

I think it is better to use ~/.molecule instead of /tmp/molecule in order to make config stateful and user dependent.

Latest RC uses ~/.cache/molecule!

Great news! Thank you!

As a temporary fix for current stable same effect can be achieved with wirtualenvwrapper by setting TMPDIR for molecule environment:

mkdir ~/.cache/molecule

workon molecule
echo "export TMPDIR=$HOME/.cache/molecule" >> $VIRTUAL_ENV/bin/postactivate
exit
workon molecule

I will mark this as closed as latest pre-release includes fix for it. Remember to mention it explicitly in order to force pip to install it.

Was this page helpful?
0 / 5 - 0 ratings