mirror of
https://github.com/versity/versitygw.git
synced 2025-12-23 05:05:16 +00:00
feat: return method not allowed when uploading to read only fs
Instead of an internal server error, we should be returning method not allowed when trying to upload to a read only filesystem or make other modifications that are expected to fail. This will give clearer feedback to the clients that this is not expected to work. Fixes #1062
This commit is contained in:
@@ -23,6 +23,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/pkg/xattr"
|
"github.com/pkg/xattr"
|
||||||
|
"github.com/versity/versitygw/s3err"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -56,10 +57,18 @@ func (x XattrMeta) RetrieveAttribute(f *os.File, bucket, object, attribute strin
|
|||||||
// StoreAttribute stores the value of a specific attribute for an object in a bucket.
|
// StoreAttribute stores the value of a specific attribute for an object in a bucket.
|
||||||
func (x XattrMeta) StoreAttribute(f *os.File, bucket, object, attribute string, value []byte) error {
|
func (x XattrMeta) StoreAttribute(f *os.File, bucket, object, attribute string, value []byte) error {
|
||||||
if f != nil {
|
if f != nil {
|
||||||
return xattr.FSet(f, xattrPrefix+attribute, value)
|
err := xattr.FSet(f, xattrPrefix+attribute, value)
|
||||||
|
if errors.Is(err, syscall.EROFS) {
|
||||||
|
return s3err.GetAPIError(s3err.ErrMethodNotAllowed)
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return xattr.Set(filepath.Join(bucket, object), xattrPrefix+attribute, value)
|
err := xattr.Set(filepath.Join(bucket, object), xattrPrefix+attribute, value)
|
||||||
|
if errors.Is(err, syscall.EROFS) {
|
||||||
|
return s3err.GetAPIError(s3err.ErrMethodNotAllowed)
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteAttribute removes the value of a specific attribute for an object in a bucket.
|
// DeleteAttribute removes the value of a specific attribute for an object in a bucket.
|
||||||
@@ -68,6 +77,9 @@ func (x XattrMeta) DeleteAttribute(bucket, object, attribute string) error {
|
|||||||
if errors.Is(err, xattr.ENOATTR) {
|
if errors.Is(err, xattr.ENOATTR) {
|
||||||
return ErrNoSuchKey
|
return ErrNoSuchKey
|
||||||
}
|
}
|
||||||
|
if errors.Is(err, syscall.EROFS) {
|
||||||
|
return s3err.GetAPIError(s3err.ErrMethodNotAllowed)
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -362,6 +362,9 @@ func (p *Posix) CreateBucket(ctx context.Context, input *s3.CreateBucketInput, a
|
|||||||
return s3err.GetAPIError(s3err.ErrBucketAlreadyExists)
|
return s3err.GetAPIError(s3err.ErrBucketAlreadyExists)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errors.Is(err, syscall.EROFS) {
|
||||||
|
return s3err.GetAPIError(s3err.ErrMethodNotAllowed)
|
||||||
|
}
|
||||||
return fmt.Errorf("mkdir bucket: %w", err)
|
return fmt.Errorf("mkdir bucket: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import (
|
|||||||
|
|
||||||
"github.com/versity/versitygw/auth"
|
"github.com/versity/versitygw/auth"
|
||||||
"github.com/versity/versitygw/backend"
|
"github.com/versity/versitygw/backend"
|
||||||
|
"github.com/versity/versitygw/s3err"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -62,6 +63,10 @@ func (p *Posix) openTmpFile(dir, bucket, obj string, size int64, acct auth.Accou
|
|||||||
// this is not supported.
|
// this is not supported.
|
||||||
fd, err := unix.Open(dir, unix.O_RDWR|unix.O_TMPFILE|unix.O_CLOEXEC, defaultFilePerm)
|
fd, err := unix.Open(dir, unix.O_RDWR|unix.O_TMPFILE|unix.O_CLOEXEC, defaultFilePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errors.Is(err, syscall.EROFS) {
|
||||||
|
return nil, s3err.GetAPIError(s3err.ErrMethodNotAllowed)
|
||||||
|
}
|
||||||
|
|
||||||
// O_TMPFILE not supported, try fallback
|
// O_TMPFILE not supported, try fallback
|
||||||
err = backend.MkdirAll(dir, uid, gid, doChown, p.newDirPerm)
|
err = backend.MkdirAll(dir, uid, gid, doChown, p.newDirPerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -24,9 +24,11 @@ import (
|
|||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/versity/versitygw/auth"
|
"github.com/versity/versitygw/auth"
|
||||||
"github.com/versity/versitygw/backend"
|
"github.com/versity/versitygw/backend"
|
||||||
|
"github.com/versity/versitygw/s3err"
|
||||||
)
|
)
|
||||||
|
|
||||||
type tmpfile struct {
|
type tmpfile struct {
|
||||||
@@ -43,11 +45,17 @@ func (p *Posix) openTmpFile(dir, bucket, obj string, size int64, acct auth.Accou
|
|||||||
var err error
|
var err error
|
||||||
err = backend.MkdirAll(dir, uid, gid, doChown, p.newDirPerm)
|
err = backend.MkdirAll(dir, uid, gid, doChown, p.newDirPerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errors.Is(err, syscall.EROFS) {
|
||||||
|
return nil, s3err.GetAPIError(s3err.ErrMethodNotAllowed)
|
||||||
|
}
|
||||||
return nil, fmt.Errorf("make temp dir: %w", err)
|
return nil, fmt.Errorf("make temp dir: %w", err)
|
||||||
}
|
}
|
||||||
f, err := os.CreateTemp(dir,
|
f, err := os.CreateTemp(dir,
|
||||||
fmt.Sprintf("%x.", sha256.Sum256([]byte(obj))))
|
fmt.Sprintf("%x.", sha256.Sum256([]byte(obj))))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errors.Is(err, syscall.EROFS) {
|
||||||
|
return nil, s3err.GetAPIError(s3err.ErrMethodNotAllowed)
|
||||||
|
}
|
||||||
return nil, fmt.Errorf("create temp file: %w", err)
|
return nil, fmt.Errorf("create temp file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user