Esempio n. 1
0
def git_clone(repo_url, ref='master', proxy_server=None):
    '''Clone a git repository from ``repo_url`` using the reference ``ref``.

    :params repo_url: URL of git repo to clone.
    :params ref: branch, commit or reference in the repo to clone.
    :params proxy_server: optional, HTTP proxy to use while cloning the repo.
    :returns: Path to the cloned repo.
    '''

    if repo_url == '':
        raise source_exceptions.GitException(repo_url)

    os.environ['GIT_TERMINAL_PROMPT'] = '0'
    _tmp_dir = tempfile.mkdtemp(prefix='armada')

    try:
        if proxy_server:
            LOG.info('Cloning [%s] with proxy [%s]', repo_url, proxy_server)
            repo = Repo.clone_from(repo_url, _tmp_dir,
                                   config='http.proxy=%s' % proxy_server)
        else:
            LOG.info('Cloning [%s]', repo_url)
            repo = Repo.clone_from(repo_url, _tmp_dir)

        repo.remotes.origin.fetch(ref)
        g = Git(repo.working_dir)
        g.checkout('FETCH_HEAD')
    except git_exc.GitCommandError as e:
        LOG.exception('Encountered GitCommandError during clone.')
        if 'Could not resolve proxy' in e.stderr:
            raise source_exceptions.GitProxyException(proxy_server)
        else:
            raise source_exceptions.GitException(repo_url)
    except Exception:
        LOG.exception('Encountered unknown Exception during clone.')
        raise source_exceptions.GitException(repo_url)

    return _tmp_dir
Esempio n. 2
0
def git_clone(repo_url, ref='master', proxy_server=None, auth_method=None):
    '''Clone a git repository from ``repo_url`` using the reference ``ref``.

    :param repo_url: URL of git repo to clone.
    :param ref: branch, commit or reference in the repo to clone. Default is
        'master'.
    :param proxy_server: optional, HTTP proxy to use while cloning the repo.
    :param auth_method: Method to use for authenticating against the repository
        specified in ``repo_url``.  If value is "SSH" Armada attempts to
        authenticate against the repository using the SSH key specified under
        ``CONF.ssh_key_path``. If value is None, authentication is skipped.
        Valid values include "SSH" or None. Note that the values are not
        case sensitive. Default is None.
    :returns: Path to the cloned repo.
    :raises GitException: If ``repo_url`` is invalid or could not be found.
    :raises GitAuthException: If authentication with the Git repository failed.
    :raises GitProxyException: If the repo could not be cloned due to a proxy
        issue.
    :raises GitSSHException: If the SSH key specified by ``CONF.ssh_key_path``
        could not be found and ``auth_method`` is "SSH".
    '''

    if not repo_url:
        raise source_exceptions.GitException(repo_url)

    env_vars = {'GIT_TERMINAL_PROMPT': '0'}
    ssh_cmd = None

    if auth_method and auth_method.lower() == 'ssh':
        LOG.debug(
            'Attempting to clone the repo at %s using reference %s '
            'with SSH authentication.', repo_url, ref)

        if not os.path.exists(CONF.ssh_key_path):
            LOG.error('SSH auth method was specified for cloning repo but '
                      'the SSH key under CONF.ssh_key_path was not found.')
            raise source_exceptions.GitSSHException(CONF.ssh_key_path)

        ssh_cmd = (
            'ssh -i {} -o ConnectionAttempts=20 -o ConnectTimeout=10 -o '
            'StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'.format(
                os.path.expanduser(CONF.ssh_key_path)))
        env_vars.update({'GIT_SSH_COMMAND': ssh_cmd})
    else:
        LOG.debug(
            'Attempting to clone the repo at %s using reference %s '
            'with no authentication.', repo_url, ref)

    try:
        temp_dir = tempfile.mkdtemp(prefix='armada')

        if proxy_server:
            LOG.debug('Cloning [%s] with proxy [%s]', repo_url, proxy_server)
            repo = Repo.clone_from(repo_url,
                                   temp_dir,
                                   env=env_vars,
                                   config='http.proxy=%s' % proxy_server)
        else:
            LOG.debug('Cloning [%s]', repo_url)
            repo = Repo.clone_from(repo_url, temp_dir, env=env_vars)

        repo.remotes.origin.fetch(ref)
        g = Git(repo.working_dir)
        g.checkout('FETCH_HEAD')
    except git_exc.GitCommandError as e:
        LOG.exception('Encountered GitCommandError during clone.')
        if ssh_cmd and ssh_cmd in e.stderr:
            raise source_exceptions.GitAuthException(repo_url,
                                                     CONF.ssh_key_path)
        elif 'Could not resolve proxy' in e.stderr:
            raise source_exceptions.GitProxyException(proxy_server)
        else:
            raise source_exceptions.GitException(repo_url)
    except Exception:
        LOG.exception('Encountered unknown Exception during clone.')
        raise source_exceptions.GitException(repo_url)

    return temp_dir