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

Fix inconsistent json output in file module #3516

Merged
merged 1 commit into from
Jul 20, 2013
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
100 changes: 50 additions & 50 deletions library/files/file
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ description:
files/symlinks/directories. Many other modules support the same options as
the M(file) module - including M(copy), M(template), and M(assemble).
options:
path:
dest:
description:
- defines the file being managed, unless when used with C(state=link), and then sets the destination to create a symbolic link to using I(src)
required: true
default: []
aliases: ['dest', 'name']
aliases: ['name', 'path']
state:
description:
- If C(directory), all immediate subdirectories will be created if they
Expand Down Expand Up @@ -127,26 +127,26 @@ options:
description:
- 'force the creation of the symlinks in two cases: the source file does
not exist (but will appear later); the destination exists and a file (so, we need to unlink the
"path" file and create symlink to the "src" file in place of it).'
"dest" file and create symlink to the "src" file in place of it).'
notes:
- See also M(copy), M(template), M(assemble)
requirements: [ ]
author: Michael DeHaan
'''

EXAMPLES = '''
- file: path=/etc/foo.conf owner=foo group=foo mode=0644
- file: dest=/etc/foo.conf owner=foo group=foo mode=0644
- file: src=/file/to/link/to dest=/path/to/symlink owner=foo group=foo state=link
'''

def dolink(src, path, state, module):
def dolink(src, dest, state, module):
try:
if state == 'hard':
os.link(src,path)
os.link(src,dest)
else:
os.symlink(src, path)
os.symlink(src, dest)
except OSError, e:
module.fail_json(path=path, msg='Error while linking: %s' % str(e))
module.fail_json(dest=dest, msg='Error while linking: %s' % str(e))

def main():

Expand All @@ -156,7 +156,7 @@ def main():
module = AnsibleModule(
argument_spec = dict(
state = dict(choices=['file','directory','link','hard','absent'], default='file'),
path = dict(aliases=['dest', 'name'], required=True),
dest = dict(aliases=['name', 'path'], required=True),
recurse = dict(default='no', type='bool'),
force = dict(required=False,default=False,type='bool'),
diff_peek = dict(default=None),
Expand All @@ -169,20 +169,20 @@ def main():
params = module.params
state = params['state']
force = params['force']
params['path'] = path = os.path.expanduser(params['path'])
params['dest'] = dest = os.path.expanduser(params['dest'])

# short-circuit for diff_peek
if params.get('diff_peek', None) is not None:
appears_binary = False
try:
f = open(path)
f = open(dest)
b = f.read(8192)
f.close()
if b.find("\x00") != -1:
appears_binary = True
except:
pass
module.exit_json(path=path, changed=False, appears_binary=appears_binary)
module.exit_json(dest=dest, changed=False, appears_binary=appears_binary)

# source is both the source of a symlink or an informational passing of the src for a template module
# or copy module, even if this module never uses it, it is needed to key off some things
Expand All @@ -191,89 +191,89 @@ def main():
if src:
src = os.path.expanduser(src)

if src is not None and os.path.isdir(path) and state != "link":
params['path'] = path = os.path.join(path, os.path.basename(src))
if src is not None and os.path.isdir(dest) and state != "link":
params['dest'] = dest = os.path.join(dest, os.path.basename(src))

file_args = module.load_file_common_arguments(params)

if state in ['link','hard'] and (src is None or path is None):
if state in ['link','hard'] and (src is None or dest is None):
module.fail_json(msg='src and dest are required for creating links')
elif path is None:
elif dest is None:
module.fail_json(msg='path is required')

changed = False

prev_state = 'absent'

if os.path.lexists(path):
if os.path.islink(path):
if os.path.lexists(dest):
if os.path.islink(dest):
prev_state = 'link'
elif os.path.isdir(path):
elif os.path.isdir(dest):
prev_state = 'directory'
else:
prev_state = 'file'

if prev_state != 'absent' and state == 'absent':
try:
if prev_state == 'directory':
if os.path.islink(path):
if os.path.islink(dest):
if module.check_mode:
module.exit_json(changed=True)
os.unlink(path)
os.unlink(dest)
else:
try:
if module.check_mode:
module.exit_json(changed=True)
shutil.rmtree(path, ignore_errors=False)
shutil.rmtree(dest, ignore_errors=False)
except:
module.exit_json(msg="rmtree failed")
else:
if module.check_mode:
module.exit_json(changed=True)
os.unlink(path)
os.unlink(dest)
except Exception, e:
module.fail_json(path=path, msg=str(e))
module.exit_json(path=path, changed=True)
module.fail_json(dest=dest, msg=str(e))
module.exit_json(dest=dest, changed=True)

if prev_state != 'absent' and prev_state != state:
if force and prev_state == 'file' and state == 'link':
pass
else:
module.fail_json(path=path, msg='refusing to convert between %s and %s for %s' % (prev_state, state, src))
module.fail_json(dest=dest, msg='refusing to convert between %s and %s for %s' % (prev_state, state, src))

if prev_state == 'absent' and state == 'absent':
module.exit_json(path=path, changed=False)
module.exit_json(dest=dest, changed=False)

if state == 'file':

if prev_state != 'file':
module.fail_json(path=path, msg='file (%s) does not exist, use copy or template module to create' % path)
module.fail_json(dest=dest, msg='file (%s) does not exist, use copy or template module to create' % dest)

changed = module.set_file_attributes_if_different(file_args, changed)
module.exit_json(path=path, changed=changed)
module.exit_json(dest=dest, changed=changed)

elif state == 'directory':
if prev_state == 'absent':
if module.check_mode:
module.exit_json(changed=True)
os.makedirs(path)
os.makedirs(dest)
changed = True

changed = module.set_directory_attributes_if_different(file_args, changed)
recurse = params['recurse']
if recurse:
for root,dirs,files in os.walk( file_args['path'] ):
for root,dirs,files in os.walk( file_args['dest'] ):
for dir in dirs:
dirname=os.path.join(root,dir)
tmp_file_args = file_args.copy()
tmp_file_args['path']=dirname
tmp_file_args['dest']=dirname
changed = module.set_directory_attributes_if_different(tmp_file_args, changed)
for file in files:
filename=os.path.join(root,file)
tmp_file_args = file_args.copy()
tmp_file_args['path']=filename
tmp_file_args['dest']=filename
changed = module.set_file_attributes_if_different(tmp_file_args, changed)
module.exit_json(path=path, changed=changed)
module.exit_json(dest=dest, changed=changed)

elif state in ['link','hard']:

Expand All @@ -283,46 +283,46 @@ def main():
module.fail_json(msg="absolute paths are required")

if not os.path.exists(abs_src) and not force:
module.fail_json(path=path, src=src, msg='src file does not exist')
module.fail_json(dest=dest, src=src, msg='src file does not exist')

if prev_state == 'absent':
if module.check_mode:
module.exit_json(changed=True)
dolink(src, path, state, module)
dolink(src, dest, state, module)
changed = True
elif prev_state == 'link':
old_src = os.readlink(path)
old_src = os.readlink(dest)
if not os.path.isabs(old_src):
old_src = os.path.join(os.path.dirname(path), old_src)
old_src = os.path.join(os.path.dirname(dest), old_src)
if old_src != src:
if module.check_mode:
module.exit_json(changed=True)
os.unlink(path)
dolink(src, path, state, module)
os.unlink(dest)
dolink(src, dest, state, module)
changed = True
elif prev_state == 'file':
if not force:
module.fail_json(dest=path, src=src, msg='Cannot link, file exists at destination')
module.fail_json(dest=dest, src=src, msg='Cannot link, file exists at destination')
else:
if module.check_mode:
module.exit_json(changed=True)
os.unlink(path)
dolink(src, path, state, module)
os.unlink(dest)
dolink(src, dest, state, module)
changed = True
else:
module.fail_json(dest=path, src=src, msg='unexpected position reached')
module.fail_json(dest=dest, src=src, msg='unexpected position reached')

# set modes owners and context as needed

file_args = module.load_file_common_arguments(module.params)
changed = module.set_context_if_different(path, file_args['secontext'], changed)
changed = module.set_owner_if_different(path, file_args['owner'], changed)
changed = module.set_group_if_different(path, file_args['group'], changed)
changed = module.set_mode_if_different(path, file_args['mode'], changed)
changed = module.set_context_if_different(dest, file_args['secontext'], changed)
changed = module.set_owner_if_different(dest, file_args['owner'], changed)
changed = module.set_group_if_different(dest, file_args['group'], changed)
changed = module.set_mode_if_different(dest, file_args['mode'], changed)

module.exit_json(dest=path, src=src, changed=changed)
module.exit_json(dest=dest, src=src, changed=changed)

module.fail_json(path=path, msg='unexpected position reached')
module.fail_json(dest=dest, msg='unexpected position reached')

# this is magic, see lib/ansible/module_common.py
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
Expand Down