Exemple #1
0
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
Exemple #2
0
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()
Exemple #3
0
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
Exemple #4
0
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)
Exemple #5
0
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)