docker/docker — pull request #8456 by dkjer (2014-10-07 20:31:14+00:00)
Title: Cleanup: Replace ResolveRepositoryName with RepositoryInfo{}

# Reason for cleanup

Currently, we breakdown a repository name using a combination of ResolveRepositoryName, and NewEndpoint as follows:

```
debian
\____/
|
repoName => ResolveRepositoryName()
|
______/ \_____________________
/ \
https://index.docker.io/v1/ debian
\_________________________/ \____/
| |
hostname => NewEndpoint() remoteName
| |
endpoint ___/\______
| / \
https://index.docker.io/v1/ library/debian debian
\______/\_____________/\__/ \____________/ \___/
| | | | |
URL.Scheme URL.Host Version remoteName~ localName

127.0.0.1:5000/myapp _________________________________
\__________________/ \
| |
repoName => ResolveRepositoryName() |
| |
______/ \______________________ |
/ \ |
127.0.0.1:5000 myapp |
\____________/ \____/ |
| | |
hostname => NewEndpoint() | |
| | |
GET https://127.0.0.1:5000/v1/_ping | |
| | |
x (Error) | |
| | |
GET http://127.0.0.1:5000/v1/_ping | |
| | |
endpoint | |
| | |
http://127.0.0.1:5000/v1/ | |
\_____/\____________/\__/ | |
| | | | |
URL.Scheme URL.Host Version remoteName localName
```

However, policies around whether or not repository is using the 'official index' or an 'official repository' are sprinkled throughout the code. Also, rules regarding remoteName for the official repositories ('library/ prefix'), localName, which mirrors to use, etc, are also sprinkled throughout the code.

This results in awkward follow-up checks against repository names, such as
```
if len(strings.SplitN(name, "/", 2)) == 1 { ... "You cannot push a \"root\" repository." ...}
```
```
if endpoint.VersionString(1) == registry.IndexServerAddress() { ... [clean up names and set up mirrors] ... }
```

Having to track down these pieces of logic throughout the code makes modifications to repository name parsing fragile, and hard to test.

# Refactors made

## ResolveRepositoryName(repoName) deprecated.
Replaced with the following:
* ValidateRepositoryName(repoName)
* Used when a RepositoryInfo breakdown is not needed, just a validation check.
* ParseRepositoryInfo(repoName)
* Used when RegistryServiceConfig is not available, and just performs the breakdown (above)
* ResolveRepositoryInfo
* Calls a Job("resolve_repository") to fully resolve a repository name into a RepositoryInfo
* Result includes repository configuration (for now, only Mirrors are defined).

## RepositoryInfo

```
type RepositoryInfo struct {
IndexName string `json:"index_name"`
Mirrors []string `json:"mirrors"`
RemoteName string `json:"remote_name"`
LocalName string `json:"local_name"`
CanonicalName string `json:"canonical_name"`
IsOfficialIndex bool `json:"is_official_index"`
IsOfficialRepo bool `json:"is_official_repo"`
}
```

Returned by ParseRepositoryInfo, or ResolveRepositoryInfo.
* IndexName: Replaces 'hostname'.
* Examples: 'docker.io' (official), '127.0.0.1:8000' (private)
* Mirrors: List of mirrors for use in a pull.
* Only configurable for official index, currently.
* RemoteName: Remote repository name
* Examples: 'library/debian', 'user/repo'
* Policies for official repo names are resolved.
* LocalName: Name to use in TagStore.Repositories
* Examples: 'debian', '127.0.0.1:8000/user/repo'
* Policies for official vs private repo names are resolved.
* CanonicalName: 'global' name of repository.
* Displayed to the user in information messages, e.g.: "Pulling image from "
* For now, the CanonicalName matches LocalName rules.
* IsOfficialIndex: Whether or not repository refers to the official docker.io index.
* IsOfficialRepo: Whether or not repository refers to a library repository on the official docker.io index.