mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
passwordstore plugin: vendor FileLock that was removed from ansible-core devel (#6447)
Vendor FileLock that was removed from ansible-core devel.
This commit is contained in:
parent
6e913a3b28
commit
c58dda14c2
3 changed files with 113 additions and 1 deletions
2
changelogs/fragments/passwordstore-lock.yml
Normal file
2
changelogs/fragments/passwordstore-lock.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
bugfixes:
|
||||||
|
- "passwordstore lookup plugin - make compatible with ansible-core 2.16 (https://github.com/ansible-collections/community.general/pull/6447)."
|
|
@ -209,7 +209,6 @@ import time
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from ansible.errors import AnsibleError, AnsibleAssertionError
|
from ansible.errors import AnsibleError, AnsibleAssertionError
|
||||||
from ansible.module_utils.common.file import FileLock
|
|
||||||
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
||||||
from ansible.module_utils.parsing.convert_bool import boolean
|
from ansible.module_utils.parsing.convert_bool import boolean
|
||||||
from ansible.utils.display import Display
|
from ansible.utils.display import Display
|
||||||
|
@ -217,6 +216,8 @@ from ansible.utils.encrypt import random_password
|
||||||
from ansible.plugins.lookup import LookupBase
|
from ansible.plugins.lookup import LookupBase
|
||||||
from ansible import constants as C
|
from ansible import constants as C
|
||||||
|
|
||||||
|
from ansible_collections.community.general.plugins.module_utils._filelock import FileLock
|
||||||
|
|
||||||
display = Display()
|
display = Display()
|
||||||
|
|
||||||
|
|
||||||
|
|
109
plugins/module_utils/_filelock.py
Normal file
109
plugins/module_utils/_filelock.py
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
# Copyright (c) 2018, Ansible Project
|
||||||
|
# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
# NOTE:
|
||||||
|
# This has been vendored from ansible.module_utils.common.file. This code has been removed from there for ansible-core 2.16.
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import os
|
||||||
|
import stat
|
||||||
|
import time
|
||||||
|
import fcntl
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from contextlib import contextmanager
|
||||||
|
|
||||||
|
|
||||||
|
class LockTimeout(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class FileLock:
|
||||||
|
'''
|
||||||
|
Currently FileLock is implemented via fcntl.flock on a lock file, however this
|
||||||
|
behaviour may change in the future. Avoid mixing lock types fcntl.flock,
|
||||||
|
fcntl.lockf and module_utils.common.file.FileLock as it will certainly cause
|
||||||
|
unwanted and/or unexpected behaviour
|
||||||
|
'''
|
||||||
|
def __init__(self):
|
||||||
|
self.lockfd = None
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def lock_file(self, path, tmpdir, lock_timeout=None):
|
||||||
|
'''
|
||||||
|
Context for lock acquisition
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
self.set_lock(path, tmpdir, lock_timeout)
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
self.unlock()
|
||||||
|
|
||||||
|
def set_lock(self, path, tmpdir, lock_timeout=None):
|
||||||
|
'''
|
||||||
|
Create a lock file based on path with flock to prevent other processes
|
||||||
|
using given path.
|
||||||
|
Please note that currently file locking only works when it's executed by
|
||||||
|
the same user, I.E single user scenarios
|
||||||
|
|
||||||
|
:kw path: Path (file) to lock
|
||||||
|
:kw tmpdir: Path where to place the temporary .lock file
|
||||||
|
:kw lock_timeout:
|
||||||
|
Wait n seconds for lock acquisition, fail if timeout is reached.
|
||||||
|
0 = Do not wait, fail if lock cannot be acquired immediately,
|
||||||
|
Default is None, wait indefinitely until lock is released.
|
||||||
|
:returns: True
|
||||||
|
'''
|
||||||
|
lock_path = os.path.join(tmpdir, 'ansible-{0}.lock'.format(os.path.basename(path)))
|
||||||
|
l_wait = 0.1
|
||||||
|
r_exception = IOError
|
||||||
|
if sys.version_info[0] == 3:
|
||||||
|
r_exception = BlockingIOError
|
||||||
|
|
||||||
|
self.lockfd = open(lock_path, 'w')
|
||||||
|
|
||||||
|
if lock_timeout <= 0:
|
||||||
|
fcntl.flock(self.lockfd, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||||
|
os.chmod(lock_path, stat.S_IWRITE | stat.S_IREAD)
|
||||||
|
return True
|
||||||
|
|
||||||
|
if lock_timeout:
|
||||||
|
e_secs = 0
|
||||||
|
while e_secs < lock_timeout:
|
||||||
|
try:
|
||||||
|
fcntl.flock(self.lockfd, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||||
|
os.chmod(lock_path, stat.S_IWRITE | stat.S_IREAD)
|
||||||
|
return True
|
||||||
|
except r_exception:
|
||||||
|
time.sleep(l_wait)
|
||||||
|
e_secs += l_wait
|
||||||
|
continue
|
||||||
|
|
||||||
|
self.lockfd.close()
|
||||||
|
raise LockTimeout('{0} sec'.format(lock_timeout))
|
||||||
|
|
||||||
|
fcntl.flock(self.lockfd, fcntl.LOCK_EX)
|
||||||
|
os.chmod(lock_path, stat.S_IWRITE | stat.S_IREAD)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def unlock(self):
|
||||||
|
'''
|
||||||
|
Make sure lock file is available for everyone and Unlock the file descriptor
|
||||||
|
locked by set_lock
|
||||||
|
|
||||||
|
:returns: True
|
||||||
|
'''
|
||||||
|
if not self.lockfd:
|
||||||
|
return True
|
||||||
|
|
||||||
|
try:
|
||||||
|
fcntl.flock(self.lockfd, fcntl.LOCK_UN)
|
||||||
|
self.lockfd.close()
|
||||||
|
except ValueError: # file wasn't opened, let context manager fail gracefully
|
||||||
|
pass
|
||||||
|
|
||||||
|
return True
|
Loading…
Reference in a new issue