mirror of
https://github.com/versity/versitygw.git
synced 2026-09-22 16:04:15 +00:00
Replace the hardcoded 0644 defaultFilePerm with a NewFilePerm option on the posix and scoutfs backends, exposed as the --file-perms flag and VGW_FILE_PERMS env var alongside the existing dir-perms option. The mode passed to open() is masked by the process umask, so the O_TMPFILE path now chmods explicitly to match the CreateTemp fallback path and give new objects the configured mode regardless of umask.
175 lines
5.6 KiB
Go
175 lines
5.6 KiB
Go
// Copyright 2023 Versity Software
|
|
// This file is licensed under the Apache License, Version 2.0
|
|
// (the "License"); you may not use this file except in compliance
|
|
// with the License. You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing,
|
|
// software distributed under the License is distributed on an
|
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
// KIND, either express or implied. See the License for the
|
|
// specific language governing permissions and limitations
|
|
// under the License.
|
|
|
|
package gwcli
|
|
|
|
import (
|
|
"fmt"
|
|
"io/fs"
|
|
"math"
|
|
|
|
"github.com/urfave/cli/v2"
|
|
"github.com/versity/versitygw/backend/scoutfs"
|
|
)
|
|
|
|
var (
|
|
glacier bool
|
|
disableNoArchive bool
|
|
setProjectID bool
|
|
)
|
|
|
|
// ScoutfsCommand returns the "scoutfs" subcommand, common to all versitygw
|
|
// binaries.
|
|
func ScoutfsCommand() *cli.Command {
|
|
return &cli.Command{
|
|
Name: "scoutfs",
|
|
Usage: "scoutfs filesystem storage backend",
|
|
Description: `Support for ScoutFS.
|
|
The top level directory for the gateway must be provided. All sub directories
|
|
of the top level directory are treated as buckets, and all files/directories
|
|
below the "bucket directory" are treated as the objects. The object name is
|
|
split on "/" separator to translate to posix storage.
|
|
For example:
|
|
top level: /mnt/fs/gwroot
|
|
bucket: mybucket
|
|
object: a/b/c/myobject
|
|
will be translated into the file /mnt/fs/gwroot/mybucket/a/b/c/myobject
|
|
|
|
ScoutFS contains optimizations for multipart uploads using extent
|
|
move interfaces as well as support for tiered filesystems.`,
|
|
Action: runScoutfs,
|
|
Flags: []cli.Flag{
|
|
&cli.BoolFlag{
|
|
Name: "glacier",
|
|
Usage: "enable glacier emulation mode",
|
|
Aliases: []string{"g"},
|
|
EnvVars: []string{"VGW_SCOUTFS_GLACIER"},
|
|
Destination: &glacier,
|
|
},
|
|
&cli.BoolFlag{
|
|
Name: "chuid",
|
|
Usage: "chown newly created files and directories to client account UID",
|
|
EnvVars: []string{"VGW_CHOWN_UID"},
|
|
Destination: &chownuid,
|
|
},
|
|
&cli.BoolFlag{
|
|
Name: "chgid",
|
|
Usage: "chown newly created files and directories to client account GID",
|
|
EnvVars: []string{"VGW_CHOWN_GID"},
|
|
Destination: &chowngid,
|
|
},
|
|
&cli.BoolFlag{
|
|
Name: "projectid",
|
|
Usage: "set project id on newly created buckets, files, and directories to client account ProjectID",
|
|
EnvVars: []string{"VGW_SET_PROJECT_ID"},
|
|
Destination: &setProjectID,
|
|
},
|
|
&cli.BoolFlag{
|
|
Name: "bucketlinks",
|
|
Usage: "allow symlinked directories at bucket level to be treated as buckets",
|
|
EnvVars: []string{"VGW_BUCKET_LINKS"},
|
|
Destination: &bucketlinks,
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "versioning-dir",
|
|
Usage: "the directory path to enable bucket versioning",
|
|
EnvVars: []string{"VGW_VERSIONING_DIR"},
|
|
Destination: &versioningDir,
|
|
},
|
|
&cli.UintFlag{
|
|
Name: "dir-perms",
|
|
Usage: "default directory permissions for new directories",
|
|
EnvVars: []string{"VGW_DIR_PERMS"},
|
|
Destination: &dirPerms,
|
|
DefaultText: "0755",
|
|
Value: 0755,
|
|
},
|
|
&cli.UintFlag{
|
|
Name: "file-perms",
|
|
Usage: "default file permissions for new objects",
|
|
EnvVars: []string{"VGW_FILE_PERMS"},
|
|
Destination: &filePerms,
|
|
DefaultText: "0644",
|
|
Value: 0644,
|
|
},
|
|
&cli.BoolFlag{
|
|
Name: "disable-noarchive",
|
|
Usage: "disable setting noarchive for multipart part uploads",
|
|
EnvVars: []string{"VGW_DISABLE_NOARCHIVE"},
|
|
Destination: &disableNoArchive,
|
|
},
|
|
&cli.IntFlag{
|
|
Name: "concurrency",
|
|
Usage: "maximum concurrent actions allowed",
|
|
EnvVars: []string{"VGW_POSIX_CONCURRENCY"},
|
|
Value: 5000,
|
|
Destination: &actionsConcurrency,
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "default-etag",
|
|
Usage: "default ETag value returned for objects that do not have a stored etag attribute (e.g. files placed on the filesystem outside of versitygw)",
|
|
EnvVars: []string{"VGW_DEFAULT_ETAG"},
|
|
Destination: &defaultEtag,
|
|
},
|
|
&cli.BoolFlag{
|
|
Name: "data-integrity-etag",
|
|
Usage: "use data-integrity checksum-derived ETags instead of MD5-based ETags (PUT object ETag, multipart part ETags, and completed multipart object ETag)",
|
|
EnvVars: []string{"VGW_DATA_INTEGRITY_ETAG"},
|
|
Destination: &dataIntegrityEtag,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func runScoutfs(ctx *cli.Context) error {
|
|
if ctx.NArg() == 0 {
|
|
return fmt.Errorf("no directory provided for operation")
|
|
}
|
|
|
|
if dirPerms > math.MaxUint32 {
|
|
return fmt.Errorf("invalid directory permissions: %d", dirPerms)
|
|
}
|
|
|
|
if filePerms > maxFilePerms {
|
|
return fmt.Errorf("invalid file permissions: %o, must be within 0000-0777", filePerms)
|
|
}
|
|
|
|
if actionsConcurrency <= 0 {
|
|
return fmt.Errorf("concurrency must be positive, got %d", actionsConcurrency)
|
|
}
|
|
|
|
var opts scoutfs.ScoutfsOpts
|
|
opts.GlacierMode = glacier
|
|
opts.ChownUID = chownuid
|
|
opts.ChownGID = chowngid
|
|
opts.BucketLinks = bucketlinks
|
|
opts.DisableNoArchive = disableNoArchive
|
|
opts.VersioningDir = versioningDir
|
|
opts.ValidateBucketNames = DisableStrictBucketNames
|
|
opts.SetProjectID = setProjectID
|
|
opts.Concurrency = actionsConcurrency
|
|
opts.CopyObjectThreshold = CopyObjectThreshold
|
|
opts.DefaultEtag = defaultEtag
|
|
opts.DataIntegrityEtag = dataIntegrityEtag
|
|
opts.SetNewDirPerm(fs.FileMode(dirPerms))
|
|
opts.SetNewFilePerm(fs.FileMode(filePerms))
|
|
|
|
be, err := scoutfs.New(ctx.Args().Get(0), opts)
|
|
if err != nil {
|
|
return fmt.Errorf("init scoutfs: %v", err)
|
|
}
|
|
|
|
return RunGateway(ctx.Context, be)
|
|
}
|