dir remove ext (#634)

This commit is contained in:
Alex Sharov 2022-09-12 10:51:50 +07:00 committed by GitHub
parent 2017964398
commit 34bd7cfc4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,62 +1,10 @@
package dir
import (
"errors"
"fmt"
"os"
"path/filepath"
"syscall"
"github.com/gofrs/flock"
"github.com/ledgerwatch/log/v3"
)
// Rw - type to represent Read-Write access to directory
// if some code accept this typ - it can be sure: dir exists, no other process now write there
// We have no specific Ro type, just use `string` for Ro directory path
type Rw struct {
dirLock *flock.Flock // prevents concurrent use of instance directory
Path string
}
func convertFileLockError(err error, dir string) error {
if errno, ok := err.(syscall.Errno); ok && dirInUseErrnos[uint(errno)] { //nolint
return fmt.Errorf("%w: %s", ErrDirUsed, dir)
}
return err
}
var dirInUseErrnos = map[uint]bool{11: true, 32: true, 35: true}
var (
ErrDirUsed = errors.New("datadir already used by another process")
)
func OpenRw(dir string) (*Rw, error) {
MustExist(dir)
// Lock the instance directory to prevent concurrent use by another instance as well as
// accidental use of the instance directory as a database.
l := flock.New(filepath.Join(dir, "LOCK"))
locked, err := l.TryLock()
if err != nil {
return nil, convertFileLockError(err, dir)
}
if !locked {
return nil, fmt.Errorf("%w: %s", ErrDirUsed, dir)
}
return &Rw{dirLock: l, Path: dir}, nil
}
func (t *Rw) Close() {
// Release instance directory lock.
if t.dirLock != nil {
if err := t.dirLock.Unlock(); err != nil {
log.Error("Can't release snapshot dir lock", "err", err)
}
t.dirLock = nil
}
}
func MustExist(path string) {
const perm = 0764 // user rwx, group rw, other r
if err := os.MkdirAll(path, perm); err != nil {
@ -78,3 +26,47 @@ func Recreate(dir string) {
}
MustExist(dir)
}
func HasFileOfType(dir, ext string) bool {
files, err := os.ReadDir(dir)
if err != nil {
return false
}
for _, f := range files {
if f.IsDir() {
continue
}
if filepath.Ext(f.Name()) == ext {
return true
}
}
return false
}
func DeleteFilesOfType(dir string, exts ...string) {
d, err := os.Open(dir)
if err != nil {
if os.IsNotExist(err) {
return
}
panic(err)
}
defer d.Close()
files, err := d.Readdir(-1)
if err != nil {
panic(err)
}
for _, file := range files {
if !file.Mode().IsRegular() {
continue
}
for _, ext := range exts {
if filepath.Ext(file.Name()) == ext {
_ = os.Remove(file.Name())
}
}
}
}