mirror of
https://github.com/foxcpp/maddy.git
synced 2025-04-06 14:37:37 +03:00
95 lines
1.9 KiB
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)
|
|
}
|