forked from TrueCloudLab/distribution
127 lines
3.7 KiB
Go
127 lines
3.7 KiB
Go
|
package registry
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
"net"
|
||
|
"net/url"
|
||
|
|
||
|
"github.com/docker/docker/opts"
|
||
|
flag "github.com/docker/docker/pkg/mflag"
|
||
|
)
|
||
|
|
||
|
// Options holds command line options.
|
||
|
type Options struct {
|
||
|
Mirrors opts.ListOpts
|
||
|
InsecureRegistries opts.ListOpts
|
||
|
}
|
||
|
|
||
|
// InstallFlags adds command-line options to the top-level flag parser for
|
||
|
// the current process.
|
||
|
func (options *Options) InstallFlags() {
|
||
|
options.Mirrors = opts.NewListOpts(ValidateMirror)
|
||
|
flag.Var(&options.Mirrors, []string{"-registry-mirror"}, "Specify a preferred Docker registry mirror")
|
||
|
options.InsecureRegistries = opts.NewListOpts(ValidateIndexName)
|
||
|
flag.Var(&options.InsecureRegistries, []string{"-insecure-registry"}, "Enable insecure communication with specified registries (no certificate verification for HTTPS and enable HTTP fallback) (e.g., localhost:5000 or 10.20.0.0/16)")
|
||
|
}
|
||
|
|
||
|
// ValidateMirror validates an HTTP(S) registry mirror
|
||
|
func ValidateMirror(val string) (string, error) {
|
||
|
uri, err := url.Parse(val)
|
||
|
if err != nil {
|
||
|
return "", fmt.Errorf("%s is not a valid URI", val)
|
||
|
}
|
||
|
|
||
|
if uri.Scheme != "http" && uri.Scheme != "https" {
|
||
|
return "", fmt.Errorf("Unsupported scheme %s", uri.Scheme)
|
||
|
}
|
||
|
|
||
|
if uri.Path != "" || uri.RawQuery != "" || uri.Fragment != "" {
|
||
|
return "", fmt.Errorf("Unsupported path/query/fragment at end of the URI")
|
||
|
}
|
||
|
|
||
|
return fmt.Sprintf("%s://%s/v1/", uri.Scheme, uri.Host), nil
|
||
|
}
|
||
|
|
||
|
// ValidateIndexName validates an index name.
|
||
|
func ValidateIndexName(val string) (string, error) {
|
||
|
// 'index.docker.io' => 'docker.io'
|
||
|
if val == "index."+IndexServerName() {
|
||
|
val = IndexServerName()
|
||
|
}
|
||
|
// *TODO: Check if valid hostname[:port]/ip[:port]?
|
||
|
return val, nil
|
||
|
}
|
||
|
|
||
|
type netIPNet net.IPNet
|
||
|
|
||
|
func (ipnet *netIPNet) MarshalJSON() ([]byte, error) {
|
||
|
return json.Marshal((*net.IPNet)(ipnet).String())
|
||
|
}
|
||
|
|
||
|
func (ipnet *netIPNet) UnmarshalJSON(b []byte) (err error) {
|
||
|
var ipnet_str string
|
||
|
if err = json.Unmarshal(b, &ipnet_str); err == nil {
|
||
|
var cidr *net.IPNet
|
||
|
if _, cidr, err = net.ParseCIDR(ipnet_str); err == nil {
|
||
|
*ipnet = netIPNet(*cidr)
|
||
|
}
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// ServiceConfig stores daemon registry services configuration.
|
||
|
type ServiceConfig struct {
|
||
|
InsecureRegistryCIDRs []*netIPNet `json:"InsecureRegistryCIDRs"`
|
||
|
IndexConfigs map[string]*IndexInfo `json:"IndexConfigs"`
|
||
|
}
|
||
|
|
||
|
// NewServiceConfig returns a new instance of ServiceConfig
|
||
|
func NewServiceConfig(options *Options) *ServiceConfig {
|
||
|
if options == nil {
|
||
|
options = &Options{
|
||
|
Mirrors: opts.NewListOpts(nil),
|
||
|
InsecureRegistries: opts.NewListOpts(nil),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Localhost is by default considered as an insecure registry
|
||
|
// This is a stop-gap for people who are running a private registry on localhost (especially on Boot2docker).
|
||
|
//
|
||
|
// TODO: should we deprecate this once it is easier for people to set up a TLS registry or change
|
||
|
// daemon flags on boot2docker?
|
||
|
options.InsecureRegistries.Set("127.0.0.0/8")
|
||
|
|
||
|
config := &ServiceConfig{
|
||
|
InsecureRegistryCIDRs: make([]*netIPNet, 0),
|
||
|
IndexConfigs: make(map[string]*IndexInfo, 0),
|
||
|
}
|
||
|
// Split --insecure-registry into CIDR and registry-specific settings.
|
||
|
for _, r := range options.InsecureRegistries.GetAll() {
|
||
|
// Check if CIDR was passed to --insecure-registry
|
||
|
_, ipnet, err := net.ParseCIDR(r)
|
||
|
if err == nil {
|
||
|
// Valid CIDR.
|
||
|
config.InsecureRegistryCIDRs = append(config.InsecureRegistryCIDRs, (*netIPNet)(ipnet))
|
||
|
} else {
|
||
|
// Assume `host:port` if not CIDR.
|
||
|
config.IndexConfigs[r] = &IndexInfo{
|
||
|
Name: r,
|
||
|
Mirrors: make([]string, 0),
|
||
|
Secure: false,
|
||
|
Official: false,
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Configure public registry.
|
||
|
config.IndexConfigs[IndexServerName()] = &IndexInfo{
|
||
|
Name: IndexServerName(),
|
||
|
Mirrors: options.Mirrors.GetAll(),
|
||
|
Secure: true,
|
||
|
Official: true,
|
||
|
}
|
||
|
|
||
|
return config
|
||
|
}
|