github.com/rkt/rkt@v1.30.1-0.20200224141603-171c416fac02/pkg/distribution/distribution.go (about)

     1  // Copyright 2016 The rkt Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package distribution
    16  
    17  import (
    18  	"fmt"
    19  	"net/url"
    20  )
    21  
    22  // Type represents the Distribution type
    23  type Type string
    24  
    25  const (
    26  	// Scheme represents the Distribution URI scheme
    27  	Scheme = "cimd"
    28  )
    29  
    30  // Distribution is the interface that represents a distribution point.
    31  type Distribution interface {
    32  	// URI returns a copy of the Distribution CIMD URI.
    33  	CIMD() *url.URL
    34  	// String returns a user friendly representation of the distribution point.
    35  	String() string
    36  	// Equals returns true if this distribution equals the given distribution, else false.
    37  	Equals(Distribution) bool
    38  }
    39  
    40  type newDistribution func(*url.URL) (Distribution, error)
    41  
    42  var distributions = make(map[Type]newDistribution)
    43  
    44  // Register registers a function that returns a new instance of the given
    45  // distribution. This is intended to be called from the init function in
    46  // packages that implement distribution functions.
    47  func Register(distType Type, f newDistribution) {
    48  	if _, ok := distributions[distType]; ok {
    49  		panic(fmt.Errorf("distribution %q already registered", distType))
    50  	}
    51  	distributions[distType] = f
    52  }
    53  
    54  // Get returns a Distribution from the input URI.
    55  // It returns an error if the uri string is wrong or referencing an unknown
    56  // distribution type.
    57  func Get(u *url.URL) (Distribution, error) {
    58  	c, err := parseCIMD(u)
    59  	if err != nil {
    60  		return nil, fmt.Errorf("malformed distribution uri %q: %v", u.String(), err)
    61  	}
    62  	if u.Scheme != Scheme {
    63  		return nil, fmt.Errorf("malformed distribution uri %q", u.String())
    64  	}
    65  	if _, ok := distributions[c.Type]; !ok {
    66  		return nil, fmt.Errorf("unknown distribution type: %q", c.Type)
    67  	}
    68  	return distributions[c.Type](u)
    69  }
    70  
    71  // Parse parses the provided distribution URI string and returns a
    72  // Distribution.
    73  func Parse(rawuri string) (Distribution, error) {
    74  	u, err := url.Parse(rawuri)
    75  	if err != nil {
    76  		return nil, fmt.Errorf("cannot parse uri: %q: %v", rawuri, err)
    77  	}
    78  	return Get(u)
    79  }