Documentation
¶
Index ¶
- Variables
- func NewRegistryProperties(ref string, regConf *RegistriesConfig) (*properties.Registry, error)
- func ToHostname(addr string) string
- type AuthConfig
- type CertsDir
- type Config
- func (cfg *Config) CredentialHelpers() map[string]string
- func (cfg *Config) CredentialsStore() string
- func (cfg *Config) DeleteAuthConfig(serverAddress string) error
- func (cfg *Config) GetAuthConfig(serverAddress string) (AuthConfig, error)
- func (cfg *Config) GetAuthConfigHierarchical(serverAddress string) (AuthConfig, error)
- func (cfg *Config) GetCredentialHelper(serverAddress string) string
- func (cfg *Config) IsAuthConfigured() bool
- func (cfg *Config) Path() string
- func (cfg *Config) PutAuthConfig(serverAddress string, authCfg AuthConfig) error
- func (cfg *Config) RemoveAuthConfig(serverAddress string)
- func (cfg *Config) Save() error
- func (cfg *Config) SetAuthConfig(serverAddress string, authCfg AuthConfig) error
- func (cfg *Config) SetCredentialHelper(serverAddress, helper string)
- func (cfg *Config) SetCredentialsStore(credsStore string)
- func (cfg *Config) SetPath(path string)
- type Configs
- type LoadConfigsOptions
- type Mirror
- type RegistriesConfig
- func (rc *RegistriesConfig) FindRegistry(ref string) *Registry
- func (rc *RegistriesConfig) GetMirrors(ref string) []Mirror
- func (rc *RegistriesConfig) IsBlocked(ref string) bool
- func (rc *RegistriesConfig) RegistryProperties(ref string) (*properties.Registry, error)
- func (rc *RegistriesConfig) ResolveAlias(shortName string) (string, bool)
- func (rc *RegistriesConfig) RewriteReference(ref string) string
- func (rc *RegistriesConfig) SearchRegistryProperties(imageName string) ([]*properties.Registry, error)
- type RegistriesDConfig
- type RegistriesDDockerConfig
- type Registry
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var EncodeAuth = authtype.EncodeAuth
EncodeAuth base64-encodes username and password into base64(username:password).
var ErrInvalidAuthConfig = authtype.ErrInvalidAuthConfig
ErrInvalidAuthConfig is returned when the auth config format is invalid.
var ErrInvalidConfigFormat = errors.New("invalid config format")
ErrInvalidConfigFormat is returned when the config format is invalid.
var ErrNoConfigPath = errors.New("no config path configured")
ErrNoConfigPath is returned when Save is called on a Config with no path.
var ErrRegistriesConfigNotFound = fmt.Errorf("registries.conf not found")
ErrRegistriesConfigNotFound is returned when no registries.conf file is found.
var ErrRegistryBlocked = errors.New("registry is blocked")
ErrRegistryBlocked is returned when a registry is blocked by the registries configuration.
var NewAuthConfig = authtype.NewAuthConfig
NewAuthConfig creates an AuthConfig based on credential components.
Functions ¶
func NewRegistryProperties ¶
func NewRegistryProperties(ref string, regConf *RegistriesConfig) (*properties.Registry, error)
NewRegistryProperties creates a properties.Registry from a reference string with optional RegistriesConfig for transport settings. If regConf is nil, only reference parsing is performed.
Example ¶
package main
import (
"fmt"
"github.com/oras-project/oras-go/v3/registry/remote/config"
)
func main() {
// Create properties without a registries config (programmatic flow).
props, err := config.NewRegistryProperties("ghcr.io/user/repo:v1", nil)
if err != nil {
panic(err)
}
fmt.Println("Registry:", props.Reference.Registry)
fmt.Println("Repository:", props.Reference.Repository)
fmt.Println("Tag:", props.Reference.Tag)
}
Output: Registry: ghcr.io Repository: user/repo Tag: v1
func ToHostname ¶
ToHostname normalizes a server address to just its hostname, removing the scheme and the path parts. It is used to match keys in the auths map, which may be either stored as hostname or as hostname including scheme (in legacy docker config files). Reference: https://github.com/docker/cli/blob/v24.0.6/cli/config/credentials/file_store.go#L71
Types ¶
type AuthConfig ¶
type AuthConfig = authtype.AuthConfig
AuthConfig contains authorization information for connecting to a Registry. References:
type CertsDir ¶
type CertsDir struct {
// CACertPaths contains paths to .crt files (CA certificates).
CACertPaths []string
// ClientCert is the path to a .cert file (client certificate).
ClientCert string
// ClientKey is the path to the matching .key file (client key).
ClientKey string
}
CertsDir holds TLS certificate paths discovered from a containers-certs.d directory for a specific registry host.
func LoadCertsDir ¶
LoadCertsDir discovers TLS certificate files for the given registry host from the default containers-certs.d directories:
- /etc/containers/certs.d/<host>/
- $HOME/.config/containers/certs.d/<host>/
Files from later directories are appended (not overridden). Returns nil if no certificate files are found.
func LoadCertsDirFromPaths ¶
LoadCertsDirFromPaths discovers TLS certificate files for the given registry host from the specified base directories. Returns nil if no certificate files are found.
Example ¶
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/oras-project/oras-go/v3/registry/remote/config"
)
func main() {
// Set up a temporary containers-certs.d directory structure.
tmpDir, err := os.MkdirTemp("", "certsd-example")
if err != nil {
panic(err)
}
defer os.RemoveAll(tmpDir)
// Create a per-host directory with certificate files.
hostDir := filepath.Join(tmpDir, "myregistry.example.com")
if err := os.MkdirAll(hostDir, 0755); err != nil {
panic(err)
}
if err := os.WriteFile(filepath.Join(hostDir, "ca.crt"), []byte("ca-data"), 0644); err != nil {
panic(err)
}
if err := os.WriteFile(filepath.Join(hostDir, "client.cert"), []byte("cert-data"), 0644); err != nil {
panic(err)
}
if err := os.WriteFile(filepath.Join(hostDir, "client.key"), []byte("key-data"), 0600); err != nil {
panic(err)
}
// Discover certificate files for the registry host.
cd, err := config.LoadCertsDirFromPaths("myregistry.example.com", []string{tmpDir})
if err != nil {
panic(err)
}
fmt.Printf("CA certs: %d\n", len(cd.CACertPaths))
fmt.Printf("Client cert found: %v\n", cd.ClientCert != "")
fmt.Printf("Client key found: %v\n", cd.ClientKey != "")
}
Output: CA certs: 1 Client cert found: true Client key found: true
func (*CertsDir) ApplyToTransport ¶
func (cd *CertsDir) ApplyToTransport(t *properties.Transport)
ApplyToTransport populates the Transport CACerts, Cert, and Key fields from the discovered certificate paths. Existing values are not overwritten.
type Config ¶
type Config struct {
// contains filtered or unexported fields
}
Config represents a docker configuration file. References:
- https://docs.docker.com/engine/reference/commandline/cli/#docker-cli-configuration-file-configjson-properties
- https://github.com/docker/cli/blob/v24.0.0-beta.2/cli/config/configfile/file.go#L17-L44
func NewConfig ¶
func NewConfig() *Config
NewConfig creates an in-memory Config with no file backing. Use this when you want to configure credentials programmatically without reading from or writing to a file.
func NewConfigWithPath ¶
NewConfigWithPath creates an in-memory Config with a file path configured. The file is not read; use Load() to read from an existing file. The path is used when Save() is called.
func (*Config) CredentialHelpers ¶
CredentialHelpers returns a copy of all configured credential helpers.
func (*Config) CredentialsStore ¶
CredentialsStore returns the configured credentials store.
func (*Config) DeleteAuthConfig ¶
DeleteAuthConfig deletes the corresponding credential for serverAddress and saves to file.
func (*Config) GetAuthConfig ¶
func (cfg *Config) GetAuthConfig(serverAddress string) (AuthConfig, error)
GetAuthConfig returns an AuthConfig for serverAddress.
func (*Config) GetAuthConfigHierarchical ¶
func (cfg *Config) GetAuthConfigHierarchical(serverAddress string) (AuthConfig, error)
GetAuthConfigHierarchical returns an AuthConfig using longest-prefix matching against auths keys. This is used for containers-auth.json (Podman/Buildah) which supports hierarchical namespace matching.
For example, given auths keys:
- "registry.example.com/namespace/repo"
- "registry.example.com/namespace"
- "registry.example.com"
A lookup for "registry.example.com/namespace/repo" would match the first, while "registry.example.com/namespace/other" would match the second.
func (*Config) GetCredentialHelper ¶
GetCredentialHelper returns the credential helper for serverAddress.
func (*Config) IsAuthConfigured ¶
IsAuthConfigured returns whether there is authentication configured in this config file or not.
func (*Config) PutAuthConfig ¶
func (cfg *Config) PutAuthConfig(serverAddress string, authCfg AuthConfig) error
PutAuthConfig puts authCfg for serverAddress and saves to file if a path is configured.
func (*Config) RemoveAuthConfig ¶
RemoveAuthConfig removes the credential for serverAddress from memory without saving. Use Save() to persist changes, or DeleteAuthConfig() to remove and save atomically.
func (*Config) Save ¶
Save saves the config to the configured file path. Returns ErrNoConfigPath if no path is configured.
func (*Config) SetAuthConfig ¶
func (cfg *Config) SetAuthConfig(serverAddress string, authCfg AuthConfig) error
SetAuthConfig sets authCfg for serverAddress in memory without saving to file. Use Save() to persist changes, or PutAuthConfig() to set and save atomically.
func (*Config) SetCredentialHelper ¶
SetCredentialHelper sets the credential helper for serverAddress in memory.
func (*Config) SetCredentialsStore ¶
SetCredentialsStore sets the credentials store in memory without saving.
type Configs ¶
type Configs struct {
// DockerConfig is the loaded Docker config.json, or nil if not found.
DockerConfig *Config
// ContainersAuthConfig is the loaded containers auth.json
// (Podman/Buildah format), or nil if not found.
// The auth.json format is identical to Docker config.json but uses
// hierarchical namespace matching via GetAuthConfigHierarchical().
ContainersAuthConfig *Config
// RegistriesConfig is the loaded registries.conf, or nil if not found.
RegistriesConfig *RegistriesConfig
// PolicyConfig is the loaded containers-policy.json, or nil if not found.
PolicyConfig *policy.Policy
// RegistriesDConfig is the loaded registries.d signature storage config,
// or nil if no configuration was found.
RegistriesDConfig *RegistriesDConfig
// CertsDirPaths is the resolved list of base directories for
// containers-certs.d certificate discovery.
CertsDirPaths []string
}
Configs holds loaded configuration from Docker config.json and system registries.conf. Fields are nil if the corresponding file was not found.
func LoadConfigs ¶
LoadConfigs loads Docker config.json and system registries.conf from their default locations. Missing files are silently skipped. Returns an error only if a file exists but cannot be parsed.
func LoadConfigsWithOptions ¶
func LoadConfigsWithOptions(opts LoadConfigsOptions) (*Configs, error)
LoadConfigsWithOptions loads configs from specified or default paths. Missing files are silently skipped. Returns an error only if a file exists but cannot be parsed.
func (*Configs) CredentialStore ¶
func (c *Configs) CredentialStore(opts credentials.StoreOptions) (credentials.Store, error)
CredentialStore creates a credentials.Store combining Docker config and containers auth.json credentials. The Docker config store is used as the primary store, with the containers auth store as a fallback.
Returns an error if neither DockerConfig nor ContainersAuthConfig is loaded.
func (*Configs) PolicyEvaluator ¶
PolicyEvaluator creates a policy.Evaluator from the loaded policy config. Returns (nil, nil) if no policy configuration was loaded.
func (*Configs) RegistryProperties ¶
func (c *Configs) RegistryProperties(ref string) (*properties.Registry, error)
RegistryProperties creates a properties.Registry for the given reference string by combining settings from RegistriesConfig and CertsDir.
It performs the following steps:
- Creates base properties from RegistriesConfig (or plain reference parsing if RegistriesConfig is nil).
- Loads and applies TLS certificates from CertsDirPaths for the resolved registry host.
type LoadConfigsOptions ¶
type LoadConfigsOptions struct {
// DockerConfigPath overrides the Docker config.json path.
// When empty, the default path is used ($DOCKER_CONFIG/config.json
// or $HOME/.docker/config.json).
DockerConfigPath string
// ContainersAuthPath overrides the containers auth.json path.
// When empty, the default paths are searched:
// $XDG_RUNTIME_DIR/containers/auth.json, then
// $HOME/.config/containers/auth.json.
ContainersAuthPath string
// RegistriesConfigPath overrides the registries.conf path.
// When empty, the system default locations are searched.
RegistriesConfigPath string
// PolicyConfigPath overrides the containers-policy.json path.
// When empty, the default locations are searched
// ($HOME/.config/containers/policy.json, then /etc/containers/policy.json).
PolicyConfigPath string
// RegistriesDPath overrides the registries.d directory path.
// When empty, the system default locations are searched
// (/etc/containers/registries.d and $HOME/.config/containers/registries.d).
RegistriesDPath string
// CertsDirPaths overrides the containers-certs.d base directories.
// When empty, the default paths are used (/etc/containers/certs.d
// and $HOME/.config/containers/certs.d).
CertsDirPaths []string
}
LoadConfigsOptions configures LoadConfigs behavior.
type Mirror ¶
type Mirror struct {
// Location is the mirror's address.
Location string `toml:"location"`
// Insecure allows HTTP or unverified HTTPS for this mirror.
Insecure bool `toml:"insecure"`
// PullFromMirror controls when to use this mirror: "all", "digest-only", or "tag-only".
PullFromMirror string `toml:"pull-from-mirror"`
}
Mirror represents a registry mirror configuration.
type RegistriesConfig ¶
type RegistriesConfig struct {
// UnqualifiedSearchRegistries is the list of registries to try when pulling unqualified images.
UnqualifiedSearchRegistries []string `toml:"unqualified-search-registries"`
// ShortNameMode controls short-name lookup behavior: "enforcing", "permissive", or "disabled".
ShortNameMode string `toml:"short-name-mode"`
// Registries is a list of registry configurations.
Registries []Registry `toml:"registry"`
// Aliases maps short names to fully qualified references.
Aliases map[string]string `toml:"aliases"`
}
RegistriesConfig represents a registries.conf configuration file. Reference: https://github.com/containers/image/blob/main/docs/containers-registries.conf.5.md
func LoadRegistriesConfig ¶
func LoadRegistriesConfig(path string) (*RegistriesConfig, error)
LoadRegistriesConfig loads a registries.conf file from the given path.
func LoadSystemRegistriesConfig ¶
func LoadSystemRegistriesConfig() (*RegistriesConfig, error)
LoadSystemRegistriesConfig loads registries.conf from system default locations. Load order (each layer overrides the previous):
- /etc/containers/registries.conf
- /etc/containers/registries.conf.d/*.conf (alpha-numerical order)
- $HOME/.config/containers/registries.conf
- $HOME/.config/containers/registries.conf.d/*.conf (alpha-numerical order)
func (*RegistriesConfig) FindRegistry ¶
func (rc *RegistriesConfig) FindRegistry(ref string) *Registry
FindRegistry finds the best matching registry configuration for the given image reference. It matches by longest prefix first and supports wildcard prefixes like "*.example.com".
func (*RegistriesConfig) GetMirrors ¶
func (rc *RegistriesConfig) GetMirrors(ref string) []Mirror
GetMirrors returns the mirrors for the given reference, in order of preference.
func (*RegistriesConfig) IsBlocked ¶
func (rc *RegistriesConfig) IsBlocked(ref string) bool
IsBlocked returns true if the given reference is blocked.
func (*RegistriesConfig) RegistryProperties ¶
func (rc *RegistriesConfig) RegistryProperties(ref string) (*properties.Registry, error)
RegistryProperties creates a properties.Registry for the given reference string using transport settings from the registries configuration.
It performs the following steps:
- Resolves aliases (short names to fully qualified references).
- Checks if the registry is blocked (returns ErrRegistryBlocked).
- Rewrites the reference using Location rules.
- Applies transport settings (Insecure) from the matching registry entry.
Example ¶
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/oras-project/oras-go/v3/registry/remote/config"
)
func main() {
// Create a sample registries.conf file.
tmpDir, err := os.MkdirTemp("", "registries-example")
if err != nil {
panic(err)
}
defer os.RemoveAll(tmpDir)
confContent := `
[[registry]]
prefix = "docker.io"
location = "registry-1.docker.io"
[[registry]]
prefix = "insecure.example.com"
insecure = true
`
confPath := filepath.Join(tmpDir, "registries.conf")
if err := os.WriteFile(confPath, []byte(confContent), 0644); err != nil {
panic(err)
}
// Load registries configuration.
regConf, err := config.LoadRegistriesConfig(confPath)
if err != nil {
panic(err)
}
// Convert config to properties for a docker.io reference.
props, err := regConf.RegistryProperties("docker.io/library/alpine:latest")
if err != nil {
panic(err)
}
fmt.Println("Registry:", props.Reference.Registry)
fmt.Println("Repository:", props.Reference.Repository)
fmt.Println("Tag:", props.Reference.Tag)
fmt.Println("Insecure:", props.Transport.Insecure)
}
Output: Registry: registry-1.docker.io Repository: library/alpine Tag: latest Insecure: false
Example (Mirrors) ¶
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/oras-project/oras-go/v3/registry/remote/config"
)
func main() {
// Create a sample registries.conf file with mirrors.
tmpDir, err := os.MkdirTemp("", "registries-mirror-example")
if err != nil {
panic(err)
}
defer os.RemoveAll(tmpDir)
confContent := `
[[registry]]
prefix = "docker.io"
location = "registry-1.docker.io"
[[registry.mirror]]
location = "mirror1.example.com"
insecure = true
[[registry.mirror]]
location = "mirror2.example.com"
pull-from-mirror = "digest-only"
`
confPath := filepath.Join(tmpDir, "registries.conf")
if err := os.WriteFile(confPath, []byte(confContent), 0644); err != nil {
panic(err)
}
// Load registries configuration.
regConf, err := config.LoadRegistriesConfig(confPath)
if err != nil {
panic(err)
}
// Convert config to properties for a docker.io reference.
props, err := regConf.RegistryProperties("docker.io/library/alpine:latest")
if err != nil {
panic(err)
}
fmt.Println("Registry:", props.Reference.Registry)
fmt.Printf("Mirrors: %d\n", len(props.Mirrors))
for i, m := range props.Mirrors {
fmt.Printf(" Mirror %d: %s (insecure=%v, pull-from-mirror=%s)\n",
i, m.Location, m.Transport.Insecure, m.PullFromMirror)
}
}
Output: Registry: registry-1.docker.io Mirrors: 2 Mirror 0: mirror1.example.com (insecure=true, pull-from-mirror=) Mirror 1: mirror2.example.com (insecure=false, pull-from-mirror=digest-only)
func (*RegistriesConfig) ResolveAlias ¶
func (rc *RegistriesConfig) ResolveAlias(shortName string) (string, bool)
ResolveAlias resolves a short name to a fully qualified reference.
func (*RegistriesConfig) RewriteReference ¶
func (rc *RegistriesConfig) RewriteReference(ref string) string
RewriteReference rewrites a reference to its actual location. If the registry has a Location specified, the prefix is replaced with it.
func (*RegistriesConfig) SearchRegistryProperties ¶
func (rc *RegistriesConfig) SearchRegistryProperties(imageName string) ([]*properties.Registry, error)
SearchRegistryProperties returns properties for each unqualified search registry combined with the given image name. This supports the UnqualifiedSearchRegistries feature from registries.conf.
For example, if UnqualifiedSearchRegistries contains ["docker.io", "quay.io"] and imageName is "library/alpine:latest", this returns properties for "docker.io/library/alpine:latest" and "quay.io/library/alpine:latest".
Example ¶
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/oras-project/oras-go/v3/registry/remote/config"
)
func main() {
// Create a sample registries.conf file.
tmpDir, err := os.MkdirTemp("", "registries-search-example")
if err != nil {
panic(err)
}
defer os.RemoveAll(tmpDir)
confContent := `
unqualified-search-registries = ["docker.io", "quay.io"]
[[registry]]
prefix = "docker.io"
location = "registry-1.docker.io"
`
confPath := filepath.Join(tmpDir, "registries.conf")
if err := os.WriteFile(confPath, []byte(confContent), 0644); err != nil {
panic(err)
}
// Load registries configuration.
regConf, err := config.LoadRegistriesConfig(confPath)
if err != nil {
panic(err)
}
// Search for an unqualified image name across configured search registries.
results, err := regConf.SearchRegistryProperties("library/alpine:latest")
if err != nil {
panic(err)
}
for _, props := range results {
fmt.Printf("%s/%s:%s\n", props.Reference.Registry, props.Reference.Repository, props.Reference.Tag)
}
}
Output: registry-1.docker.io/library/alpine:latest quay.io/library/alpine:latest
type RegistriesDConfig ¶
type RegistriesDConfig struct {
// DefaultDocker is the default configuration for all docker transport images.
DefaultDocker *RegistriesDDockerConfig `yaml:"default-docker"`
// Docker is a map of registry-specific configurations, keyed by namespace.
Docker map[string]RegistriesDDockerConfig `yaml:"docker"`
}
RegistriesDConfig represents a registries.d YAML configuration file. These files specify where signatures are stored for each registry. Reference: https://github.com/containers/image/blob/main/docs/containers-registries.d.5.md
func LoadRegistriesDConfig ¶
func LoadRegistriesDConfig(path string) (*RegistriesDConfig, error)
LoadRegistriesDConfig loads a single registries.d YAML configuration file.
func LoadSystemRegistriesDConfig ¶
func LoadSystemRegistriesDConfig() (*RegistriesDConfig, error)
LoadSystemRegistriesDConfig loads and merges registries.d configuration from system and user default locations. Load order (each layer overrides the previous):
- /etc/containers/registries.d/*.yaml (alpha-numerical order)
- $HOME/.config/containers/registries.d/*.yaml (alpha-numerical order)
func (*RegistriesDConfig) GetLookasideURLs ¶
func (c *RegistriesDConfig) GetLookasideURLs(scope string) (readURL, writeURL string)
GetLookasideURLs returns the effective read and write lookaside URLs for the given image scope. It uses longest-prefix matching against the Docker namespace keys, falling back to the default-docker configuration.
Returns empty strings if no configuration matches.
type RegistriesDDockerConfig ¶
type RegistriesDDockerConfig struct {
// Lookaside is the URL of the lookaside storage for reading signatures.
Lookaside string `yaml:"lookaside"`
// LookasideStaging is the URL of the lookaside storage for writing signatures.
// If empty, Lookaside is used for both reading and writing.
LookasideStaging string `yaml:"lookaside-staging"`
// UseSigstoreAttachments indicates whether signatures should be stored
// as OCI image attachments (sigstore format) instead of using lookaside storage.
UseSigstoreAttachments bool `yaml:"use-sigstore-attachments"`
// Legacy field names (sigstore was renamed to lookaside).
// These are supported for backward compatibility.
SigStore string `yaml:"sigstore"`
SigStoreStaging string `yaml:"sigstore-staging"`
}
RegistriesDDockerConfig represents the docker-specific signature storage configuration for a registry namespace.
type Registry ¶
type Registry struct {
// Prefix identifies which images match this configuration (e.g., "docker.io", "*.example.com").
Prefix string `toml:"prefix"`
// Location is the actual registry location (defaults to Prefix if empty).
Location string `toml:"location"`
// Insecure allows HTTP or unverified HTTPS.
Insecure bool `toml:"insecure"`
// Blocked prevents pulling from this registry.
Blocked bool `toml:"blocked"`
// Mirrors is a list of mirror configurations.
Mirrors []Mirror `toml:"mirror"`
// MirrorByDigestOnly restricts mirrors to digest-based pulls only.
MirrorByDigestOnly bool `toml:"mirror-by-digest-only"`
// ForceBasicAuth forces HTTP Basic authentication regardless of what the
// registry advertises. When true, if the registry challenges with Bearer
// auth the client will use Basic auth instead. Requires the registry to
// also accept Basic auth credentials. This is an ORAS-specific field and
// may be ignored by other tools that parse registries.conf.
ForceBasicAuth bool `toml:"force-basic-auth"`
// ReferrersAPI indicates whether the registry supports the OCI Referrers
// API. Valid values: "supported", "unsupported". An empty or unrecognized
// value defaults to auto-detection on first use. This is an ORAS-specific
// field and may be ignored by other tools that parse registries.conf.
ReferrersAPI string `toml:"referrers-api"`
}
Registry represents configuration for a specific registry namespace.
func (*Registry) GetLocation ¶
GetLocation returns the effective location for a registry. If Location is empty, returns the Prefix.