Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
ansible
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
ansible
Commits
fc3597af
Commit
fc3597af
authored
Dec 07, 2013
by
Paulo Bittencourt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
files/file: add support for symbolic permission modes
parent
9018d53a
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
144 additions
and
14 deletions
+144
-14
lib/ansible/module_utils/basic.py
+95
-9
library/files/file
+1
-1
test/TestRunner.py
+48
-4
No files found.
lib/ansible/module_utils/basic.py
View file @
fc3597af
...
...
@@ -416,17 +416,23 @@ class AnsibleModule(object):
def
set_mode_if_different
(
self
,
path
,
mode
,
changed
):
path
=
os
.
path
.
expanduser
(
path
)
path_stat
=
os
.
lstat
(
path
)
if
mode
is
None
:
return
changed
try
:
# FIXME: support English modes
if
not
isinstance
(
mode
,
int
)
:
if
not
isinstance
(
mode
,
int
):
try
:
mode
=
int
(
mode
,
8
)
except
Exception
,
e
:
self
.
fail_json
(
path
=
path
,
msg
=
'mode needs to be something octalish'
,
details
=
str
(
e
))
except
Exception
:
try
:
mode
=
self
.
_symbolic_mode_to_octal
(
path_stat
,
mode
)
except
Exception
,
e
:
self
.
fail_json
(
path
=
path
,
msg
=
"mode must be in octal or symbolic form"
,
details
=
str
(
e
))
st
=
os
.
lstat
(
path
)
prev_mode
=
stat
.
S_IMODE
(
st
[
stat
.
ST_MODE
])
prev_mode
=
stat
.
S_IMODE
(
path_stat
.
st_mode
)
if
prev_mode
!=
mode
:
if
self
.
check_mode
:
...
...
@@ -448,13 +454,93 @@ class AnsibleModule(object):
except
Exception
,
e
:
self
.
fail_json
(
path
=
path
,
msg
=
'chmod failed'
,
details
=
str
(
e
))
s
t
=
os
.
lstat
(
path
)
new_mode
=
stat
.
S_IMODE
(
st
[
stat
.
ST_MODE
]
)
path_sta
t
=
os
.
lstat
(
path
)
new_mode
=
stat
.
S_IMODE
(
path_stat
.
st_mode
)
if
new_mode
!=
prev_mode
:
changed
=
True
return
changed
def
_symbolic_mode_to_octal
(
self
,
path_stat
,
symbolic_mode
):
new_mode
=
stat
.
S_IMODE
(
path_stat
.
st_mode
)
mode_re
=
re
.
compile
(
r'^(?P<users>[ugoa]+)(?P<operator>[-+=])(?P<perms>[rwxXst]*|[ugo])$'
)
for
mode
in
symbolic_mode
.
split
(
','
):
match
=
mode_re
.
match
(
mode
)
if
match
:
users
=
match
.
group
(
'users'
)
operator
=
match
.
group
(
'operator'
)
perms
=
match
.
group
(
'perms'
)
if
users
==
'a'
:
users
=
'ugo'
for
user
in
users
:
mode_to_apply
=
self
.
_get_octal_mode_from_symbolic_perms
(
path_stat
,
user
,
perms
)
new_mode
=
self
.
_apply_operation_to_mode
(
user
,
operator
,
mode_to_apply
,
new_mode
)
else
:
raise
ValueError
(
"bad symbolic permission for mode:
%
s"
%
mode
)
return
new_mode
def
_apply_operation_to_mode
(
self
,
user
,
operator
,
mode_to_apply
,
current_mode
):
if
operator
==
'='
:
if
user
==
'u'
:
mask
=
stat
.
S_IRWXU
|
stat
.
S_ISUID
elif
user
==
'g'
:
mask
=
stat
.
S_IRWXG
|
stat
.
S_ISGID
elif
user
==
'o'
:
mask
=
stat
.
S_IRWXO
|
stat
.
S_ISVTX
# mask out u, g, or o permissions from current_mode and apply new permissions
inverse_mask
=
mask
^
07777
new_mode
=
(
current_mode
&
inverse_mask
)
|
mode_to_apply
elif
operator
==
'+'
:
new_mode
=
current_mode
|
mode_to_apply
elif
operator
==
'-'
:
new_mode
=
current_mode
-
(
current_mode
&
mode_to_apply
)
return
new_mode
def
_get_octal_mode_from_symbolic_perms
(
self
,
path_stat
,
user
,
perms
):
prev_mode
=
stat
.
S_IMODE
(
path_stat
.
st_mode
)
is_directory
=
stat
.
S_ISDIR
(
path_stat
.
st_mode
)
has_x_permissions
=
(
prev_mode
&
00111
)
>
0
apply_X_permission
=
is_directory
or
has_x_permissions
# Permission bits constants documented at:
# http://docs.python.org/2/library/stat.html#stat.S_ISUID
user_perms_to_modes
=
{
'u'
:
{
'r'
:
stat
.
S_IRUSR
,
'w'
:
stat
.
S_IWUSR
,
'x'
:
stat
.
S_IXUSR
,
'X'
:
stat
.
S_IXUSR
if
apply_X_permission
else
0
,
's'
:
stat
.
S_ISUID
,
't'
:
0
,
'u'
:
prev_mode
&
stat
.
S_IRWXU
,
'g'
:
(
prev_mode
&
stat
.
S_IRWXG
)
<<
3
,
'o'
:
(
prev_mode
&
stat
.
S_IRWXO
)
<<
6
},
'g'
:
{
'r'
:
stat
.
S_IRGRP
,
'w'
:
stat
.
S_IWGRP
,
'x'
:
stat
.
S_IXGRP
,
'X'
:
stat
.
S_IXGRP
if
apply_X_permission
else
0
,
's'
:
stat
.
S_ISGID
,
't'
:
0
,
'u'
:
(
prev_mode
&
stat
.
S_IRWXU
)
>>
3
,
'g'
:
prev_mode
&
stat
.
S_IRWXG
,
'o'
:
(
prev_mode
&
stat
.
S_IRWXO
)
<<
3
},
'o'
:
{
'r'
:
stat
.
S_IROTH
,
'w'
:
stat
.
S_IWOTH
,
'x'
:
stat
.
S_IXOTH
,
'X'
:
stat
.
S_IXOTH
if
apply_X_permission
else
0
,
's'
:
0
,
't'
:
stat
.
S_ISVTX
,
'u'
:
(
prev_mode
&
stat
.
S_IRWXU
)
>>
6
,
'g'
:
(
prev_mode
&
stat
.
S_IRWXG
)
>>
3
,
'o'
:
prev_mode
&
stat
.
S_IRWXO
}
}
or_reduce
=
lambda
mode
,
perm
:
mode
|
user_perms_to_modes
[
user
][
perm
]
return
reduce
(
or_reduce
,
perms
,
0
)
def
set_file_attributes_if_different
(
self
,
file_args
,
changed
):
# set modes owners and context as needed
changed
=
self
.
set_context_if_different
(
...
...
library/files/file
View file @
fc3597af
...
...
@@ -63,7 +63,7 @@ options:
default: null
choices: []
description:
- mode the file or directory should be, such as 0644 as would be fed to I(chmod)
- mode the file or directory should be, such as 0644
or o=rwx,g=rwx,o=rx
as would be fed to I(chmod)
owner:
required: false
default: null
...
...
test/TestRunner.py
View file @
fc3597af
...
...
@@ -10,6 +10,7 @@ import os
import
shutil
import
time
import
tempfile
import
stat
from
nose.plugins.skip
import
SkipTest
...
...
@@ -221,9 +222,47 @@ class TestRunner(unittest.TestCase):
assert
self
.
_run
(
'file'
,
[
'dest='
+
filedemo
,
'src=/dev/null'
,
'state=link'
])[
'failed'
]
assert
os
.
path
.
isfile
(
filedemo
)
res
=
self
.
_run
(
'file'
,
[
'dest='
+
filedemo
,
'mode=604'
,
'state=file'
])
assert
res
[
'changed'
]
assert
os
.
path
.
isfile
(
filedemo
)
and
os
.
stat
(
filedemo
)
.
st_mode
==
0100604
os
.
chmod
(
filedemo
,
0
)
assert
self
.
_run
(
'file'
,
[
'dest='
+
filedemo
,
'mode=604'
,
'state=file'
])[
'changed'
]
assert
os
.
path
.
isfile
(
filedemo
)
and
stat
.
S_IMODE
(
os
.
stat
(
filedemo
)
.
st_mode
)
==
00604
os
.
chmod
(
filedemo
,
0
)
assert
self
.
_run
(
'file'
,
[
'dest='
+
filedemo
,
'mode="u=rwsx,g=rwxs,o=rwxt"'
,
'state=file'
])[
'changed'
]
assert
os
.
path
.
isfile
(
filedemo
)
and
stat
.
S_IMODE
(
os
.
stat
(
filedemo
)
.
st_mode
)
==
07777
os
.
chmod
(
filedemo
,
0
)
assert
self
.
_run
(
'file'
,
[
'dest='
+
filedemo
,
'mode="u=rwx,g=rwx,o=rwx"'
,
'state=file'
])[
'changed'
]
assert
os
.
path
.
isfile
(
filedemo
)
and
stat
.
S_IMODE
(
os
.
stat
(
filedemo
)
.
st_mode
)
==
00777
os
.
chmod
(
filedemo
,
0
)
assert
self
.
_run
(
'file'
,
[
'dest='
+
filedemo
,
'mode="u=rwx,g=,o=rwx"'
,
'state=file'
])[
'changed'
]
assert
os
.
path
.
isfile
(
filedemo
)
and
stat
.
S_IMODE
(
os
.
stat
(
filedemo
)
.
st_mode
)
==
00707
os
.
chmod
(
filedemo
,
07777
)
assert
self
.
_run
(
'file'
,
[
'dest='
+
filedemo
,
'mode="u=,g=,o="'
,
'state=file'
])[
'changed'
]
assert
os
.
path
.
isfile
(
filedemo
)
and
stat
.
S_IMODE
(
os
.
stat
(
filedemo
)
.
st_mode
)
==
0
os
.
chmod
(
filedemo
,
00777
)
assert
self
.
_run
(
'file'
,
[
'dest='
+
filedemo
,
'mode="u-X"'
,
'state=file'
])[
'changed'
]
assert
os
.
path
.
isfile
(
filedemo
)
and
stat
.
S_IMODE
(
os
.
stat
(
filedemo
)
.
st_mode
)
==
00677
os
.
chmod
(
filedemo
,
00777
)
assert
self
.
_run
(
'file'
,
[
'dest='
+
filedemo
,
'mode="u-x"'
,
'state=file'
])[
'changed'
]
assert
os
.
path
.
isfile
(
filedemo
)
and
stat
.
S_IMODE
(
os
.
stat
(
filedemo
)
.
st_mode
)
==
00677
os
.
chmod
(
filedemo
,
00411
)
assert
self
.
_run
(
'file'
,
[
'dest='
+
filedemo
,
'mode="u+X"'
,
'state=file'
])[
'changed'
]
assert
os
.
path
.
isfile
(
filedemo
)
and
stat
.
S_IMODE
(
os
.
stat
(
filedemo
)
.
st_mode
)
==
00511
os
.
chmod
(
filedemo
,
00444
)
assert
not
self
.
_run
(
'file'
,
[
'dest='
+
filedemo
,
'mode="g+X"'
,
'state=file'
])[
'changed'
]
assert
os
.
path
.
isfile
(
filedemo
)
and
stat
.
S_IMODE
(
os
.
stat
(
filedemo
)
.
st_mode
)
==
00444
os
.
chmod
(
filedemo
,
00444
)
assert
not
self
.
_run
(
'file'
,
[
'dest='
+
filedemo
,
'mode="u=u,g=g,o=o"'
,
'state=file'
])[
'changed'
]
assert
os
.
path
.
isfile
(
filedemo
)
and
stat
.
S_IMODE
(
os
.
stat
(
filedemo
)
.
st_mode
)
==
00444
assert
self
.
_run
(
'file'
,
[
'dest='
+
filedemo
,
'mode=u=gx'
,
'state=file'
])[
'failed'
]
assert
self
.
_run
(
'file'
,
[
'dest='
+
filedemo
,
'state=absent'
])[
'changed'
]
assert
not
os
.
path
.
exists
(
filedemo
)
...
...
@@ -239,8 +278,13 @@ class TestRunner(unittest.TestCase):
#assert result['failed']
#assert os.path.isdir(filedemo)
os
.
chmod
(
filedemo
,
0
)
assert
self
.
_run
(
'file'
,
[
'dest='
+
filedemo
,
'mode=701'
,
'state=directory'
])[
'changed'
]
assert
os
.
path
.
isdir
(
filedemo
)
and
os
.
stat
(
filedemo
)
.
st_mode
==
040701
assert
os
.
path
.
isdir
(
filedemo
)
and
stat
.
S_IMODE
(
os
.
stat
(
filedemo
)
.
st_mode
)
==
00701
os
.
chmod
(
filedemo
,
00444
)
assert
self
.
_run
(
'file'
,
[
'dest='
+
filedemo
,
'mode=ugo+X'
,
'state=directory'
])[
'changed'
]
assert
os
.
path
.
isdir
(
filedemo
)
and
stat
.
S_IMODE
(
os
.
stat
(
filedemo
)
.
st_mode
)
==
00555
assert
self
.
_run
(
'file'
,
[
'dest='
+
filedemo
,
'state=absent'
])[
'changed'
]
assert
not
os
.
path
.
exists
(
filedemo
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment