keel/util/image/parse.go

132 lines
2.6 KiB
Go

package image
import (
"strings"
)
// Reference is an opaque object that include identifier such as a name, tag, repository, registry, etc...
type Reference struct {
named Named
tag string
scheme string // registry scheme, i.e. http, https
}
func (r Reference) String() string {
return r.Name()
}
// Name returns the image's name. (ie: debian[:8.2])
func (r Reference) Name() string {
return r.named.RemoteName() + r.tag
}
// ShortName returns the image's name (ie: debian)
func (r Reference) ShortName() string {
return r.named.RemoteName()
}
// Tag returns the image's tag (or digest).
func (r Reference) Tag() string {
if len(r.tag) > 1 {
return r.tag[1:]
}
return ""
}
// Registry returns the image's registry. (ie: host[:port])
func (r Reference) Registry() string {
return r.named.Hostname()
}
// Scheme returns registry's scheme. (ie: https)
func (r Reference) Scheme() string {
return r.scheme
}
// Repository returns the image's repository. (ie: registry/name)
func (r Reference) Repository() string {
return r.named.FullName()
}
// Remote returns the image's remote identifier. (ie: registry/name[:tag])
func (r Reference) Remote() string {
return r.named.FullName() + r.tag
}
func clean(url string) (cleaned string, scheme string) {
s := url
if strings.HasPrefix(url, "http://") {
scheme = "http"
s = strings.Replace(url, "http://", "", 1)
} else if strings.HasPrefix(url, "https://") {
scheme = "https"
s = strings.Replace(url, "https://", "", 1)
}
if scheme == "" {
scheme = DefaultScheme
}
return s, scheme
}
// Parse returns a Reference from analyzing the given remote identifier.
func Parse(remote string) (*Reference, error) {
cleaned, scheme := clean(remote)
n, err := ParseNamed(cleaned)
if err != nil {
return nil, err
}
n = WithDefaultTag(n)
var t string
switch x := n.(type) {
case Canonical:
t = "@" + x.Digest().String()
case NamedTagged:
t = ":" + x.Tag()
}
return &Reference{named: n, tag: t, scheme: scheme}, nil
}
// ParseRepo - parses remote
// pretty much the same as Parse but better for testing
func ParseRepo(remote string) (*Repository, error) {
cleaned, scheme := clean(remote)
n, err := ParseNamed(cleaned)
if err != nil {
return nil, err
}
n = WithDefaultTag(n)
var t string
switch x := n.(type) {
case Canonical:
t = "@" + x.Digest().String()
case NamedTagged:
t = ":" + x.Tag()
}
ref := &Reference{named: n, tag: t, scheme: scheme}
return &Repository{
Name: ref.Name(),
Repository: ref.Repository(),
Registry: ref.Registry(),
Remote: ref.Remote(),
ShortName: ref.ShortName(),
Tag: ref.Tag(),
Scheme: ref.scheme,
}, nil
}