Esempio n. 1
0
def remove_repos_by_id(repo_ids):
    """
    Try to remove each of the given 'repo_ids':
    Find the url and determine the path.
    If resource exists on the filesystem level ->
    remove its files and DB record.
    """
    for git_repo in repo_ids:
        git_repo_id = ''.join(('git_repo_id:', str(git_repo)))
        repo_url = redis.hmget(git_repo_id, 'url')[0]

        if repo_url:
            repo_name = repo_url.split('/')[-1]  # assuming url is valid!
            git_repo_path = path.join(GIT_REPOS_PATH, repo_name)

            if check_repo_was_cloned(git_repo_path, git_repo_id):
                rmtree(git_repo_path)  # folder on FS
                redis.delete(git_repo_id)  # DB record
                redis.delete(repo_url)  # DB record

            else:
                raise BadRequest('Bad Request', 400,
                                {'error': 'The repository with id %s is '
                                 'not yet cloned.' % git_repo})
        else:
            raise BadRequest('Bad Request', 400,
                            {'error': 'Could not find an url for repository '
                             'with a given id %s. Repository may not exist.'
                             % git_repo})
Esempio n. 2
0
def check_repo_was_cloned(repo_path, repo_id):
    """
    Returns True if in the given 'repo_path' a .git folder
    can be found, it contains a non-empty index file, and
    respective DB record has a 'last_checkout' timestamp.
    """
    path_to_git_index = path.join(repo_path, '.git/index')

    if path.exists(path_to_git_index):
        if stat(path_to_git_index).st_size > 0:
            if redis.hmget(repo_id, 'last_checkout')[0]:
                return True
Esempio n. 3
0
def run_git_clone_or_checkout(git_repo_id):
    """
    Clones or checks out the repository to 'GIT_REPOS_PATH/'.
    Operations performed with lock to avoid race conditions if
    two users are POSTing the same url at the same time.
    """
    # Get the respective repo url, branch, revision:
    repo_url = redis.hmget(git_repo_id, 'url')[0]
    repo_branch = redis.hmget(git_repo_id, 'branch')[0] or 'master'
    repo_revision = redis.hmget(git_repo_id, 'revision')[0]

    repo_name = repo_url.split('/')[-1]  # assuming url is valid!
    git_repo_path = path.join(GIT_REPOS_PATH, repo_name)  # where to clone
    clone_params = {'branch': repo_branch}  # branch to clone

    with open("".join((repo_name, '.lock')), 'w') as lock_file:
        fcntl.flock(lock_file, fcntl.LOCK_EX)  # lock

        try:
            if check_repo_was_cloned(git_repo_path, git_repo_id):
                redis.hdel(git_repo_id, 'last_checkout')  # del last_checkout value
                GitRepo = Repo(git_repo_path)
                GitRepo.git.checkout(repo_branch)

            else:  # otherwise clone the repo:
                GitRepo = Repo.clone_from(repo_url, git_repo_path, **clone_params)

            if repo_revision:  # goto exact commit/revision, if was specified
                GitRepo.git.checkout(repo_revision)

            update_repo_stats(git_repo_id, git_repo_path, GitRepo)

        except (git_exc.CheckoutError, git_exc.InvalidGitRepositoryError,
                git_exc.NoSuchPathError, git_exc.GitCommandError) as exc:
            app.logger.error("Error while git was working: %s" % exc)

        fcntl.flock(lock_file, fcntl.LOCK_UN)  # unlock