Merge pull request #3516 from dagwieers/file-dest

Fix inconsistent json output in file module
pull/3502/merge
Michael DeHaan 12 years ago
commit cac5e7d168

@ -37,12 +37,12 @@ description:
files/symlinks/directories. Many other modules support the same options as files/symlinks/directories. Many other modules support the same options as
the M(file) module - including M(copy), M(template), and M(assemble). the M(file) module - including M(copy), M(template), and M(assemble).
options: options:
path: dest:
description: 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) - 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 required: true
default: [] default: []
aliases: ['dest', 'name'] aliases: ['name', 'path']
state: state:
description: description:
- If C(directory), all immediate subdirectories will be created if they - If C(directory), all immediate subdirectories will be created if they
@ -127,7 +127,7 @@ options:
description: description:
- 'force the creation of the symlinks in two cases: the source file does - '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 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: notes:
- See also M(copy), M(template), M(assemble) - See also M(copy), M(template), M(assemble)
requirements: [ ] requirements: [ ]
@ -135,18 +135,18 @@ author: Michael DeHaan
''' '''
EXAMPLES = ''' 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 - 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: try:
if state == 'hard': if state == 'hard':
os.link(src,path) os.link(src,dest)
else: else:
os.symlink(src, path) os.symlink(src, dest)
except OSError, e: 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(): def main():
@ -156,7 +156,7 @@ def main():
module = AnsibleModule( module = AnsibleModule(
argument_spec = dict( argument_spec = dict(
state = dict(choices=['file','directory','link','hard','absent'], default='file'), 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'), recurse = dict(default='no', type='bool'),
force = dict(required=False,default=False,type='bool'), force = dict(required=False,default=False,type='bool'),
diff_peek = dict(default=None), diff_peek = dict(default=None),
@ -169,20 +169,20 @@ def main():
params = module.params params = module.params
state = params['state'] state = params['state']
force = params['force'] force = params['force']
params['path'] = path = os.path.expanduser(params['path']) params['dest'] = dest = os.path.expanduser(params['dest'])
# short-circuit for diff_peek # short-circuit for diff_peek
if params.get('diff_peek', None) is not None: if params.get('diff_peek', None) is not None:
appears_binary = False appears_binary = False
try: try:
f = open(path) f = open(dest)
b = f.read(8192) b = f.read(8192)
f.close() f.close()
if b.find("\x00") != -1: if b.find("\x00") != -1:
appears_binary = True appears_binary = True
except: except:
pass 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 # 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 # or copy module, even if this module never uses it, it is needed to key off some things
@ -191,24 +191,24 @@ def main():
if src: if src:
src = os.path.expanduser(src) src = os.path.expanduser(src)
if src is not None and os.path.isdir(path) and state != "link": if src is not None and os.path.isdir(dest) and state != "link":
params['path'] = path = os.path.join(path, os.path.basename(src)) params['dest'] = dest = os.path.join(dest, os.path.basename(src))
file_args = module.load_file_common_arguments(params) 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') 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') module.fail_json(msg='path is required')
changed = False changed = False
prev_state = 'absent' prev_state = 'absent'
if os.path.lexists(path): if os.path.lexists(dest):
if os.path.islink(path): if os.path.islink(dest):
prev_state = 'link' prev_state = 'link'
elif os.path.isdir(path): elif os.path.isdir(dest):
prev_state = 'directory' prev_state = 'directory'
else: else:
prev_state = 'file' prev_state = 'file'
@ -216,64 +216,64 @@ def main():
if prev_state != 'absent' and state == 'absent': if prev_state != 'absent' and state == 'absent':
try: try:
if prev_state == 'directory': if prev_state == 'directory':
if os.path.islink(path): if os.path.islink(dest):
if module.check_mode: if module.check_mode:
module.exit_json(changed=True) module.exit_json(changed=True)
os.unlink(path) os.unlink(dest)
else: else:
try: try:
if module.check_mode: if module.check_mode:
module.exit_json(changed=True) module.exit_json(changed=True)
shutil.rmtree(path, ignore_errors=False) shutil.rmtree(dest, ignore_errors=False)
except: except:
module.exit_json(msg="rmtree failed") module.exit_json(msg="rmtree failed")
else: else:
if module.check_mode: if module.check_mode:
module.exit_json(changed=True) module.exit_json(changed=True)
os.unlink(path) os.unlink(dest)
except Exception, e: except Exception, e:
module.fail_json(path=path, msg=str(e)) module.fail_json(dest=dest, msg=str(e))
module.exit_json(path=path, changed=True) module.exit_json(dest=dest, changed=True)
if prev_state != 'absent' and prev_state != state: if prev_state != 'absent' and prev_state != state:
if force and prev_state == 'file' and state == 'link': if force and prev_state == 'file' and state == 'link':
pass pass
else: 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': 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 state == 'file':
if prev_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) 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': elif state == 'directory':
if prev_state == 'absent': if prev_state == 'absent':
if module.check_mode: if module.check_mode:
module.exit_json(changed=True) module.exit_json(changed=True)
os.makedirs(path) os.makedirs(dest)
changed = True changed = True
changed = module.set_directory_attributes_if_different(file_args, changed) changed = module.set_directory_attributes_if_different(file_args, changed)
recurse = params['recurse'] recurse = params['recurse']
if 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: for dir in dirs:
dirname=os.path.join(root,dir) dirname=os.path.join(root,dir)
tmp_file_args = file_args.copy() 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) changed = module.set_directory_attributes_if_different(tmp_file_args, changed)
for file in files: for file in files:
filename=os.path.join(root,file) filename=os.path.join(root,file)
tmp_file_args = file_args.copy() 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) 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']: elif state in ['link','hard']:
@ -283,46 +283,46 @@ def main():
module.fail_json(msg="absolute paths are required") module.fail_json(msg="absolute paths are required")
if not os.path.exists(abs_src) and not force: 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 prev_state == 'absent':
if module.check_mode: if module.check_mode:
module.exit_json(changed=True) module.exit_json(changed=True)
dolink(src, path, state, module) dolink(src, dest, state, module)
changed = True changed = True
elif prev_state == 'link': elif prev_state == 'link':
old_src = os.readlink(path) old_src = os.readlink(dest)
if not os.path.isabs(old_src): 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 old_src != src:
if module.check_mode: if module.check_mode:
module.exit_json(changed=True) module.exit_json(changed=True)
os.unlink(path) os.unlink(dest)
dolink(src, path, state, module) dolink(src, dest, state, module)
changed = True changed = True
elif prev_state == 'file': elif prev_state == 'file':
if not force: 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: else:
if module.check_mode: if module.check_mode:
module.exit_json(changed=True) module.exit_json(changed=True)
os.unlink(path) os.unlink(dest)
dolink(src, path, state, module) dolink(src, dest, state, module)
changed = True changed = True
else: 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 # set modes owners and context as needed
file_args = module.load_file_common_arguments(module.params) file_args = module.load_file_common_arguments(module.params)
changed = module.set_context_if_different(path, file_args['secontext'], changed) changed = module.set_context_if_different(dest, file_args['secontext'], changed)
changed = module.set_owner_if_different(path, file_args['owner'], changed) changed = module.set_owner_if_different(dest, file_args['owner'], changed)
changed = module.set_group_if_different(path, file_args['group'], changed) changed = module.set_group_if_different(dest, file_args['group'], changed)
changed = module.set_mode_if_different(path, file_args['mode'], 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 # this is magic, see lib/ansible/module_common.py
#<<INCLUDE_ANSIBLE_MODULE_COMMON>> #<<INCLUDE_ANSIBLE_MODULE_COMMON>>

Loading…
Cancel
Save