mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-16 12:16:36 +00:00
* Add GitHub Actions workflow for codespell on master * Add rudimentary codespell config * Tune codespell config: skip generated code, ignore camelCase, whitelist domain terms Add camelCase/PascalCase regex to ignore common Go/Rust/JS identifiers like allLocations, publishErr, ReadInside, FlushInterval. Also skip templ-generated *_templ.go files, and whitelist a handful of short/domain-specific words (visibles, fo, te, ser, bject, unparseable, keep-alives, tread, anc, ue) that show up as false positives across the tree. Co-Authored-By: Claude Code 2.1.217 / Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Fix ambiguous typos and protect false positives Fixes typos that codespell reports with multiple candidate suggestions (so `codespell -w` cannot auto-apply them), plus one inline pragma and one config entry to protect legitimate identifiers. Manual fixes (single correct answer chosen from context): - pattens -> patterns (5x) in filer/upload/shell flag help strings - finded -> found (2x) in tarantool storage.lua comment - spacify -> specify (2x) in helm chart values.yaml comment - wether -> whether in skiplist.go docstring - simpe -> simple in mq schema test case name False-positive protection: - Add `//codespell:ignore` next to `source GET's` (possessive of HTTP verb) in s3api_object_handlers_copy_stream.go - Whitelist `auther` in .codespellrc — it's a local variable meaning "authenticator" in weed/security/tls.go, not a typo of "author". Co-Authored-By: Claude Code 2.1.217 / Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Extend codespell ignore list: .git-meta path and thirdparty groupId Also skip `.git-meta` (scratch dir for commit messages that may contain typo words verbatim) and whitelist `thirdparty` — it appears as the literal Maven groupId `org.apache.hadoop.thirdparty` in hdfs3 poms and cannot be renamed. Co-Authored-By: Claude Code 2.1.217 / Claude Opus 4.7 (1M context) <noreply@anthropic.com> * [DATALAD RUNCMD] Fix non-ambiguous typos with codespell -w Auto-applied fixes to the 44 remaining single-suggestion typos across docs, comments, log messages, tests, config, and one Java pom. === Do not change lines below === { "chain": [], "cmd": "uvx codespell -w", "exit": 0, "extra_inputs": [], "inputs": [], "outputs": [], "pwd": "." } ^^^ Do not change lines above ^^^ * Revert breaking codespell fixes; whitelist unknwon and atleast Two of the auto-applied `codespell -w` fixes were false positives that would break the build/tests: - go.mod: `github.com/unknwon/goconfig` is a real Go module path — the upstream author's GitHub handle is literally `unknwon`. Renaming to `unknown` would fail dependency resolution. - test/benchmark/fuse_db/bin/{sqlite_verify.py,run_mysql.sh,run_sqlite.sh}: `atleast` is a literal CLI mode value (a string constant compared and passed as a positional argument). Rewriting to `at least` splits it into two arguments and breaks the mode check. Reverted those files and whitelisted both words in .codespellrc so future runs won't re-suggest the same broken fixes. Co-Authored-By: Claude Code 2.1.217 / Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Code 2.1.217 / Claude Opus 4.7 (1M context) <noreply@anthropic.com>
126 lines
4.7 KiB
Go
126 lines
4.7 KiB
Go
package command
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/glog"
|
|
"github.com/seaweedfs/seaweedfs/weed/pb"
|
|
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
|
|
"github.com/seaweedfs/seaweedfs/weed/pb/remote_pb"
|
|
"github.com/seaweedfs/seaweedfs/weed/replication/source"
|
|
"github.com/seaweedfs/seaweedfs/weed/security"
|
|
"github.com/seaweedfs/seaweedfs/weed/util"
|
|
"google.golang.org/grpc"
|
|
)
|
|
|
|
type RemoteGatewayOptions struct {
|
|
filerAddress *string
|
|
grpcDialOption grpc.DialOption
|
|
readChunkFromFiler *bool
|
|
timeAgo *time.Duration
|
|
createBucketAt *string
|
|
createBucketRandomSuffix *bool
|
|
include *string
|
|
exclude *string
|
|
|
|
mappings *remote_pb.RemoteStorageMapping
|
|
remoteConfs map[string]*remote_pb.RemoteConf
|
|
bucketsDir string
|
|
clientId int32
|
|
clientEpoch int32
|
|
}
|
|
|
|
var _ = filer_pb.FilerClient(&RemoteGatewayOptions{})
|
|
|
|
func (option *RemoteGatewayOptions) WithFilerClient(streamingMode bool, fn func(filer_pb.SeaweedFilerClient) error) error {
|
|
return pb.WithFilerClient(streamingMode, option.clientId, pb.ServerAddress(*option.filerAddress), option.grpcDialOption, func(client filer_pb.SeaweedFilerClient) error {
|
|
return fn(client)
|
|
})
|
|
}
|
|
func (option *RemoteGatewayOptions) AdjustedUrl(location *filer_pb.Location) string {
|
|
return location.Url
|
|
}
|
|
|
|
func (option *RemoteGatewayOptions) GetDataCenter() string {
|
|
return ""
|
|
}
|
|
|
|
var (
|
|
remoteGatewayOptions RemoteGatewayOptions
|
|
)
|
|
|
|
func init() {
|
|
cmdFilerRemoteGateway.Run = runFilerRemoteGateway // break init cycle
|
|
remoteGatewayOptions.filerAddress = cmdFilerRemoteGateway.Flag.String("filer", "localhost:8888", "filer of the SeaweedFS cluster")
|
|
remoteGatewayOptions.createBucketAt = cmdFilerRemoteGateway.Flag.String("createBucketAt", "", "one remote storage name to create new buckets in")
|
|
remoteGatewayOptions.createBucketRandomSuffix = cmdFilerRemoteGateway.Flag.Bool("createBucketWithRandomSuffix", true, "add randomized suffix to bucket name to avoid conflicts")
|
|
remoteGatewayOptions.readChunkFromFiler = cmdFilerRemoteGateway.Flag.Bool("filerProxy", false, "read file chunks from filer instead of volume servers")
|
|
remoteGatewayOptions.timeAgo = cmdFilerRemoteGateway.Flag.Duration("timeAgo", 0, "start time before now. \"300ms\", \"1.5h\" or \"2h45m\". Valid time units are \"ns\", \"us\" (or \"µs\"), \"ms\", \"s\", \"m\", \"h\"")
|
|
remoteGatewayOptions.include = cmdFilerRemoteGateway.Flag.String("include", "", "patterns of new bucket names, e.g., s3*")
|
|
remoteGatewayOptions.exclude = cmdFilerRemoteGateway.Flag.String("exclude", "", "patterns of new bucket names, e.g., local*")
|
|
remoteGatewayOptions.clientId = util.RandomInt32()
|
|
}
|
|
|
|
var cmdFilerRemoteGateway = &Command{
|
|
UsageLine: "filer.remote.gateway",
|
|
Short: "resumable continuously write back bucket creation, deletion, and other local updates to remote object store",
|
|
Long: `resumable continuously write back bucket creation, deletion, and other local updates to remote object store
|
|
|
|
filer.remote.gateway listens on filer local buckets update events.
|
|
If any bucket is created, deleted, or updated, it will mirror the changes to remote object store.
|
|
|
|
weed filer.remote.gateway -createBucketAt=cloud1
|
|
|
|
`,
|
|
}
|
|
|
|
func runFilerRemoteGateway(cmd *Command, args []string) bool {
|
|
|
|
util.LoadSecurityConfiguration()
|
|
grpcDialOption := security.LoadClientTLS(util.GetViper(), "grpc.client")
|
|
remoteGatewayOptions.grpcDialOption = grpcDialOption
|
|
|
|
filerAddress := pb.ServerAddress(*remoteGatewayOptions.filerAddress)
|
|
|
|
filerSource := &source.FilerSource{}
|
|
filerSource.DoInitialize(
|
|
filerAddress.ToHttpAddress(),
|
|
filerAddress.ToGrpcAddress(),
|
|
"/", // does not matter
|
|
*remoteGatewayOptions.readChunkFromFiler,
|
|
)
|
|
|
|
remoteGatewayOptions.bucketsDir = "/buckets"
|
|
// check buckets again
|
|
remoteGatewayOptions.WithFilerClient(false, func(filerClient filer_pb.SeaweedFilerClient) error {
|
|
resp, err := filerClient.GetFilerConfiguration(context.Background(), &filer_pb.GetFilerConfigurationRequest{})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
remoteGatewayOptions.bucketsDir = resp.DirBuckets
|
|
return nil
|
|
})
|
|
|
|
// read filer remote storage mount mappings
|
|
if detectErr := remoteGatewayOptions.collectRemoteStorageConf(); detectErr != nil {
|
|
fmt.Fprintf(os.Stderr, "read mount info: %v\n", detectErr)
|
|
return true
|
|
}
|
|
|
|
// synchronize /buckets folder
|
|
fmt.Printf("synchronize buckets in %s ...\n", remoteGatewayOptions.bucketsDir)
|
|
util.RetryUntil("filer.remote.sync buckets", func() error {
|
|
return remoteGatewayOptions.followBucketUpdatesAndUploadToRemote(filerSource)
|
|
}, func(err error) bool {
|
|
if err != nil {
|
|
glog.Errorf("synchronize %s: %v", remoteGatewayOptions.bucketsDir, err)
|
|
}
|
|
return true
|
|
})
|
|
return true
|
|
|
|
}
|