123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- package server
- import (
- "crypto/sha256"
- "fmt"
- "io"
- "os"
- "strings"
- "golang.org/x/exp/slices"
- )
- type Layers struct {
- items []*Layer
- }
- func (ls *Layers) Add(layer *Layer) {
- if layer.Size > 0 {
- ls.items = append(ls.items, layer)
- }
- }
- func (ls *Layers) Replace(layer *Layer) {
- if layer.Size > 0 {
- mediatype := layer.MediaType
- layers := slices.DeleteFunc(ls.items, func(l *Layer) bool {
- return l.MediaType == mediatype
- })
- ls.items = append(layers, layer)
- }
- }
- type Layer struct {
- MediaType string `json:"mediaType"`
- Digest string `json:"digest"`
- Size int64 `json:"size"`
- From string `json:"from,omitempty"`
- tempFileName string
- }
- func NewLayer(r io.Reader, mediatype string) (*Layer, error) {
- blobs, err := GetBlobsPath("")
- if err != nil {
- return nil, err
- }
- const delimiter = "-"
- pattern := strings.Join([]string{"sha256", "*-partial"}, delimiter)
- temp, err := os.CreateTemp(blobs, pattern)
- if err != nil {
- return nil, err
- }
- defer temp.Close()
- sha256sum := sha256.New()
- n, err := io.Copy(io.MultiWriter(temp, sha256sum), r)
- if err != nil {
- return nil, err
- }
- return &Layer{
- MediaType: mediatype,
- Digest: fmt.Sprintf("sha256:%x", sha256sum.Sum(nil)),
- Size: n,
- tempFileName: temp.Name(),
- }, nil
- }
- func NewLayerFromLayer(digest, mediatype, from string) (*Layer, error) {
- blob, err := GetBlobsPath(digest)
- if err != nil {
- return nil, err
- }
- fi, err := os.Stat(blob)
- if err != nil {
- return nil, err
- }
- return &Layer{
- MediaType: mediatype,
- Digest: digest,
- Size: fi.Size(),
- From: from,
- }, nil
- }
- func (l *Layer) Commit() (bool, error) {
- // always remove temp
- defer os.Remove(l.tempFileName)
- blob, err := GetBlobsPath(l.Digest)
- if err != nil {
- return false, err
- }
- if _, err := os.Stat(blob); err != nil {
- return true, os.Rename(l.tempFileName, blob)
- }
- return false, nil
- }
|