lib/dockerregistry/metadata.go (80 lines of code) (raw):

// Copyright (c) 2016-2019 Uber Technologies, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package dockerregistry import ( "fmt" "regexp" "strings" "time" "github.com/uber/kraken/lib/store/metadata" ) const ( _startedAtSuffix = "_startedat" _startedAtLayout = time.RFC3339 ) func init() { metadata.Register(regexp.MustCompile(_startedAtSuffix), &startedAtMetadataFactory{}) // TODO(evelynl): use _ instead of /, otherwise it won't support reload. metadata.Register(regexp.MustCompile("_hashstates/\\w+/\\w+$"), &hashStateMetadataFactory{}) } type startedAtMetadataFactory struct{} func (f startedAtMetadataFactory) Create(suffix string) metadata.Metadata { return &startedAtMetadata{} } // startedAtMetadata is used to remove uploads that have been active for too long. type startedAtMetadata struct { time time.Time } func newStartedAtMetadata(t time.Time) *startedAtMetadata { return &startedAtMetadata{t} } func (s *startedAtMetadata) GetSuffix() string { return _startedAtSuffix } func (s *startedAtMetadata) Movable() bool { return false } func (s *startedAtMetadata) Serialize() ([]byte, error) { return []byte(s.time.Format(_startedAtLayout)), nil } func (s *startedAtMetadata) Deserialize(b []byte) error { t, err := time.Parse(_startedAtLayout, string(b)) if err != nil { return err } s.time = t return nil } type hashStateMetadataFactory struct{} func (f hashStateMetadataFactory) Create(suffix string) metadata.Metadata { parts := strings.Split(suffix, "/") if len(parts) != 3 { return nil } algo := parts[1] offset := parts[2] return newHashStateMetadata(algo, offset) } // hashStateMetadata stores partial hash result of upload data for resumable upload. // Docker registry double writes to a writer and digester, and the digester // generates this snapshot. type hashStateMetadata struct { algo string offset string content []byte } func newHashStateMetadata(algo, offset string) *hashStateMetadata { return &hashStateMetadata{ algo: algo, offset: offset, } } func (h *hashStateMetadata) GetSuffix() string { return fmt.Sprintf("_hashstates/%s/%s", h.algo, h.offset) } func (h *hashStateMetadata) Movable() bool { return false } func (h *hashStateMetadata) Serialize() ([]byte, error) { return h.content, nil } func (h *hashStateMetadata) Deserialize(b []byte) error { h.content = b return nil } func (h *hashStateMetadata) dockerPath() string { return fmt.Sprintf("hashstates/%s/%s", h.algo, h.offset) }