Skip to content

feat(db): add query to perform rename of repository

Suleimi Ahmed requested to merge 894-introduce-rename-repository-query into master

Related to #894 (closed)

Context 🌱

Renaming a GitLab project that contains container repositories is not allowed today. This is mainly because we do not have support for renaming the project's associated repositories to match the new project name.

This MR puts us a step closer to realizing renaming a GitLab project that contains container repositories, by introducing the necessary queries for renaming a repository (and all its sub-repositories) into the registry codebase. Subsequent MRs can then expose this functionality that can be utilized by Gitlab rails when performing a project rename. See #894 (closed) and its parent epic &9761 for more details.

What's in this MR? 🎰

This MR introduces three queries to:

  1. Update all repositories that start with a specific path to a new path. The new path is constructed with the same parent directory structure as the old-path, only replacing the base path (i.e the last part of the path) to the newly specified base path.

e.g: All repositories with path: my-group/my-sub-group/old-repo-name will be changed to my-group/my-sub-group/new-repo-name, where new-repo-name is the newly specified base path

  1. Update the name of a repository to a new name
  2. Count the number of repositories under a specific repository path

Why? 🐳

This is a build up to #894 (closed), that aims to expose an API endpoint to facilitate renaming a container repository (and all its sub-repositories) when a GitLab project rename is triggered.

How will these queries be used once exposed via an API

The two main queries (to process a rename) added in this MR are expected be run under the following conditions:

  1. The rename queries are expected to be used together in the same transaction. This means for a rename operation to be successful both the repository rename query (i.e RenameRepository) and the sub-repository rename query (i.e RenamePathForSubRepositories) must succeed. The current plan is to wrap both rename operations in a transaction from a rename request handler (in a subsequent MR) like so:
        tx, err := h.db.BeginTx(h.Context, nil)
	if err != nil {
		...
	}
	defer tx.Rollback()
	rStoreTx := datastore.NewRepositoryStore(tx)
	err = rStoreTx.RenameRepository(txCtx, repo.NamespaceID, repo.Path, newPath, newName)
	if err != nil {
		...
	}
	err = rStoreTx.RenamePathForSubRepositories(txCtx, repo.NamespaceID, repo.Path, newPath)
	if err != nil {
               ...
	}

The pattern above of starting the transaction at the handler level is consistent with other db transaction patterns that exist in the code base today.

  1. The count query is expected to be run independently (i.e outside the transaction mentioned in 2.) to count how many repositories exist under a given path before proceeding with a rename. This is to make sure the rename queries will only be used against repositories with less than 1000 sub repositories (For GitLab.com, this covers 99.98% of all projects) for now.
Edited by Suleimi Ahmed

Merge request reports