maddy/internal/storage/blob/fs/fs.go

95 lines
1.9 KiB
Go

package fs
import (
"context"
"fmt"
"io"
"os"
"path/filepath"
"github.com/foxcpp/maddy/framework/config"
"github.com/foxcpp/maddy/framework/module"
)
// FSStore struct represents directory on FS used to store blobs.
type FSStore struct {
instName string
root string
}
func New(_, instName string, _, inlineArgs []string) (module.Module, error) {
switch len(inlineArgs) {
case 0:
return &FSStore{instName: instName}, nil
case 1:
return &FSStore{instName: instName, root: inlineArgs[0]}, nil
default:
return nil, fmt.Errorf("storage.blob.fs: 1 or 0 arguments expected")
}
}
func (s FSStore) Name() string {
return "storage.blob.fs"
}
func (s FSStore) InstanceName() string {
return s.instName
}
func (s *FSStore) Init(cfg *config.Map) error {
cfg.String("root", false, false, s.root, &s.root)
if _, err := cfg.Process(); err != nil {
return err
}
if s.root == "" {
return config.NodeErr(cfg.Block, "storage.blob.fs: directory not set")
}
if err := os.MkdirAll(s.root, os.ModeDir|os.ModePerm); err != nil {
return err
}
return nil
}
func (s *FSStore) Open(_ context.Context, key string) (io.ReadCloser, error) {
f, err := os.Open(filepath.Join(s.root, key))
if err != nil {
if os.IsNotExist(err) {
return nil, module.ErrNoSuchBlob
}
return nil, err
}
return f, nil
}
func (s *FSStore) Create(_ context.Context, key string, blobSize int64) (module.Blob, error) {
f, err := os.Create(filepath.Join(s.root, key))
if err != nil {
return nil, err
}
if blobSize >= 0 {
if err := f.Truncate(blobSize); err != nil {
return nil, err
}
}
return f, nil
}
func (s *FSStore) Delete(_ context.Context, keys []string) error {
for _, key := range keys {
if err := os.Remove(filepath.Join(s.root, key)); err != nil {
if os.IsNotExist(err) {
continue
}
return err
}
}
return nil
}
func init() {
var _ module.BlobStore = &FSStore{}
module.Register(FSStore{}.Name(), New)
}