def submodules_fetch(git_path, module, remote, track_submodules, dest): changed = False if not os.path.exists(os.path.join(dest, '.gitmodules')): # no submodules return changed gitmodules_file = open(os.path.join(dest, '.gitmodules'), 'r') for line in gitmodules_file: # Check for new submodules if not changed and line.strip().startswith('path'): path = line.split('=', 1)[1].strip() # Check that dest/path/.git exists if not os.path.exists(os.path.join(dest, path, '.git')): changed = True # add the submodule repo's hostkey if line.strip().startswith('url'): repo = line.split('=', 1)[1].strip() if module.params['ssh_opts'] is not None: if "-o StrictHostKeyChecking=no" not in module.params['ssh_opts']: add_git_host_key(module, repo, accept_hostkey=module.params['accept_hostkey']) else: add_git_host_key(module, repo, accept_hostkey=module.params['accept_hostkey']) # Check for updates to existing modules if not changed: # Fetch updates begin = get_submodule_versions(git_path, module, dest) cmd = [git_path, 'submodule', 'foreach', git_path, 'fetch'] (rc, out, err) = module.run_command(cmd, check_rc=True, cwd=dest) if rc != 0: module.fail_json(msg="Failed to fetch submodules: %s" % out + err) if track_submodules: # Compare against submodule HEAD ### FIXME: determine this from .gitmodules version = 'master' after = get_submodule_versions(git_path, module, dest, '%s/%s' % (remote, version)) if begin != after: changed = True else: # Compare against the superproject's expectation cmd = [git_path, 'submodule', 'status'] (rc, out, err) = module.run_command(cmd, check_rc=True, cwd=dest) if rc != 0: module.fail_json(msg='Failed to retrieve submodule status: %s' % out + err) for line in out.splitlines(): if line[0] != ' ': changed = True break return changed
def setup(cont_name, keyfile, image, need_install_python=False, **kwargs): with open(keyfile) as f: pub_key = f.read() # добавляем директорию ansible_plugins в список, где искать доп. расширения # (до run_api()) from ansible import utils import o_p import os get_par = os.path.dirname utils.plugins.push_basedir(o_p.join(get_par(get_par(__file__)), "ansible_plugins")) import ans_module labels = { "disvolvu": "test" } # настраиваем docker без with_sudo=True res = ans_module.run_api("docker", name=cont_name, image=image, labels=labels, docker_api_version="auto", **kwargs) assert res client = create_dclient() cont = find_container(cont_name, client) assert cont ip_addr = update_ssh_config.get_ipaddr(cont, client) #print(ip_addr) # удаляем предыдущий возможный fingerprint known_hosts = os.path.expanduser("~/.ssh/known_hosts") run_command("""ssh-keygen -f "%(known_hosts)s" -R %(ip_addr)s""" % locals()) # добавляем SSH-публичный ключ хоста в known_hosts, чтобы # ssh не ругался при неинтерактивном соединении from ansible.module_utils.known_hosts import add_git_host_key # :TRICKY: настраиваем фейковый модуль from ansible.module_utils.basic import AnsibleModule ans_module.setup_module_arguments(None) fake_module = AnsibleModule({}) # :KLUDGE: сделать нормальную функцию без имитации git-адреса add_git_host_key(fake_module, "git@%(ip_addr)s/" % locals()) # standard_password = "******" if need_install_python: run_command("sshpass -p %(standard_password)s ssh root@%(ip_addr)s apt-get -y install python" % locals()) # в Ubuntu пакет python уже есть, поэтому # сразу к делу - authorized_key run_module([ { "host": ip_addr, "settings": { "ansible_ssh_user": "******", "ansible_ssh_pass": "******" }, }, ], "authorized_key", '', user="******", key=pub_key) update_ssh_config.main()
def submodules_fetch(git_path, module, remote, track_submodules, dest): changed = False if not os.path.exists(os.path.join(dest, '.gitmodules')): # no submodules return changed gitmodules_file = open(os.path.join(dest, '.gitmodules'), 'r') for line in gitmodules_file: # Check for new submodules if not changed and line.strip().startswith('path'): path = line.split('=', 1)[1].strip() # Check that dest/path/.git exists if not os.path.exists(os.path.join(dest, path, '.git')): changed = True # add the submodule repo's hostkey if line.strip().startswith('url'): repo = line.split('=', 1)[1].strip() if module.params['ssh_opts'] is not None: if "-o StrictHostKeyChecking=no" not in module.params[ 'ssh_opts']: add_git_host_key( module, repo, accept_hostkey=module.params['accept_hostkey']) else: add_git_host_key( module, repo, accept_hostkey=module.params['accept_hostkey']) # Check for updates to existing modules if not changed: # Fetch updates begin = get_submodule_versions(git_path, module, dest) cmd = [git_path, 'submodule', 'foreach', git_path, 'fetch'] (rc, out, err) = module.run_command(cmd, check_rc=True, cwd=dest) if rc != 0: module.fail_json(msg="Failed to fetch submodules: %s" % out + err) if track_submodules: # Compare against submodule HEAD ### FIXME: determine this from .gitmodules version = 'master' after = get_submodule_versions(git_path, module, dest, '%s/%s' % (remote, version)) if begin != after: changed = True else: # Compare against the superproject's expectation cmd = [git_path, 'submodule', 'status'] (rc, out, err) = module.run_command(cmd, check_rc=True, cwd=dest) if rc != 0: module.fail_json( msg='Failed to retrieve submodule status: %s' % out + err) for line in out.splitlines(): if line[0] != ' ': changed = True break return changed
def main(): module = AnsibleModule(argument_spec=dict( dest=dict(type='path'), repo=dict(required=True, aliases=['name']), version=dict(default='HEAD'), remote=dict(default='origin'), refspec=dict(default=None), reference=dict(default=None), force=dict(default='no', type='bool'), depth=dict(default=None, type='int'), clone=dict(default='yes', type='bool'), update=dict(default='yes', type='bool'), verify_commit=dict(default='no', type='bool'), accept_hostkey=dict(default='no', type='bool'), key_file=dict(default=None, type='path', required=False), ssh_opts=dict(default=None, required=False), executable=dict(default=None, type='path'), bare=dict(default='no', type='bool'), recursive=dict(default='yes', type='bool'), track_submodules=dict(default='no', type='bool'), umask=dict(default=None, type='raw'), ), supports_check_mode=True) dest = module.params['dest'] repo = module.params['repo'] version = module.params['version'] remote = module.params['remote'] refspec = module.params['refspec'] force = module.params['force'] depth = module.params['depth'] update = module.params['update'] allow_clone = module.params['clone'] bare = module.params['bare'] verify_commit = module.params['verify_commit'] reference = module.params['reference'] git_path = module.params['executable'] or module.get_bin_path('git', True) key_file = module.params['key_file'] ssh_opts = module.params['ssh_opts'] umask = module.params['umask'] result = dict(changed=False, warnings=list()) # evaluate and set the umask before doing anything else if umask is not None: if not isinstance(umask, string_types): module.fail_json( msg="umask must be defined as a quoted octal integer") try: umask = int(umask, 8) except: module.fail_json(msg="umask must be an octal integer", details=str(sys.exc_info()[1])) os.umask(umask) # Certain features such as depth require a file:/// protocol for path based urls # so force a protocol here ... if repo.startswith('/'): repo = 'file://' + repo # We screenscrape a huge amount of git commands so use C locale anytime we # call run_command() module.run_command_environ_update = dict(LANG='C', LC_ALL='C', LC_MESSAGES='C', LC_CTYPE='C') gitconfig = None if not dest and allow_clone: module.fail_json( msg="the destination directory must be specified unless clone=no") elif dest: dest = os.path.abspath(dest) if bare: gitconfig = os.path.join(dest, 'config') else: gitconfig = os.path.join(dest, '.git', 'config') # create a wrapper script and export # GIT_SSH=<path> as an environment variable # for git to use the wrapper script ssh_wrapper = None if key_file or ssh_opts: ssh_wrapper = write_ssh_wrapper() set_git_ssh(ssh_wrapper, key_file, ssh_opts) module.add_cleanup_file(path=ssh_wrapper) # add the git repo's hostkey if module.params['ssh_opts'] is not None: if "-o StrictHostKeyChecking=no" not in module.params['ssh_opts']: add_git_host_key(module, repo, accept_hostkey=module.params['accept_hostkey']) else: add_git_host_key(module, repo, accept_hostkey=module.params['accept_hostkey']) git_version_used = git_version(git_path, module) if depth is not None and git_version_used < LooseVersion('1.9.1'): result['warnings'].append( "Your git version is too old to fully support the depth argument. Falling back to full checkouts." ) depth = None recursive = module.params['recursive'] track_submodules = module.params['track_submodules'] result.update(before=None) local_mods = False need_fetch = True if (dest and not os.path.exists(gitconfig)) or (not dest and not allow_clone): # if there is no git configuration, do a clone operation unless: # * the user requested no clone (they just want info) # * we're doing a check mode test # In those cases we do an ls-remote if module.check_mode or not allow_clone: remote_head = get_remote_head(git_path, module, dest, version, repo, bare) result.update(changed=True, after=remote_head) if module._diff: diff = get_diff(module, git_path, dest, repo, remote, depth, bare, result['before'], result['after']) if diff: result['diff'] = diff module.exit_json(**result) # there's no git config, so clone clone(git_path, module, repo, dest, remote, depth, version, bare, reference, refspec, verify_commit) need_fetch = False elif not update: # Just return having found a repo already in the dest path # this does no checking that the repo is the actual repo # requested. result['before'] = get_version(module, git_path, dest) result.update(after=result['before']) module.exit_json(**result) else: # else do a pull local_mods = has_local_mods(module, git_path, dest, bare) result['before'] = get_version(module, git_path, dest) if local_mods: # failure should happen regardless of check mode if not force: module.fail_json( msg="Local modifications exist in repository (force=no).", **result) # if force and in non-check mode, do a reset if not module.check_mode: reset(git_path, module, dest) result.update(changed=True, msg='Local modifications exist.') # exit if already at desired sha version if module.check_mode: remote_url = get_remote_url(git_path, module, dest, remote) remote_url_changed = remote_url and remote_url != repo and remote_url != unfrackgitpath( repo) else: remote_url_changed = set_remote_url(git_path, module, repo, dest, remote) result.update(remote_url_changed=remote_url_changed) if module.check_mode: remote_head = get_remote_head(git_path, module, dest, version, remote, bare) result.update(changed=(result['before'] != remote_head or remote_url_changed), after=remote_head) # FIXME: This diff should fail since the new remote_head is not fetched yet?! if module._diff: diff = get_diff(module, git_path, dest, repo, remote, depth, bare, result['before'], result['after']) if diff: result['diff'] = diff module.exit_json(**result) else: fetch(git_path, module, repo, dest, version, remote, depth, bare, refspec, git_version_used) result['after'] = get_version(module, git_path, dest) # switch to version specified regardless of whether # we got new revisions from the repository if not bare: switch_version(git_path, module, dest, remote, version, verify_commit, depth) # Deal with submodules submodules_updated = False if recursive and not bare: submodules_updated = submodules_fetch(git_path, module, remote, track_submodules, dest) if submodules_updated: result.update(submodules_changed=submodules_updated) if module.check_mode: result.update(changed=True, after=remote_head) module.exit_json(**result) # Switch to version specified submodule_update(git_path, module, dest, track_submodules, force=force) # determine if we changed anything result['after'] = get_version(module, git_path, dest) if result['before'] != result[ 'after'] or local_mods or submodules_updated or remote_url_changed: result.update(changed=True) if module._diff: diff = get_diff(module, git_path, dest, repo, remote, depth, bare, result['before'], result['after']) if diff: result['diff'] = diff # cleanup the wrapper script if ssh_wrapper: try: os.remove(ssh_wrapper) except OSError: # No need to fail if the file already doesn't exist pass module.exit_json(**result)
def main(): module = AnsibleModule( argument_spec = dict( dest=dict(type='path'), repo=dict(required=True, aliases=['name']), version=dict(default='HEAD'), remote=dict(default='origin'), refspec=dict(default=None), reference=dict(default=None), force=dict(default='no', type='bool'), depth=dict(default=None, type='int'), clone=dict(default='yes', type='bool'), update=dict(default='yes', type='bool'), verify_commit=dict(default='no', type='bool'), accept_hostkey=dict(default='no', type='bool'), key_file=dict(default=None, type='path', required=False), ssh_opts=dict(default=None, required=False), executable=dict(default=None, type='path'), bare=dict(default='no', type='bool'), recursive=dict(default='yes', type='bool'), track_submodules=dict(default='no', type='bool'), umask=dict(default=None, type='raw'), ), supports_check_mode=True ) dest = module.params['dest'] repo = module.params['repo'] version = module.params['version'] remote = module.params['remote'] refspec = module.params['refspec'] force = module.params['force'] depth = module.params['depth'] update = module.params['update'] allow_clone = module.params['clone'] bare = module.params['bare'] verify_commit = module.params['verify_commit'] reference = module.params['reference'] git_path = module.params['executable'] or module.get_bin_path('git', True) key_file = module.params['key_file'] ssh_opts = module.params['ssh_opts'] umask = module.params['umask'] result = dict( warnings=list() ) # evaluate and set the umask before doing anything else if umask is not None: if not isinstance(umask, string_types): module.fail_json(msg="umask must be defined as a quoted octal integer") try: umask = int(umask, 8) except: module.fail_json(msg="umask must be an octal integer", details=str(sys.exc_info()[1])) os.umask(umask) # Certain features such as depth require a file:/// protocol for path based urls # so force a protocal here ... if repo.startswith('/'): repo = 'file://' + repo # We screenscrape a huge amount of git commands so use C locale anytime we # call run_command() module.run_command_environ_update = dict(LANG='C', LC_ALL='C', LC_MESSAGES='C', LC_CTYPE='C') gitconfig = None if not dest and allow_clone: module.fail_json(msg="the destination directory must be specified unless clone=no") elif dest: dest = os.path.abspath(dest) if bare: gitconfig = os.path.join(dest, 'config') else: gitconfig = os.path.join(dest, '.git', 'config') # create a wrapper script and export # GIT_SSH=<path> as an environment variable # for git to use the wrapper script ssh_wrapper = None if key_file or ssh_opts: ssh_wrapper = write_ssh_wrapper() set_git_ssh(ssh_wrapper, key_file, ssh_opts) module.add_cleanup_file(path=ssh_wrapper) # add the git repo's hostkey if module.params['ssh_opts'] is not None: if "-o StrictHostKeyChecking=no" not in module.params['ssh_opts']: add_git_host_key(module, repo, accept_hostkey=module.params['accept_hostkey']) else: add_git_host_key(module, repo, accept_hostkey=module.params['accept_hostkey']) git_version_used = git_version(git_path, module) if depth is not None and git_version_used < LooseVersion('1.9.1'): result['warnings'].append("Your git version is too old to fully support the depth argument. Falling back to full checkouts.") depth = None recursive = module.params['recursive'] track_submodules = module.params['track_submodules'] result.update(before=None) local_mods = False need_fetch = True if (dest and not os.path.exists(gitconfig)) or (not dest and not allow_clone): # if there is no git configuration, do a clone operation unless: # * the user requested no clone (they just want info) # * we're doing a check mode test # In those cases we do an ls-remote if module.check_mode or not allow_clone: remote_head = get_remote_head(git_path, module, dest, version, repo, bare) result.update(changed=True, after=remote_head) if module._diff: diff = get_diff(module, git_path, dest, repo, remote, depth, bare, result['before'], result['after']) if diff: result['diff'] = diff module.exit_json(**result) # there's no git config, so clone clone(git_path, module, repo, dest, remote, depth, version, bare, reference, refspec, verify_commit) need_fetch = False elif not update: # Just return having found a repo already in the dest path # this does no checking that the repo is the actual repo # requested. result['before'] = get_version(module, git_path, dest) result.update(changed=False, after=result['before']) module.exit_json(**result) else: # else do a pull local_mods = has_local_mods(module, git_path, dest, bare) result['before'] = get_version(module, git_path, dest) if local_mods: # failure should happen regardless of check mode if not force: module.fail_json(msg="Local modifications exist in repository (force=no).", **result) # if force and in non-check mode, do a reset if not module.check_mode: reset(git_path, module, dest) # exit if already at desired sha version if module.check_mode: remote_url = get_remote_url(git_path, module, dest, remote) remote_url_changed = remote_url and remote_url != repo and remote_url != unfrackgitpath(repo) else: remote_url_changed = set_remote_url(git_path, module, repo, dest, remote) if remote_url_changed: result.update(remote_url_changed=True) if need_fetch: if module.check_mode: remote_head = get_remote_head(git_path, module, dest, version, remote, bare) result.update(changed=(result['before'] != remote_head), after=remote_head) # FIXME: This diff should fail since the new remote_head is not fetched yet?! if module._diff: diff = get_diff(module, git_path, dest, repo, remote, depth, bare, result['before'], result['after']) if diff: result['diff'] = diff module.exit_json(**result) else: fetch(git_path, module, repo, dest, version, remote, depth, bare, refspec, git_version_used) result['after'] = get_version(module, git_path, dest) if result['before'] == result['after']: if local_mods: result.update(changed=True, after=remote_head, msg='Local modifications exist') # no diff, since the repo didn't change module.exit_json(**result) # switch to version specified regardless of whether # we got new revisions from the repository if not bare: switch_version(git_path, module, dest, remote, version, verify_commit, depth) # Deal with submodules submodules_updated = False if recursive and not bare: submodules_updated = submodules_fetch(git_path, module, remote, track_submodules, dest) if submodules_updated: result.update(submodules_changed=submodules_updated) if module.check_mode: result.update(changed=True, after=remote_head) module.exit_json(**result) # Switch to version specified submodule_update(git_path, module, dest, track_submodules, force=force) # determine if we changed anything result['after'] = get_version(module, git_path, dest) result.update(changed=False) if result['before'] != result['after'] or local_mods or submodules_updated or remote_url_changed: result.update(changed=True) if module._diff: diff = get_diff(module, git_path, dest, repo, remote, depth, bare, result['before'], result['after']) if diff: result['diff'] = diff # cleanup the wrapper script if ssh_wrapper: try: os.remove(ssh_wrapper) except OSError: # No need to fail if the file already doesn't exist pass module.exit_json(**result)