feat: mem, local uploader
This commit is contained in:
113
internal/interfaces/blobs/local.go
Normal file
113
internal/interfaces/blobs/local.go
Normal file
@ -0,0 +1,113 @@
|
||||
package blobs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"nf-repo/internal/interfaces"
|
||||
"nf-repo/internal/model"
|
||||
"nf-repo/internal/opt"
|
||||
"os"
|
||||
"path"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type localHandler struct {
|
||||
base string
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
func (l *localHandler) path(hash model.Hash) string {
|
||||
//return path.Join(l.base, hash.Hex)
|
||||
dir := path.Join(l.base, hash.Hex[:2], hash.Hex[2:4])
|
||||
_ = os.MkdirAll(dir, 0755)
|
||||
return path.Join(dir, hash.Hex)
|
||||
}
|
||||
|
||||
func (l *localHandler) Get(ctx context.Context, repo string, hash model.Hash) (io.ReadCloser, error) {
|
||||
var (
|
||||
err error
|
||||
f *os.File
|
||||
)
|
||||
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
|
||||
if f, err = os.Open(l.path(hash)); err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return nil, opt.ErrNotFound
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (l *localHandler) Stat(ctx context.Context, repo string, hash model.Hash) (int64, error) {
|
||||
var (
|
||||
err error
|
||||
info os.FileInfo
|
||||
)
|
||||
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
|
||||
if info, err = os.Stat(l.path(hash)); err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return 0, opt.ErrNotFound
|
||||
}
|
||||
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return info.Size(), nil
|
||||
}
|
||||
|
||||
func (l *localHandler) Put(ctx context.Context, repo string, hash model.Hash, rc io.ReadCloser) error {
|
||||
var (
|
||||
err error
|
||||
f *os.File
|
||||
)
|
||||
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
|
||||
if f, err = os.OpenFile(l.path(hash), os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = io.Copy(f, rc); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *localHandler) Delete(ctx context.Context, repo string, hash model.Hash) error {
|
||||
var (
|
||||
err error
|
||||
info os.FileInfo
|
||||
filename = l.path(hash)
|
||||
)
|
||||
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
|
||||
if info, err = os.Stat(filename); err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return opt.ErrNotFound
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
_ = info
|
||||
|
||||
return os.Remove(filename)
|
||||
}
|
||||
|
||||
func NewLocalBlobHandler(baseDir string) interfaces.BlobHandler {
|
||||
_ = os.MkdirAll(baseDir, 0755)
|
||||
return &localHandler{base: baseDir}
|
||||
}
|
77
internal/interfaces/blobs/mem.go
Normal file
77
internal/interfaces/blobs/mem.go
Normal file
@ -0,0 +1,77 @@
|
||||
package blobs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"nf-repo/internal/interfaces"
|
||||
"nf-repo/internal/model"
|
||||
"nf-repo/internal/opt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type bytesCloser struct {
|
||||
*bytes.Reader
|
||||
}
|
||||
|
||||
func (r *bytesCloser) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type memHandler struct {
|
||||
m map[string][]byte
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
func NewMemBlobHandler() interfaces.BlobHandler {
|
||||
return &memHandler{
|
||||
m: map[string][]byte{},
|
||||
}
|
||||
}
|
||||
|
||||
func (m *memHandler) Stat(_ context.Context, _ string, h model.Hash) (int64, error) {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
|
||||
bs, found := m.m[h.String()]
|
||||
if !found {
|
||||
return 0, opt.ErrNotFound
|
||||
}
|
||||
return int64(len(bs)), nil
|
||||
}
|
||||
|
||||
func (m *memHandler) Get(_ context.Context, _ string, h model.Hash) (io.ReadCloser, error) {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
|
||||
bs, found := m.m[h.String()]
|
||||
if !found {
|
||||
return nil, opt.ErrNotFound
|
||||
}
|
||||
return &bytesCloser{bytes.NewReader(bs)}, nil
|
||||
}
|
||||
|
||||
func (m *memHandler) Put(_ context.Context, _ string, h model.Hash, rc io.ReadCloser) error {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
|
||||
defer rc.Close()
|
||||
all, err := io.ReadAll(rc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.m[h.String()] = all
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *memHandler) Delete(_ context.Context, _ string, h model.Hash) error {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
|
||||
if _, found := m.m[h.String()]; !found {
|
||||
return opt.ErrNotFound
|
||||
}
|
||||
|
||||
delete(m.m, h.String())
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user