| ... | ... |
@@ -92,7 +92,7 @@ func httpError(w http.ResponseWriter, err error) {
|
| 92 | 92 |
// FIXME: this is brittle and should not be necessary. |
| 93 | 93 |
// If we need to differentiate between different possible error types, we should |
| 94 | 94 |
// create appropriate error types with clearly defined meaning. |
| 95 |
- if strings.Contains(err.Error(), "No such") {
|
|
| 95 |
+ if strings.Contains(err.Error(), "no such") {
|
|
| 96 | 96 |
statusCode = http.StatusNotFound |
| 97 | 97 |
} else if strings.Contains(err.Error(), "Bad parameter") {
|
| 98 | 98 |
statusCode = http.StatusBadRequest |
| ... | ... |
@@ -131,8 +131,8 @@ func (db *Database) Set(fullPath, id string) (*Entity, error) {
|
| 131 | 131 |
if _, err := db.conn.Exec("BEGIN EXCLUSIVE"); err != nil {
|
| 132 | 132 |
return nil, err |
| 133 | 133 |
} |
| 134 |
- var entityId string |
|
| 135 |
- if err := db.conn.QueryRow("SELECT id FROM entity WHERE id = ?;", id).Scan(&entityId); err != nil {
|
|
| 134 |
+ var entityID string |
|
| 135 |
+ if err := db.conn.QueryRow("SELECT id FROM entity WHERE id = ?;", id).Scan(&entityID); err != nil {
|
|
| 136 | 136 |
if err == sql.ErrNoRows {
|
| 137 | 137 |
if _, err := db.conn.Exec("INSERT INTO entity (id) VALUES(?);", id); err != nil {
|
| 138 | 138 |
rollback() |
| ... | ... |
@@ -320,14 +320,14 @@ func (db *Database) RefPaths(id string) Edges {
|
| 320 | 320 |
|
| 321 | 321 |
for rows.Next() {
|
| 322 | 322 |
var name string |
| 323 |
- var parentId string |
|
| 324 |
- if err := rows.Scan(&name, &parentId); err != nil {
|
|
| 323 |
+ var parentID string |
|
| 324 |
+ if err := rows.Scan(&name, &parentID); err != nil {
|
|
| 325 | 325 |
return refs |
| 326 | 326 |
} |
| 327 | 327 |
refs = append(refs, &Edge{
|
| 328 | 328 |
EntityID: id, |
| 329 | 329 |
Name: name, |
| 330 |
- ParentID: parentId, |
|
| 330 |
+ ParentID: parentID, |
|
| 331 | 331 |
}) |
| 332 | 332 |
} |
| 333 | 333 |
return refs |
| ... | ... |
@@ -443,11 +443,11 @@ func (db *Database) children(e *Entity, name string, depth int, entities []WalkM |
| 443 | 443 |
defer rows.Close() |
| 444 | 444 |
|
| 445 | 445 |
for rows.Next() {
|
| 446 |
- var entityId, entityName string |
|
| 447 |
- if err := rows.Scan(&entityId, &entityName); err != nil {
|
|
| 446 |
+ var entityID, entityName string |
|
| 447 |
+ if err := rows.Scan(&entityID, &entityName); err != nil {
|
|
| 448 | 448 |
return nil, err |
| 449 | 449 |
} |
| 450 |
- child := &Entity{entityId}
|
|
| 450 |
+ child := &Entity{entityID}
|
|
| 451 | 451 |
edge := &Edge{
|
| 452 | 452 |
ParentID: e.id, |
| 453 | 453 |
Name: entityName, |
| ... | ... |
@@ -490,11 +490,11 @@ func (db *Database) parents(e *Entity) (parents []string, err error) {
|
| 490 | 490 |
defer rows.Close() |
| 491 | 491 |
|
| 492 | 492 |
for rows.Next() {
|
| 493 |
- var parentId string |
|
| 494 |
- if err := rows.Scan(&parentId); err != nil {
|
|
| 493 |
+ var parentID string |
|
| 494 |
+ if err := rows.Scan(&parentID); err != nil {
|
|
| 495 | 495 |
return nil, err |
| 496 | 496 |
} |
| 497 |
- parents = append(parents, parentId) |
|
| 497 |
+ parents = append(parents, parentID) |
|
| 498 | 498 |
} |
| 499 | 499 |
|
| 500 | 500 |
return parents, nil |
| ... | ... |
@@ -6,18 +6,21 @@ import ( |
| 6 | 6 |
) |
| 7 | 7 |
|
| 8 | 8 |
const ( |
| 9 |
- // Define our own version of RFC339Nano because we want one |
|
| 9 |
+ // RFC3339NanoFixed is our own version of RFC339Nano because we want one |
|
| 10 | 10 |
// that pads the nano seconds part with zeros to ensure |
| 11 | 11 |
// the timestamps are aligned in the logs. |
| 12 | 12 |
RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00" |
| 13 |
- JSONFormat = `"` + time.RFC3339Nano + `"` |
|
| 13 |
+ // JSONFormat is the format used by FastMarshalJSON |
|
| 14 |
+ JSONFormat = `"` + time.RFC3339Nano + `"` |
|
| 14 | 15 |
) |
| 15 | 16 |
|
| 17 |
+// FastMarshalJSON avoids one of the extra allocations that |
|
| 18 |
+// time.MarshalJSON is making. |
|
| 16 | 19 |
func FastMarshalJSON(t time.Time) (string, error) {
|
| 17 | 20 |
if y := t.Year(); y < 0 || y >= 10000 {
|
| 18 | 21 |
// RFC 3339 is clear that years are 4 digits exactly. |
| 19 | 22 |
// See golang.org/issue/4556#c15 for more discussion. |
| 20 |
- return "", errors.New("Time.MarshalJSON: year outside of range [0,9999]")
|
|
| 23 |
+ return "", errors.New("time.MarshalJSON: year outside of range [0,9999]")
|
|
| 21 | 24 |
} |
| 22 | 25 |
return t.Format(JSONFormat), nil |
| 23 | 26 |
} |
| ... | ... |
@@ -10,7 +10,9 @@ import ( |
| 10 | 10 |
) |
| 11 | 11 |
|
| 12 | 12 |
var ( |
| 13 |
- ErrNoID = errors.New("prefix can't be empty")
|
|
| 13 |
+ // ErrNoID is thrown when attempting to use empty prefixes |
|
| 14 |
+ ErrNoID = errors.New("prefix can't be empty")
|
|
| 15 |
+ errDuplicateID = errors.New("multiple IDs were found")
|
|
| 14 | 16 |
) |
| 15 | 17 |
|
| 16 | 18 |
func init() {
|
| ... | ... |
@@ -27,56 +29,62 @@ type TruncIndex struct {
|
| 27 | 27 |
ids map[string]struct{}
|
| 28 | 28 |
} |
| 29 | 29 |
|
| 30 |
+// NewTruncIndex creates a new TruncIndex and initializes with a list of IDs |
|
| 30 | 31 |
func NewTruncIndex(ids []string) (idx *TruncIndex) {
|
| 31 | 32 |
idx = &TruncIndex{
|
| 32 | 33 |
ids: make(map[string]struct{}),
|
| 33 | 34 |
trie: patricia.NewTrie(), |
| 34 | 35 |
} |
| 35 | 36 |
for _, id := range ids {
|
| 36 |
- idx.addId(id) |
|
| 37 |
+ idx.addID(id) |
|
| 37 | 38 |
} |
| 38 | 39 |
return |
| 39 | 40 |
} |
| 40 | 41 |
|
| 41 |
-func (idx *TruncIndex) addId(id string) error {
|
|
| 42 |
+func (idx *TruncIndex) addID(id string) error {
|
|
| 42 | 43 |
if strings.Contains(id, " ") {
|
| 43 |
- return fmt.Errorf("Illegal character: ' '")
|
|
| 44 |
+ return fmt.Errorf("illegal character: ' '")
|
|
| 44 | 45 |
} |
| 45 | 46 |
if id == "" {
|
| 46 | 47 |
return ErrNoID |
| 47 | 48 |
} |
| 48 | 49 |
if _, exists := idx.ids[id]; exists {
|
| 49 |
- return fmt.Errorf("Id already exists: '%s'", id)
|
|
| 50 |
+ return fmt.Errorf("id already exists: '%s'", id)
|
|
| 50 | 51 |
} |
| 51 | 52 |
idx.ids[id] = struct{}{}
|
| 52 | 53 |
if inserted := idx.trie.Insert(patricia.Prefix(id), struct{}{}); !inserted {
|
| 53 |
- return fmt.Errorf("Failed to insert id: %s", id)
|
|
| 54 |
+ return fmt.Errorf("failed to insert id: %s", id)
|
|
| 54 | 55 |
} |
| 55 | 56 |
return nil |
| 56 | 57 |
} |
| 57 | 58 |
|
| 59 |
+// Add adds a new ID to the TruncIndex |
|
| 58 | 60 |
func (idx *TruncIndex) Add(id string) error {
|
| 59 | 61 |
idx.Lock() |
| 60 | 62 |
defer idx.Unlock() |
| 61 |
- if err := idx.addId(id); err != nil {
|
|
| 63 |
+ if err := idx.addID(id); err != nil {
|
|
| 62 | 64 |
return err |
| 63 | 65 |
} |
| 64 | 66 |
return nil |
| 65 | 67 |
} |
| 66 | 68 |
|
| 69 |
+// Delete removes an ID from the TruncIndex. If there are multiple IDs |
|
| 70 |
+// with the given prefix, an error is thrown. |
|
| 67 | 71 |
func (idx *TruncIndex) Delete(id string) error {
|
| 68 | 72 |
idx.Lock() |
| 69 | 73 |
defer idx.Unlock() |
| 70 | 74 |
if _, exists := idx.ids[id]; !exists || id == "" {
|
| 71 |
- return fmt.Errorf("No such id: '%s'", id)
|
|
| 75 |
+ return fmt.Errorf("no such id: '%s'", id)
|
|
| 72 | 76 |
} |
| 73 | 77 |
delete(idx.ids, id) |
| 74 | 78 |
if deleted := idx.trie.Delete(patricia.Prefix(id)); !deleted {
|
| 75 |
- return fmt.Errorf("No such id: '%s'", id)
|
|
| 79 |
+ return fmt.Errorf("no such id: '%s'", id)
|
|
| 76 | 80 |
} |
| 77 | 81 |
return nil |
| 78 | 82 |
} |
| 79 | 83 |
|
| 84 |
+// Get retrieves an ID from the TruncIndex. If there are multiple IDs |
|
| 85 |
+// with the given prefix, an error is thrown. |
|
| 80 | 86 |
func (idx *TruncIndex) Get(s string) (string, error) {
|
| 81 | 87 |
idx.RLock() |
| 82 | 88 |
defer idx.RUnlock() |
| ... | ... |
@@ -90,17 +98,17 @@ func (idx *TruncIndex) Get(s string) (string, error) {
|
| 90 | 90 |
if id != "" {
|
| 91 | 91 |
// we haven't found the ID if there are two or more IDs |
| 92 | 92 |
id = "" |
| 93 |
- return fmt.Errorf("we've found two entries")
|
|
| 93 |
+ return errDuplicateID |
|
| 94 | 94 |
} |
| 95 | 95 |
id = string(prefix) |
| 96 | 96 |
return nil |
| 97 | 97 |
} |
| 98 | 98 |
|
| 99 | 99 |
if err := idx.trie.VisitSubtree(patricia.Prefix(s), subTreeVisitFunc); err != nil {
|
| 100 |
- return "", fmt.Errorf("No such id: %s", s)
|
|
| 100 |
+ return "", fmt.Errorf("no such id: %s", s)
|
|
| 101 | 101 |
} |
| 102 | 102 |
if id != "" {
|
| 103 | 103 |
return id, nil |
| 104 | 104 |
} |
| 105 |
- return "", fmt.Errorf("No such id: %s", s)
|
|
| 105 |
+ return "", fmt.Errorf("no such id: %s", s)
|
|
| 106 | 106 |
} |
| ... | ... |
@@ -10,6 +10,7 @@ import ( |
| 10 | 10 |
// See: http://en.wikipedia.org/wiki/Binary_prefix |
| 11 | 11 |
const ( |
| 12 | 12 |
// Decimal |
| 13 |
+ |
|
| 13 | 14 |
KB = 1000 |
| 14 | 15 |
MB = 1000 * KB |
| 15 | 16 |
GB = 1000 * MB |
| ... | ... |
@@ -17,6 +18,7 @@ const ( |
| 17 | 17 |
PB = 1000 * TB |
| 18 | 18 |
|
| 19 | 19 |
// Binary |
| 20 |
+ |
|
| 20 | 21 |
KiB = 1024 |
| 21 | 22 |
MiB = 1024 * KiB |
| 22 | 23 |
GiB = 1024 * MiB |
| ... | ... |
@@ -60,7 +62,7 @@ func FromHumanSize(size string) (int64, error) {
|
| 60 | 60 |
return parseSize(size, decimalMap) |
| 61 | 61 |
} |
| 62 | 62 |
|
| 63 |
-// Parses a human-readable string representing an amount of RAM |
|
| 63 |
+// RAMInBytes parses a human-readable string representing an amount of RAM |
|
| 64 | 64 |
// in bytes, kibibytes, mebibytes, gibibytes, or tebibytes and |
| 65 | 65 |
// returns the number of bytes, or -1 if the string is unparseable. |
| 66 | 66 |
// Units are case-insensitive, and the 'b' suffix is optional. |
| ... | ... |
@@ -72,7 +74,7 @@ func RAMInBytes(size string) (int64, error) {
|
| 72 | 72 |
func parseSize(sizeStr string, uMap unitMap) (int64, error) {
|
| 73 | 73 |
matches := sizeRegex.FindStringSubmatch(sizeStr) |
| 74 | 74 |
if len(matches) != 3 {
|
| 75 |
- return -1, fmt.Errorf("Invalid size: '%s'", sizeStr)
|
|
| 75 |
+ return -1, fmt.Errorf("invalid size: '%s'", sizeStr)
|
|
| 76 | 76 |
} |
| 77 | 77 |
|
| 78 | 78 |
size, err := strconv.ParseInt(matches[1], 10, 0) |
| ... | ... |
@@ -5,53 +5,59 @@ import ( |
| 5 | 5 |
"strings" |
| 6 | 6 |
) |
| 7 | 7 |
|
| 8 |
+// Version provides utility methods for comparing versions. |
|
| 8 | 9 |
type Version string |
| 9 | 10 |
|
| 10 |
-func (me Version) compareTo(other Version) int {
|
|
| 11 |
+func (v Version) compareTo(other Version) int {
|
|
| 11 | 12 |
var ( |
| 12 |
- meTab = strings.Split(string(me), ".") |
|
| 13 |
+ currTab = strings.Split(string(v), ".") |
|
| 13 | 14 |
otherTab = strings.Split(string(other), ".") |
| 14 | 15 |
) |
| 15 | 16 |
|
| 16 |
- max := len(meTab) |
|
| 17 |
+ max := len(currTab) |
|
| 17 | 18 |
if len(otherTab) > max {
|
| 18 | 19 |
max = len(otherTab) |
| 19 | 20 |
} |
| 20 | 21 |
for i := 0; i < max; i++ {
|
| 21 |
- var meInt, otherInt int |
|
| 22 |
+ var currInt, otherInt int |
|
| 22 | 23 |
|
| 23 |
- if len(meTab) > i {
|
|
| 24 |
- meInt, _ = strconv.Atoi(meTab[i]) |
|
| 24 |
+ if len(currTab) > i {
|
|
| 25 |
+ currInt, _ = strconv.Atoi(currTab[i]) |
|
| 25 | 26 |
} |
| 26 | 27 |
if len(otherTab) > i {
|
| 27 | 28 |
otherInt, _ = strconv.Atoi(otherTab[i]) |
| 28 | 29 |
} |
| 29 |
- if meInt > otherInt {
|
|
| 30 |
+ if currInt > otherInt {
|
|
| 30 | 31 |
return 1 |
| 31 | 32 |
} |
| 32 |
- if otherInt > meInt {
|
|
| 33 |
+ if otherInt > currInt {
|
|
| 33 | 34 |
return -1 |
| 34 | 35 |
} |
| 35 | 36 |
} |
| 36 | 37 |
return 0 |
| 37 | 38 |
} |
| 38 | 39 |
|
| 39 |
-func (me Version) LessThan(other Version) bool {
|
|
| 40 |
- return me.compareTo(other) == -1 |
|
| 40 |
+// LessThan checks if a version is less than another version |
|
| 41 |
+func (v Version) LessThan(other Version) bool {
|
|
| 42 |
+ return v.compareTo(other) == -1 |
|
| 41 | 43 |
} |
| 42 | 44 |
|
| 43 |
-func (me Version) LessThanOrEqualTo(other Version) bool {
|
|
| 44 |
- return me.compareTo(other) <= 0 |
|
| 45 |
+// LessThanOrEqualTo checks if a version is less than or equal to another |
|
| 46 |
+func (v Version) LessThanOrEqualTo(other Version) bool {
|
|
| 47 |
+ return v.compareTo(other) <= 0 |
|
| 45 | 48 |
} |
| 46 | 49 |
|
| 47 |
-func (me Version) GreaterThan(other Version) bool {
|
|
| 48 |
- return me.compareTo(other) == 1 |
|
| 50 |
+// GreaterThan checks if a version is greater than another one |
|
| 51 |
+func (v Version) GreaterThan(other Version) bool {
|
|
| 52 |
+ return v.compareTo(other) == 1 |
|
| 49 | 53 |
} |
| 50 | 54 |
|
| 51 |
-func (me Version) GreaterThanOrEqualTo(other Version) bool {
|
|
| 52 |
- return me.compareTo(other) >= 0 |
|
| 55 |
+// GreaterThanOrEqualTo checks ia version is greater than or equal to another |
|
| 56 |
+func (v Version) GreaterThanOrEqualTo(other Version) bool {
|
|
| 57 |
+ return v.compareTo(other) >= 0 |
|
| 53 | 58 |
} |
| 54 | 59 |
|
| 55 |
-func (me Version) Equal(other Version) bool {
|
|
| 56 |
- return me.compareTo(other) == 0 |
|
| 60 |
+// Equal checks if a version is equal to another |
|
| 61 |
+func (v Version) Equal(other Version) bool {
|
|
| 62 |
+ return v.compareTo(other) == 0 |
|
| 57 | 63 |
} |
| ... | ... |
@@ -227,12 +227,11 @@ func Login(authConfig *AuthConfig, factory *utils.HTTPRequestFactory) (string, e |
| 227 | 227 |
return "", fmt.Errorf("Login: Account is not Active. Please check your e-mail for a confirmation link.")
|
| 228 | 228 |
} |
| 229 | 229 |
return "", fmt.Errorf("Login: Account is not Active. Please see the documentation of the registry %s for instructions how to activate it.", serverAddress)
|
| 230 |
- } else {
|
|
| 231 |
- return "", fmt.Errorf("Login: %s (Code: %d; Headers: %s)", body, resp.StatusCode, resp.Header)
|
|
| 232 | 230 |
} |
| 233 |
- } else {
|
|
| 234 |
- return "", fmt.Errorf("Registration: %s", reqBody)
|
|
| 231 |
+ return "", fmt.Errorf("Login: %s (Code: %d; Headers: %s)", body, resp.StatusCode, resp.Header)
|
|
| 235 | 232 |
} |
| 233 |
+ return "", fmt.Errorf("Registration: %s", reqBody)
|
|
| 234 |
+ |
|
| 236 | 235 |
} else if reqStatusCode == 401 {
|
| 237 | 236 |
// This case would happen with private registries where /v1/users is |
| 238 | 237 |
// protected, so people can use `docker login` as an auth check. |
| ... | ... |
@@ -13,7 +13,7 @@ import ( |
| 13 | 13 |
) |
| 14 | 14 |
|
| 15 | 15 |
// scans string for api version in the URL path. returns the trimmed hostname, if version found, string and API version. |
| 16 |
-func scanForApiVersion(hostname string) (string, APIVersion) {
|
|
| 16 |
+func scanForAPIVersion(hostname string) (string, APIVersion) {
|
|
| 17 | 17 |
var ( |
| 18 | 18 |
chunks []string |
| 19 | 19 |
apiVersionStr string |
| ... | ... |
@@ -43,7 +43,7 @@ func NewEndpoint(hostname string) (*Endpoint, error) {
|
| 43 | 43 |
if !strings.HasPrefix(hostname, "http") {
|
| 44 | 44 |
hostname = "https://" + hostname |
| 45 | 45 |
} |
| 46 |
- trimmedHostname, endpoint.Version = scanForApiVersion(hostname) |
|
| 46 |
+ trimmedHostname, endpoint.Version = scanForAPIVersion(hostname) |
|
| 47 | 47 |
endpoint.URL, err = url.Parse(trimmedHostname) |
| 48 | 48 |
if err != nil {
|
| 49 | 49 |
return nil, err |
| ... | ... |
@@ -19,7 +19,7 @@ import ( |
| 19 | 19 |
) |
| 20 | 20 |
|
| 21 | 21 |
var ( |
| 22 |
- testHttpServer *httptest.Server |
|
| 22 |
+ testHTTPServer *httptest.Server |
|
| 23 | 23 |
testLayers = map[string]map[string]string{
|
| 24 | 24 |
"77dbf71da1d00e3fbddc480176eac8994025630c6590d11cfc8fe1209c2a1d20": {
|
| 25 | 25 |
"json": `{"id":"77dbf71da1d00e3fbddc480176eac8994025630c6590d11cfc8fe1209c2a1d20",
|
| ... | ... |
@@ -99,7 +99,7 @@ func init() {
|
| 99 | 99 |
// /v2/ |
| 100 | 100 |
r.HandleFunc("/v2/version", handlerGetPing).Methods("GET")
|
| 101 | 101 |
|
| 102 |
- testHttpServer = httptest.NewServer(handlerAccessLog(r)) |
|
| 102 |
+ testHTTPServer = httptest.NewServer(handlerAccessLog(r)) |
|
| 103 | 103 |
} |
| 104 | 104 |
|
| 105 | 105 |
func handlerAccessLog(handler http.Handler) http.Handler {
|
| ... | ... |
@@ -111,7 +111,7 @@ func handlerAccessLog(handler http.Handler) http.Handler {
|
| 111 | 111 |
} |
| 112 | 112 |
|
| 113 | 113 |
func makeURL(req string) string {
|
| 114 |
- return testHttpServer.URL + req |
|
| 114 |
+ return testHTTPServer.URL + req |
|
| 115 | 115 |
} |
| 116 | 116 |
|
| 117 | 117 |
func writeHeaders(w http.ResponseWriter) {
|
| ... | ... |
@@ -198,8 +198,8 @@ func handlerGetImage(w http.ResponseWriter, r *http.Request) {
|
| 198 | 198 |
return |
| 199 | 199 |
} |
| 200 | 200 |
writeHeaders(w) |
| 201 |
- layer_size := len(layer["layer"]) |
|
| 202 |
- w.Header().Add("X-Docker-Size", strconv.Itoa(layer_size))
|
|
| 201 |
+ layerSize := len(layer["layer"]) |
|
| 202 |
+ w.Header().Add("X-Docker-Size", strconv.Itoa(layerSize))
|
|
| 203 | 203 |
io.WriteString(w, layer[vars["action"]]) |
| 204 | 204 |
} |
| 205 | 205 |
|
| ... | ... |
@@ -208,16 +208,16 @@ func handlerPutImage(w http.ResponseWriter, r *http.Request) {
|
| 208 | 208 |
return |
| 209 | 209 |
} |
| 210 | 210 |
vars := mux.Vars(r) |
| 211 |
- image_id := vars["image_id"] |
|
| 211 |
+ imageID := vars["image_id"] |
|
| 212 | 212 |
action := vars["action"] |
| 213 |
- layer, exists := testLayers[image_id] |
|
| 213 |
+ layer, exists := testLayers[imageID] |
|
| 214 | 214 |
if !exists {
|
| 215 | 215 |
if action != "json" {
|
| 216 | 216 |
http.NotFound(w, r) |
| 217 | 217 |
return |
| 218 | 218 |
} |
| 219 | 219 |
layer = make(map[string]string) |
| 220 |
- testLayers[image_id] = layer |
|
| 220 |
+ testLayers[imageID] = layer |
|
| 221 | 221 |
} |
| 222 | 222 |
if checksum := r.Header.Get("X-Docker-Checksum"); checksum != "" {
|
| 223 | 223 |
if checksum != layer["checksum_simple"] && checksum != layer["checksum_tarsum"] {
|
| ... | ... |
@@ -301,7 +301,7 @@ func handlerUsers(w http.ResponseWriter, r *http.Request) {
|
| 301 | 301 |
} |
| 302 | 302 |
|
| 303 | 303 |
func handlerImages(w http.ResponseWriter, r *http.Request) {
|
| 304 |
- u, _ := url.Parse(testHttpServer.URL) |
|
| 304 |
+ u, _ := url.Parse(testHTTPServer.URL) |
|
| 305 | 305 |
w.Header().Add("X-Docker-Endpoints", fmt.Sprintf("%s , %s ", u.Host, "test.example.com"))
|
| 306 | 306 |
w.Header().Add("X-Docker-Token", fmt.Sprintf("FAKE-SESSION-%d", time.Now().UnixNano()))
|
| 307 | 307 |
if r.Method == "PUT" {
|
| ... | ... |
@@ -317,9 +317,9 @@ func handlerImages(w http.ResponseWriter, r *http.Request) {
|
| 317 | 317 |
return |
| 318 | 318 |
} |
| 319 | 319 |
images := []map[string]string{}
|
| 320 |
- for image_id, layer := range testLayers {
|
|
| 320 |
+ for imageID, layer := range testLayers {
|
|
| 321 | 321 |
image := make(map[string]string) |
| 322 |
- image["id"] = image_id |
|
| 322 |
+ image["id"] = imageID |
|
| 323 | 323 |
image["checksum"] = layer["checksum_tarsum"] |
| 324 | 324 |
image["Tag"] = "latest" |
| 325 | 325 |
images = append(images, image) |
| ... | ... |
@@ -11,9 +11,12 @@ import ( |
| 11 | 11 |
) |
| 12 | 12 |
|
| 13 | 13 |
var ( |
| 14 |
- IMAGE_ID = "42d718c941f5c532ac049bf0b0ab53f0062f09a03afd4aa4a02c098e46032b9d" |
|
| 15 |
- TOKEN = []string{"fake-token"}
|
|
| 16 |
- REPO = "foo42/bar" |
|
| 14 |
+ token = []string{"fake-token"}
|
|
| 15 |
+) |
|
| 16 |
+ |
|
| 17 |
+const ( |
|
| 18 |
+ imageID = "42d718c941f5c532ac049bf0b0ab53f0062f09a03afd4aa4a02c098e46032b9d" |
|
| 19 |
+ REPO = "foo42/bar" |
|
| 17 | 20 |
) |
| 18 | 21 |
|
| 19 | 22 |
func spawnTestRegistrySession(t *testing.T) *Session {
|
| ... | ... |
@@ -43,27 +46,27 @@ func TestPingRegistryEndpoint(t *testing.T) {
|
| 43 | 43 |
|
| 44 | 44 |
func TestGetRemoteHistory(t *testing.T) {
|
| 45 | 45 |
r := spawnTestRegistrySession(t) |
| 46 |
- hist, err := r.GetRemoteHistory(IMAGE_ID, makeURL("/v1/"), TOKEN)
|
|
| 46 |
+ hist, err := r.GetRemoteHistory(imageID, makeURL("/v1/"), token)
|
|
| 47 | 47 |
if err != nil {
|
| 48 | 48 |
t.Fatal(err) |
| 49 | 49 |
} |
| 50 | 50 |
assertEqual(t, len(hist), 2, "Expected 2 images in history") |
| 51 |
- assertEqual(t, hist[0], IMAGE_ID, "Expected "+IMAGE_ID+"as first ancestry") |
|
| 51 |
+ assertEqual(t, hist[0], imageID, "Expected "+imageID+"as first ancestry") |
|
| 52 | 52 |
assertEqual(t, hist[1], "77dbf71da1d00e3fbddc480176eac8994025630c6590d11cfc8fe1209c2a1d20", |
| 53 | 53 |
"Unexpected second ancestry") |
| 54 | 54 |
} |
| 55 | 55 |
|
| 56 | 56 |
func TestLookupRemoteImage(t *testing.T) {
|
| 57 | 57 |
r := spawnTestRegistrySession(t) |
| 58 |
- found := r.LookupRemoteImage(IMAGE_ID, makeURL("/v1/"), TOKEN)
|
|
| 58 |
+ found := r.LookupRemoteImage(imageID, makeURL("/v1/"), token)
|
|
| 59 | 59 |
assertEqual(t, found, true, "Expected remote lookup to succeed") |
| 60 |
- found = r.LookupRemoteImage("abcdef", makeURL("/v1/"), TOKEN)
|
|
| 60 |
+ found = r.LookupRemoteImage("abcdef", makeURL("/v1/"), token)
|
|
| 61 | 61 |
assertEqual(t, found, false, "Expected remote lookup to fail") |
| 62 | 62 |
} |
| 63 | 63 |
|
| 64 | 64 |
func TestGetRemoteImageJSON(t *testing.T) {
|
| 65 | 65 |
r := spawnTestRegistrySession(t) |
| 66 |
- json, size, err := r.GetRemoteImageJSON(IMAGE_ID, makeURL("/v1/"), TOKEN)
|
|
| 66 |
+ json, size, err := r.GetRemoteImageJSON(imageID, makeURL("/v1/"), token)
|
|
| 67 | 67 |
if err != nil {
|
| 68 | 68 |
t.Fatal(err) |
| 69 | 69 |
} |
| ... | ... |
@@ -72,7 +75,7 @@ func TestGetRemoteImageJSON(t *testing.T) {
|
| 72 | 72 |
t.Fatal("Expected non-empty json")
|
| 73 | 73 |
} |
| 74 | 74 |
|
| 75 |
- _, _, err = r.GetRemoteImageJSON("abcdef", makeURL("/v1/"), TOKEN)
|
|
| 75 |
+ _, _, err = r.GetRemoteImageJSON("abcdef", makeURL("/v1/"), token)
|
|
| 76 | 76 |
if err == nil {
|
| 77 | 77 |
t.Fatal("Expected image not found error")
|
| 78 | 78 |
} |
| ... | ... |
@@ -80,7 +83,7 @@ func TestGetRemoteImageJSON(t *testing.T) {
|
| 80 | 80 |
|
| 81 | 81 |
func TestGetRemoteImageLayer(t *testing.T) {
|
| 82 | 82 |
r := spawnTestRegistrySession(t) |
| 83 |
- data, err := r.GetRemoteImageLayer(IMAGE_ID, makeURL("/v1/"), TOKEN, 0)
|
|
| 83 |
+ data, err := r.GetRemoteImageLayer(imageID, makeURL("/v1/"), token, 0)
|
|
| 84 | 84 |
if err != nil {
|
| 85 | 85 |
t.Fatal(err) |
| 86 | 86 |
} |
| ... | ... |
@@ -88,7 +91,7 @@ func TestGetRemoteImageLayer(t *testing.T) {
|
| 88 | 88 |
t.Fatal("Expected non-nil data result")
|
| 89 | 89 |
} |
| 90 | 90 |
|
| 91 |
- _, err = r.GetRemoteImageLayer("abcdef", makeURL("/v1/"), TOKEN, 0)
|
|
| 91 |
+ _, err = r.GetRemoteImageLayer("abcdef", makeURL("/v1/"), token, 0)
|
|
| 92 | 92 |
if err == nil {
|
| 93 | 93 |
t.Fatal("Expected image not found error")
|
| 94 | 94 |
} |
| ... | ... |
@@ -96,14 +99,14 @@ func TestGetRemoteImageLayer(t *testing.T) {
|
| 96 | 96 |
|
| 97 | 97 |
func TestGetRemoteTags(t *testing.T) {
|
| 98 | 98 |
r := spawnTestRegistrySession(t) |
| 99 |
- tags, err := r.GetRemoteTags([]string{makeURL("/v1/")}, REPO, TOKEN)
|
|
| 99 |
+ tags, err := r.GetRemoteTags([]string{makeURL("/v1/")}, REPO, token)
|
|
| 100 | 100 |
if err != nil {
|
| 101 | 101 |
t.Fatal(err) |
| 102 | 102 |
} |
| 103 | 103 |
assertEqual(t, len(tags), 1, "Expected one tag") |
| 104 |
- assertEqual(t, tags["latest"], IMAGE_ID, "Expected tag latest to map to "+IMAGE_ID) |
|
| 104 |
+ assertEqual(t, tags["latest"], imageID, "Expected tag latest to map to "+imageID) |
|
| 105 | 105 |
|
| 106 |
- _, err = r.GetRemoteTags([]string{makeURL("/v1/")}, "foo42/baz", TOKEN)
|
|
| 106 |
+ _, err = r.GetRemoteTags([]string{makeURL("/v1/")}, "foo42/baz", token)
|
|
| 107 | 107 |
if err == nil {
|
| 108 | 108 |
t.Fatal("Expected error when fetching tags for bogus repo")
|
| 109 | 109 |
} |
| ... | ... |
@@ -111,11 +114,11 @@ func TestGetRemoteTags(t *testing.T) {
|
| 111 | 111 |
|
| 112 | 112 |
func TestGetRepositoryData(t *testing.T) {
|
| 113 | 113 |
r := spawnTestRegistrySession(t) |
| 114 |
- parsedUrl, err := url.Parse(makeURL("/v1/"))
|
|
| 114 |
+ parsedURL, err := url.Parse(makeURL("/v1/"))
|
|
| 115 | 115 |
if err != nil {
|
| 116 | 116 |
t.Fatal(err) |
| 117 | 117 |
} |
| 118 |
- host := "http://" + parsedUrl.Host + "/v1/" |
|
| 118 |
+ host := "http://" + parsedURL.Host + "/v1/" |
|
| 119 | 119 |
data, err := r.GetRepositoryData("foo42/bar")
|
| 120 | 120 |
if err != nil {
|
| 121 | 121 |
t.Fatal(err) |
| ... | ... |
@@ -137,7 +140,7 @@ func TestPushImageJSONRegistry(t *testing.T) {
|
| 137 | 137 |
Checksum: "sha256:1ac330d56e05eef6d438586545ceff7550d3bdcb6b19961f12c5ba714ee1bb37", |
| 138 | 138 |
} |
| 139 | 139 |
|
| 140 |
- err := r.PushImageJSONRegistry(imgData, []byte{0x42, 0xdf, 0x0}, makeURL("/v1/"), TOKEN)
|
|
| 140 |
+ err := r.PushImageJSONRegistry(imgData, []byte{0x42, 0xdf, 0x0}, makeURL("/v1/"), token)
|
|
| 141 | 141 |
if err != nil {
|
| 142 | 142 |
t.Fatal(err) |
| 143 | 143 |
} |
| ... | ... |
@@ -146,7 +149,7 @@ func TestPushImageJSONRegistry(t *testing.T) {
|
| 146 | 146 |
func TestPushImageLayerRegistry(t *testing.T) {
|
| 147 | 147 |
r := spawnTestRegistrySession(t) |
| 148 | 148 |
layer := strings.NewReader("")
|
| 149 |
- _, _, err := r.PushImageLayerRegistry(IMAGE_ID, layer, makeURL("/v1/"), TOKEN, []byte{})
|
|
| 149 |
+ _, _, err := r.PushImageLayerRegistry(imageID, layer, makeURL("/v1/"), token, []byte{})
|
|
| 150 | 150 |
if err != nil {
|
| 151 | 151 |
t.Fatal(err) |
| 152 | 152 |
} |
| ... | ... |
@@ -180,7 +183,7 @@ func TestResolveRepositoryName(t *testing.T) {
|
| 180 | 180 |
|
| 181 | 181 |
func TestPushRegistryTag(t *testing.T) {
|
| 182 | 182 |
r := spawnTestRegistrySession(t) |
| 183 |
- err := r.PushRegistryTag("foo42/bar", IMAGE_ID, "stable", makeURL("/v1/"), TOKEN)
|
|
| 183 |
+ err := r.PushRegistryTag("foo42/bar", imageID, "stable", makeURL("/v1/"), token)
|
|
| 184 | 184 |
if err != nil {
|
| 185 | 185 |
t.Fatal(err) |
| 186 | 186 |
} |
| ... | ... |
@@ -3,6 +3,7 @@ package registry |
| 3 | 3 |
import ( |
| 4 | 4 |
"bytes" |
| 5 | 5 |
"crypto/sha256" |
| 6 |
+ // this is required for some certificates |
|
| 6 | 7 |
_ "crypto/sha512" |
| 7 | 8 |
"encoding/hex" |
| 8 | 9 |
"encoding/json" |
| ... | ... |
@@ -243,11 +244,11 @@ func (r *Session) GetRemoteTags(registries []string, repository string, token [] |
| 243 | 243 |
|
| 244 | 244 |
func buildEndpointsList(headers []string, indexEp string) ([]string, error) {
|
| 245 | 245 |
var endpoints []string |
| 246 |
- parsedUrl, err := url.Parse(indexEp) |
|
| 246 |
+ parsedURL, err := url.Parse(indexEp) |
|
| 247 | 247 |
if err != nil {
|
| 248 | 248 |
return nil, err |
| 249 | 249 |
} |
| 250 |
- var urlScheme = parsedUrl.Scheme |
|
| 250 |
+ var urlScheme = parsedURL.Scheme |
|
| 251 | 251 |
// The Registry's URL scheme has to match the Index' |
| 252 | 252 |
for _, ep := range headers {
|
| 253 | 253 |
epList := strings.Split(ep, ",") |