ansible: _remote_chmod() / _fixup_perms2() can be called sometimes.
It's used at least by the copy module, even though the result is still mostly a no-op. _remote_chmod() doesn't accept octal mode, it accepts symbolic mode. So implement a symbolic parser in helpers.py.
This commit is contained in:
parent
33781aba2c
commit
83f2862431
|
@ -197,8 +197,8 @@ class Connection(ansible.plugins.connection.ConnectionBase):
|
|||
:returns:
|
||||
(return code, stdout bytes, stderr bytes)
|
||||
"""
|
||||
return self.py_call(ansible_mitogen.helpers.exec_command,
|
||||
cast(cmd), cast(in_data))
|
||||
return self.call(ansible_mitogen.helpers.exec_command,
|
||||
cast(cmd), cast(in_data))
|
||||
|
||||
def fetch_file(self, in_path, out_path):
|
||||
"""
|
||||
|
@ -210,8 +210,8 @@ class Connection(ansible.plugins.connection.ConnectionBase):
|
|||
:param str out_path:
|
||||
Local filesystem path to write.
|
||||
"""
|
||||
output = self.py_call(ansible_mitogen.helpers.read_path,
|
||||
cast(in_path))
|
||||
output = self.call(ansible_mitogen.helpers.read_path,
|
||||
cast(in_path))
|
||||
ansible_mitogen.helpers.write_path(out_path, output)
|
||||
|
||||
def put_file(self, in_path, out_path):
|
||||
|
@ -224,5 +224,5 @@ class Connection(ansible.plugins.connection.ConnectionBase):
|
|||
:param str out_path:
|
||||
Remote filesystem path to write.
|
||||
"""
|
||||
self.py_call(ansible_mitogen.helpers.write_path, cast(out_path),
|
||||
ansible_mitogen.helpers.read_path(in_path))
|
||||
self.call(ansible_mitogen.helpers.write_path, cast(out_path),
|
||||
ansible_mitogen.helpers.read_path(in_path))
|
||||
|
|
|
@ -26,8 +26,11 @@
|
|||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import json
|
||||
import operator
|
||||
import os
|
||||
import pwd
|
||||
import re
|
||||
import stat
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
|
@ -165,3 +168,59 @@ def write_path(path, s):
|
|||
Writes bytes `s` to a filesystem `path`.
|
||||
"""
|
||||
open(path, 'wb').write(s)
|
||||
|
||||
|
||||
|
||||
CHMOD_CLAUSE_PAT = re.compile(r'([uoga]?)([+\-=])([ugo]|[rwx]*)')
|
||||
CHMOD_MASKS = {
|
||||
'u': stat.S_IRWXU,
|
||||
'g': stat.S_IRWXG,
|
||||
'o': stat.S_IRWXO,
|
||||
'a': (stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO),
|
||||
}
|
||||
CHMOD_BITS = {
|
||||
'u': {'r':stat.S_IRUSR, 'w':stat.S_IWUSR, 'x':stat.S_IXUSR},
|
||||
'g': {'r':stat.S_IRGRP, 'w':stat.S_IWGRP, 'x':stat.S_IXGRP},
|
||||
'o': {'r':stat.S_IROTH, 'w':stat.S_IWOTH, 'x':stat.S_IXOTH},
|
||||
'a': {
|
||||
'r': (stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH),
|
||||
'w': (stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH),
|
||||
'x': (stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
|
||||
}
|
||||
}
|
||||
|
||||
def or_(it):
|
||||
return reduce(operator.or_, it, 0)
|
||||
|
||||
|
||||
def apply_mode_spec(spec, mode):
|
||||
for clause in spec.split(','):
|
||||
match = CHMOD_CLAUSE_PAT.match(clause)
|
||||
who, op, perms = match.groups()
|
||||
mask = CHMOD_MASKS[who]
|
||||
bits = CHMOD_BITS[who]
|
||||
for ch in who or 'a':
|
||||
cur_perm_bits = mode & mask
|
||||
new_perm_bits = or_(bits[p] for p in perms)
|
||||
mode &= ~mask
|
||||
if op == '=':
|
||||
mode |= new_perm_bits
|
||||
elif op == '+':
|
||||
mode |= new_perm_bits | cur_per_bits
|
||||
else:
|
||||
mode |= cur_perm_bits & ~new_perm_bits
|
||||
return mode
|
||||
|
||||
|
||||
def set_file_mode(path, spec):
|
||||
"""
|
||||
Update the permissions of a file using the same syntax as chmod(1).
|
||||
"""
|
||||
mode = os.stat(path).st_mode
|
||||
|
||||
if spec.is_digit():
|
||||
new_mode = int(spec, 8)
|
||||
else:
|
||||
new_mode = apply_mode_spec(spec, mode)
|
||||
|
||||
os.chmod(path, new_mode)
|
||||
|
|
|
@ -117,11 +117,14 @@ class ActionModuleMixin(ansible.plugins.action.ActionBase):
|
|||
|
||||
def _fixup_perms2(self, remote_paths, remote_user=None, execute=True):
|
||||
# replaces 83 lines
|
||||
assert False, "_fixup_perms2() should never be called."
|
||||
if not execute:
|
||||
return self._remote_chmod(remote_paths, mode='u+x')
|
||||
# Do nothing unless request was to set the execute bit.
|
||||
return self.COMMAND_RESULT.copy()
|
||||
|
||||
def _remote_chmod(self, paths, mode, sudoable=False):
|
||||
return self.fake_shell(lambda: mitogen.master.Select.all(
|
||||
self._connection.call_async(os.chmod, path, mode)
|
||||
self._connection.call_async(helpers.set_file_mode, path, mode)
|
||||
for path in paths
|
||||
))
|
||||
|
||||
|
|
Loading…
Reference in New Issue