Add archive option in git plugin (#23332)
* Add archive option in git plugin This fix will add archive option in git plugin Fixes https://github.com/ansible/ansible/issues/22943 Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com> * Update code as per code review comments Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
This commit is contained in:
parent
91969b8c67
commit
e9672748cc
1 changed files with 93 additions and 0 deletions
|
@ -186,6 +186,15 @@ options:
|
||||||
to be installed. The commit MUST be signed and the public key MUST
|
to be installed. The commit MUST be signed and the public key MUST
|
||||||
be trusted in the GPG trustdb.
|
be trusted in the GPG trustdb.
|
||||||
|
|
||||||
|
archive:
|
||||||
|
required: false
|
||||||
|
version_added: "2.4"
|
||||||
|
description:
|
||||||
|
- Specify archive file path with extension. If specified, creates an
|
||||||
|
archive file of the specified format containing the tree structure
|
||||||
|
for the source tree.
|
||||||
|
Allowed archive formats ["zip", "tar.gz", "tar", "tgz"]
|
||||||
|
|
||||||
requirements:
|
requirements:
|
||||||
- git>=1.7.1 (the command line tool)
|
- git>=1.7.1 (the command line tool)
|
||||||
|
|
||||||
|
@ -228,6 +237,13 @@ EXAMPLES = '''
|
||||||
repo: https://github.com/ansible/ansible-examples.git
|
repo: https://github.com/ansible/ansible-examples.git
|
||||||
dest: /src/ansible-examples
|
dest: /src/ansible-examples
|
||||||
refspec: '+refs/pull/*:refs/heads/*'
|
refspec: '+refs/pull/*:refs/heads/*'
|
||||||
|
|
||||||
|
# Example Create git archive from repo
|
||||||
|
- git:
|
||||||
|
repo: https://github.com/ansible/ansible-examples.git
|
||||||
|
dest: /src/ansible-examples
|
||||||
|
archive: /tmp/ansible-examples.zip
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
RETURN = '''
|
RETURN = '''
|
||||||
|
@ -253,15 +269,18 @@ warnings:
|
||||||
sample: Your git version is too old to fully support the depth argument. Falling back to full checkouts.
|
sample: Your git version is too old to fully support the depth argument. Falling back to full checkouts.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
import filecmp
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import shlex
|
import shlex
|
||||||
import stat
|
import stat
|
||||||
import sys
|
import sys
|
||||||
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
from distutils.version import LooseVersion
|
from distutils.version import LooseVersion
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule, get_module_path
|
from ansible.module_utils.basic import AnsibleModule, get_module_path
|
||||||
|
from ansible.module_utils.basic import get_exception
|
||||||
from ansible.module_utils.known_hosts import add_git_host_key
|
from ansible.module_utils.known_hosts import add_git_host_key
|
||||||
from ansible.module_utils.six import b, string_types
|
from ansible.module_utils.six import b, string_types
|
||||||
from ansible.module_utils._text import to_native
|
from ansible.module_utils._text import to_native
|
||||||
|
@ -901,6 +920,68 @@ def git_version(git_path, module):
|
||||||
return LooseVersion(rematch.groups()[0])
|
return LooseVersion(rematch.groups()[0])
|
||||||
|
|
||||||
|
|
||||||
|
def git_archive(git_path, module, dest, archive, archive_fmt, version):
|
||||||
|
""" Create git archive in given source directory """
|
||||||
|
cmd = "%s archive --format=%s --output=%s %s" \
|
||||||
|
% (git_path, archive_fmt, archive, version)
|
||||||
|
(rc, out, err) = module.run_command(cmd, cwd=dest)
|
||||||
|
if rc != 0:
|
||||||
|
module.fail_json(msg="Failed to perform archive operation",
|
||||||
|
details="Git archive command failed to create "
|
||||||
|
"archive %s using %s directory."
|
||||||
|
"Error: %s" % (archive, dest, err))
|
||||||
|
return rc, out, err
|
||||||
|
|
||||||
|
|
||||||
|
def create_archive(git_path, module, dest, archive, version, repo, result):
|
||||||
|
""" Helper function for creating archive using git_archive """
|
||||||
|
all_archive_fmt = {'.zip': 'zip', '.gz': 'tar.gz', '.tar': 'tar',
|
||||||
|
'.tgz': 'tgz'}
|
||||||
|
_, archive_ext = os.path.splitext(archive)
|
||||||
|
archive_fmt = all_archive_fmt.get(archive_ext, None)
|
||||||
|
if archive_fmt is None:
|
||||||
|
module.fail_json(msg="Unable to get file extension from "
|
||||||
|
"archive file name : %s" % archive,
|
||||||
|
details="Please specify archive as filename with "
|
||||||
|
"extension. File extension can be one "
|
||||||
|
"of ['tar', 'tar.gz', 'zip', 'tgz']")
|
||||||
|
|
||||||
|
repo_name = repo.split("/")[-1].replace(".git", "")
|
||||||
|
|
||||||
|
if os.path.exists(archive):
|
||||||
|
# If git archive file exists, then compare it with new git archive file.
|
||||||
|
# if match, do nothing
|
||||||
|
# if does not match, then replace existing with temp archive file.
|
||||||
|
tempdir = tempfile.mkdtemp()
|
||||||
|
new_archive_dest = os.path.join(tempdir, repo_name)
|
||||||
|
new_archive = new_archive_dest + '.' + archive_fmt
|
||||||
|
git_archive(git_path, module, dest, new_archive, archive_fmt, version)
|
||||||
|
|
||||||
|
# filecmp is supposed to be efficient than md5sum checksum
|
||||||
|
if filecmp.cmp(new_archive, archive):
|
||||||
|
result.update(changed=False)
|
||||||
|
# Cleanup before exiting
|
||||||
|
try:
|
||||||
|
shutil.remove(tempdir)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
shutil.move(new_archive, archive)
|
||||||
|
shutil.remove(tempdir)
|
||||||
|
result.update(changed=True)
|
||||||
|
except OSError:
|
||||||
|
exception = get_exception()
|
||||||
|
module.fail_json(msg="Failed to move %s to %s" %
|
||||||
|
(new_archive, archive),
|
||||||
|
details="Error occured while moving : %s"
|
||||||
|
% exception)
|
||||||
|
else:
|
||||||
|
# Perform archive from local directory
|
||||||
|
git_archive(git_path, module, dest, archive, archive_fmt, version)
|
||||||
|
result.update(changed=True)
|
||||||
|
|
||||||
|
|
||||||
# ===========================================
|
# ===========================================
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -925,6 +1006,7 @@ def main():
|
||||||
recursive=dict(default='yes', type='bool'),
|
recursive=dict(default='yes', type='bool'),
|
||||||
track_submodules=dict(default='no', type='bool'),
|
track_submodules=dict(default='no', type='bool'),
|
||||||
umask=dict(default=None, type='raw'),
|
umask=dict(default=None, type='raw'),
|
||||||
|
archive=dict(type='path'),
|
||||||
),
|
),
|
||||||
supports_check_mode=True
|
supports_check_mode=True
|
||||||
)
|
)
|
||||||
|
@ -945,6 +1027,7 @@ def main():
|
||||||
key_file = module.params['key_file']
|
key_file = module.params['key_file']
|
||||||
ssh_opts = module.params['ssh_opts']
|
ssh_opts = module.params['ssh_opts']
|
||||||
umask = module.params['umask']
|
umask = module.params['umask']
|
||||||
|
archive = module.params['archive']
|
||||||
|
|
||||||
result = dict(changed=False, warnings=list())
|
result = dict(changed=False, warnings=list())
|
||||||
|
|
||||||
|
@ -1003,6 +1086,7 @@ def main():
|
||||||
track_submodules = module.params['track_submodules']
|
track_submodules = module.params['track_submodules']
|
||||||
|
|
||||||
result.update(before=None)
|
result.update(before=None)
|
||||||
|
|
||||||
local_mods = False
|
local_mods = False
|
||||||
need_fetch = True
|
need_fetch = True
|
||||||
if (dest and not os.path.exists(gitconfig)) or (not dest and not allow_clone):
|
if (dest and not os.path.exists(gitconfig)) or (not dest and not allow_clone):
|
||||||
|
@ -1092,6 +1176,15 @@ def main():
|
||||||
if diff:
|
if diff:
|
||||||
result['diff'] = diff
|
result['diff'] = diff
|
||||||
|
|
||||||
|
if archive:
|
||||||
|
# Git archive is not supported by all git servers, so
|
||||||
|
# we will first clone and perform git archive from local directory
|
||||||
|
if module.check_mode:
|
||||||
|
result.update(changed=True)
|
||||||
|
module.exit_json(**result)
|
||||||
|
|
||||||
|
create_archive(git_path, module, dest, archive, version, repo, result)
|
||||||
|
|
||||||
# cleanup the wrapper script
|
# cleanup the wrapper script
|
||||||
if ssh_wrapper:
|
if ssh_wrapper:
|
||||||
try:
|
try:
|
||||||
|
|
Loading…
Reference in a new issue