1package fs23import (4 "context"5 "fmt"6 "io"7 "os"8 "path/filepath"910 "github.com/foxcpp/maddy/framework/config"11 "github.com/foxcpp/maddy/framework/module"12)1314// FSStore struct represents directory on FS used to store blobs.15type FSStore struct {16 instName string17 root string18}1920func New(_, instName string, _, inlineArgs []string) (module.Module, error) {21 switch len(inlineArgs) {22 case 0:23 return &FSStore{instName: instName}, nil24 case 1:25 return &FSStore{instName: instName, root: inlineArgs[0]}, nil26 default:27 return nil, fmt.Errorf("storage.blob.fs: 1 or 0 arguments expected")28 }29}3031func (s FSStore) Name() string {32 return "storage.blob.fs"33}3435func (s FSStore) InstanceName() string {36 return s.instName37}3839func (s *FSStore) Init(cfg *config.Map) error {40 cfg.String("root", false, false, s.root, &s.root)41 if _, err := cfg.Process(); err != nil {42 return err43 }4445 if s.root == "" {46 return config.NodeErr(cfg.Block, "storage.blob.fs: directory not set")47 }4849 if err := os.MkdirAll(s.root, os.ModeDir|os.ModePerm); err != nil {50 return err51 }5253 return nil54}5556func (s *FSStore) Open(_ context.Context, key string) (io.ReadCloser, error) {57 f, err := os.Open(filepath.Join(s.root, key))58 if err != nil {59 if os.IsNotExist(err) {60 return nil, module.ErrNoSuchBlob61 }62 return nil, err63 }64 return f, nil65}6667func (s *FSStore) Create(_ context.Context, key string, blobSize int64) (module.Blob, error) {68 f, err := os.Create(filepath.Join(s.root, key))69 if err != nil {70 return nil, err71 }72 if blobSize >= 0 {73 if err := f.Truncate(blobSize); err != nil {74 return nil, err75 }76 }77 return f, nil78}7980func (s *FSStore) Delete(_ context.Context, keys []string) error {81 for _, key := range keys {82 if err := os.Remove(filepath.Join(s.root, key)); err != nil {83 if os.IsNotExist(err) {84 continue85 }86 return err87 }88 }89 return nil90}9192func init() {93 var _ module.BlobStore = &FSStore{}94 module.Register(FSStore{}.Name(), New)95}