mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-01 20:26:27 +00:00
Compare commits
231
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33ecc8442e | ||
|
|
81aeec74a4 | ||
|
|
60f11f6510 | ||
|
|
61c4f01e05 | ||
|
|
ce51d60127 | ||
|
|
a489d99333 | ||
|
|
00c621abb8 | ||
|
|
c99530ec66 | ||
|
|
7439af0eca | ||
|
|
cc135c63f7 | ||
|
|
c4695fc3b3 | ||
|
|
bed0a64693 | ||
|
|
d8ddc22fc2 | ||
|
|
35f0daa198 | ||
|
|
2f3de5e199 | ||
|
|
bd4891a117 | ||
|
|
7039d5003c | ||
|
|
7151a54b28 | ||
|
|
b25561d0d7 | ||
|
|
9994617dad | ||
|
|
7265a9c3b7 | ||
|
|
4217f0dcaf | ||
|
|
aeb3bcdfc1 | ||
|
|
2c494751e5 | ||
|
|
d40746f34e | ||
|
|
7204731749 | ||
|
|
5e354a18a3 | ||
|
|
90802cb201 | ||
|
|
ee0c14673d | ||
|
|
9ffc8bcb54 | ||
|
|
283d9e0079 | ||
|
|
62aaaa18f3 | ||
|
|
2786bea839 | ||
|
|
6677f1f563 | ||
|
|
c1c09b60a1 | ||
|
|
aa5b927a18 | ||
|
|
2d77c15569 | ||
|
|
dd5a24fb89 | ||
|
|
a907e71a96 | ||
|
|
27a392f706 | ||
|
|
ea70d17c5f | ||
|
|
2e1506c31e | ||
|
|
f1181f1121 | ||
|
|
f3d44b1eb6 | ||
|
|
896096c41b | ||
|
|
25d6310307 | ||
|
|
874b4a5535 | ||
|
|
165af32d6b | ||
|
|
5182d46e22 | ||
|
|
140b7a7402 | ||
|
|
c25e455111 | ||
|
|
01306b66ba | ||
|
|
31660aa8e8 | ||
|
|
0cc965737b | ||
|
|
6fd752445e | ||
|
|
372547e332 | ||
|
|
ff878a542d | ||
|
|
d8c574a5ef | ||
|
|
0be020b0fa | ||
|
|
ba1d82db90 | ||
|
|
b0f7c33ce0 | ||
|
|
c993a43a91 | ||
|
|
6eaa35040b | ||
|
|
8da3079d22 | ||
|
|
45964c2f86 | ||
|
|
9c1048bacb | ||
|
|
dddb0f0ae5 | ||
|
|
d8cc269294 | ||
|
|
848d1f7c34 | ||
|
|
2ae5b480a6 | ||
|
|
97dad06ed8 | ||
|
|
582206b7d2 | ||
|
|
7522f11fd7 | ||
|
|
3c15c8ddad | ||
|
|
93aed187e9 | ||
|
|
a2c5510ae1 | ||
|
|
a2473af05a | ||
|
|
51b0f9b7fd | ||
|
|
5aff086aa4 | ||
|
|
e4e8505208 | ||
|
|
ed15357c7a | ||
|
|
21514e1fea | ||
|
|
4e7948abd2 | ||
|
|
b45f43ded1 | ||
|
|
f14de131b3 | ||
|
|
d424cbbcd5 | ||
|
|
71382d3279 | ||
|
|
0fbdedecc7 | ||
|
|
affacb1b67 | ||
|
|
9f4be83e88 | ||
|
|
8d0e6f1ead | ||
|
|
c8b0a04409 | ||
|
|
ea941462f9 | ||
|
|
8c1cb203fa | ||
|
|
cea34dc21a | ||
|
|
df6f230681 | ||
|
|
7a97bea3c0 | ||
|
|
23fe412ee3 | ||
|
|
ae73bc9685 | ||
|
|
396a602f86 | ||
|
|
2e0e5c09cd | ||
|
|
ad138a0c0e | ||
|
|
999ca04e64 | ||
|
|
183ab487c6 | ||
|
|
aa9121aa9d | ||
|
|
4dca59ed27 | ||
|
|
cc67a0370c | ||
|
|
43ffbfe608 | ||
|
|
b10791f8a0 | ||
|
|
55501bb51c | ||
|
|
0e08b83521 | ||
|
|
216c52e377 | ||
|
|
1af0b282db | ||
|
|
9d482a8da9 | ||
|
|
43019b4fdb | ||
|
|
da4a63cf61 | ||
|
|
ba3afd1803 | ||
|
|
528702d30b | ||
|
|
46b3a71a1f | ||
|
|
669a3917af | ||
|
|
9d8b975ff9 | ||
|
|
138b66231a | ||
|
|
4a37ea443e | ||
|
|
1c0a057af8 | ||
|
|
bb32bb3053 | ||
|
|
c9faddf799 | ||
|
|
95746f48e6 | ||
|
|
cbf4ae76a2 | ||
|
|
f88f7e7074 | ||
|
|
be2b389b81 | ||
|
|
43c3e80970 | ||
|
|
8fc63361f2 | ||
|
|
db759a1ad1 | ||
|
|
4ad669b2aa | ||
|
|
f99a818ad2 | ||
|
|
94bd8b39cf | ||
|
|
cb33ee006e | ||
|
|
e60aa71890 | ||
|
|
7244a3d047 | ||
|
|
75ef324533 | ||
|
|
5ab04e1baf | ||
|
|
04c820594d | ||
|
|
b615499cf0 | ||
|
|
23709cc781 | ||
|
|
feffdd9302 | ||
|
|
ffe6d928e3 | ||
|
|
1d89d20798 | ||
|
|
7766e9729f | ||
|
|
c45b8bd6ac | ||
|
|
537b3a8618 | ||
|
|
f7f6e1158e | ||
|
|
5e43af8a91 | ||
|
|
aedb4d9f28 | ||
|
|
20d7e44fc8 | ||
|
|
6f3718ddaa | ||
|
|
faaecf92c9 | ||
|
|
02773a6107 | ||
|
|
14cb8a24c6 | ||
|
|
271505717e | ||
|
|
61249d8dde | ||
|
|
533b675ec8 | ||
|
|
3ed52662df | ||
|
|
2259662c7b | ||
|
|
91a9631904 | ||
|
|
d3221099bf | ||
|
|
0e79bbaf36 | ||
|
|
fb41d03a11 | ||
|
|
2adafe366d | ||
|
|
d0eff7b818 | ||
|
|
941794f640 | ||
|
|
d7dcfd515b | ||
|
|
74ce59f6b0 | ||
|
|
3ee4d6e69e | ||
|
|
c07596691c | ||
|
|
76a111f0a2 | ||
|
|
314f211260 | ||
|
|
9bd4c47299 | ||
|
|
4613186e8a | ||
|
|
476aabb04b | ||
|
|
df436d342b | ||
|
|
65b0a7cf83 | ||
|
|
b977e0b3b2 | ||
|
|
2dc26a064c | ||
|
|
e6c4fc2550 | ||
|
|
e4c946229a | ||
|
|
1fbd2902e8 | ||
|
|
15926cf626 | ||
|
|
f9401d34dd | ||
|
|
ef4eda0761 | ||
|
|
be74548cb5 | ||
|
|
299e372b48 | ||
|
|
60c9a7496d | ||
|
|
0833d119c3 | ||
|
|
41f5cc69b4 | ||
|
|
ddd67dd191 | ||
|
|
b78a897f14 | ||
|
|
7d7e06681d | ||
|
|
7fa0e78abd | ||
|
|
82888da4e9 | ||
|
|
1fea3f1072 | ||
|
|
94c3de8273 | ||
|
|
7392161894 | ||
|
|
c2b8942769 | ||
|
|
441614b386 | ||
|
|
903d288e08 | ||
|
|
485c881c10 | ||
|
|
9604db2c93 | ||
|
|
392656d59e | ||
|
|
de66c82252 | ||
|
|
239bef5677 | ||
|
|
de61e21654 | ||
|
|
3220c0de15 | ||
|
|
bad0c61154 | ||
|
|
b4fd5f71c0 | ||
|
|
e369fe5c72 | ||
|
|
9ca2b0b763 | ||
|
|
a7b964af96 | ||
|
|
e8d8bfcccc | ||
|
|
8eab76c5db | ||
|
|
9ebc132ffc | ||
|
|
29c2d9b965 | ||
|
|
a250699225 | ||
|
|
68f547bdf2 | ||
|
|
5e46960651 | ||
|
|
95d8f4415a | ||
|
|
7fd42f5d06 | ||
|
|
8f45e4589c | ||
|
|
c105f5a1b8 | ||
|
|
fc649018b0 | ||
|
|
bc5aadd8af | ||
|
|
568c0e4a6e |
@@ -53,7 +53,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed-large-disk
|
||||
@@ -68,7 +68,7 @@ jobs:
|
||||
release_tag: dev
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed-normal-disk
|
||||
@@ -102,7 +102,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed-large-disk
|
||||
@@ -117,7 +117,7 @@ jobs:
|
||||
release_tag: dev
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed-normal-disk
|
||||
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
# build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
# build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
# build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
# build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
|
||||
@@ -36,10 +36,10 @@ jobs:
|
||||
goos: ${{ matrix.goos }}
|
||||
goarch: ${{ matrix.goarch }}
|
||||
overwrite: true
|
||||
build_flags: -tags elastic,gocdk,rclone,sqlite,tikv,ydb
|
||||
build_flags: -tags elastic,gocdk,rclone,sqlite,tarantool,tikv,ydb
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
# build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
@@ -52,8 +52,8 @@ jobs:
|
||||
goarch: ${{ matrix.goarch }}
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
build_flags: -tags 5BytesOffset,elastic,gocdk,rclone,sqlite,tikv,ydb
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
build_flags: -tags 5BytesOffset,elastic,gocdk,rclone,sqlite,tarantool,tikv,ydb
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
# build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
overwrite: true
|
||||
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
|
||||
build_flags: -tags 5BytesOffset # optional, default is
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||
ldflags: -s -w -extldflags -static -X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=${{github.sha}}
|
||||
# Where to run `go build .`
|
||||
project_path: weed
|
||||
binary_name: weed
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
-
|
||||
name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v3
|
||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v3
|
||||
with:
|
||||
images: |
|
||||
chrislusf/seaweedfs
|
||||
@@ -33,30 +33,30 @@ jobs:
|
||||
org.opencontainers.image.vendor=Chris Lu
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v1
|
||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v1
|
||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v1
|
||||
with:
|
||||
buildkitd-flags: "--debug"
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v1
|
||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Login to GHCR
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v1
|
||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.GHCR_USERNAME }}
|
||||
password: ${{ secrets.GHCR_TOKEN }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v2
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v2
|
||||
with:
|
||||
context: ./docker
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
-
|
||||
name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v3
|
||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v3
|
||||
with:
|
||||
images: |
|
||||
chrislusf/seaweedfs
|
||||
@@ -34,30 +34,30 @@ jobs:
|
||||
org.opencontainers.image.vendor=Chris Lu
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v1
|
||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v1
|
||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v1
|
||||
with:
|
||||
buildkitd-flags: "--debug"
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v1
|
||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Login to GHCR
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v1
|
||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.GHCR_USERNAME }}
|
||||
password: ${{ secrets.GHCR_TOKEN }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v2
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v2
|
||||
with:
|
||||
context: ./docker
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
-
|
||||
name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v3
|
||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v3
|
||||
with:
|
||||
images: |
|
||||
chrislusf/seaweedfs
|
||||
@@ -34,20 +34,20 @@ jobs:
|
||||
org.opencontainers.image.vendor=Chris Lu
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v1
|
||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v1
|
||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v1
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v1
|
||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v2
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v2
|
||||
with:
|
||||
context: ./docker
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
-
|
||||
name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v3
|
||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v3
|
||||
with:
|
||||
images: |
|
||||
chrislusf/seaweedfs
|
||||
@@ -35,20 +35,20 @@ jobs:
|
||||
org.opencontainers.image.vendor=Chris Lu
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v1
|
||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v1
|
||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v1
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v1
|
||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v2
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v2
|
||||
with:
|
||||
context: ./docker
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
-
|
||||
name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v3
|
||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v3
|
||||
with:
|
||||
images: |
|
||||
chrislusf/seaweedfs
|
||||
@@ -35,20 +35,20 @@ jobs:
|
||||
org.opencontainers.image.vendor=Chris Lu
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v1
|
||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v1
|
||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v1
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v1
|
||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v2
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v2
|
||||
with:
|
||||
context: ./docker
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
-
|
||||
name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v3
|
||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v3
|
||||
with:
|
||||
images: |
|
||||
chrislusf/seaweedfs
|
||||
@@ -34,25 +34,25 @@ jobs:
|
||||
org.opencontainers.image.vendor=Chris Lu
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v1
|
||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v1
|
||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v1
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v1
|
||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v2
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v2
|
||||
with:
|
||||
context: ./docker
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
file: ./docker/Dockerfile.go_build
|
||||
build-args: TAGS=elastic,gocdk,rclone,sqlite,tikv,ydb
|
||||
build-args: TAGS=elastic,gocdk,rclone,sqlite,tarantool,tikv,ydb
|
||||
platforms: linux/amd64
|
||||
tags: ${{ steps.docker_meta.outputs.tags }}
|
||||
labels: ${{ steps.docker_meta.outputs.labels }}
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
-
|
||||
name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v3
|
||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v3
|
||||
with:
|
||||
images: |
|
||||
chrislusf/seaweedfs
|
||||
@@ -34,25 +34,25 @@ jobs:
|
||||
org.opencontainers.image.vendor=Chris Lu
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v1
|
||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v1
|
||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v1
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v1
|
||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v2
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v2
|
||||
with:
|
||||
context: ./docker
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
file: ./docker/Dockerfile.go_build
|
||||
build-args: TAGS=5BytesOffset,elastic,gocdk,rclone,sqlite,tikv,ydb
|
||||
build-args: TAGS=5BytesOffset,elastic,gocdk,rclone,sqlite,tarantool,tikv,ydb
|
||||
platforms: linux/amd64
|
||||
tags: ${{ steps.docker_meta.outputs.tags }}
|
||||
labels: ${{ steps.docker_meta.outputs.labels }}
|
||||
|
||||
@@ -11,4 +11,4 @@ jobs:
|
||||
- name: 'Checkout Repository'
|
||||
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
|
||||
- name: 'Dependency Review'
|
||||
uses: actions/dependency-review-action@0659a74c94536054bfa5aeb92241f70d680cc78e
|
||||
uses: actions/dependency-review-action@da24556b548a50705dd671f47852072ea4c105d9
|
||||
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
cd weed; go get -v -t -d ./...
|
||||
|
||||
- name: Build
|
||||
run: cd weed; go build -tags "elastic gocdk sqlite ydb tikv rclone" -v .
|
||||
run: cd weed; go build -tags "elastic gocdk sqlite ydb tarantool tikv rclone" -v .
|
||||
|
||||
- name: Test
|
||||
run: cd weed; go test -tags "elastic gocdk sqlite ydb tikv rclone" -v ./...
|
||||
run: cd weed; go test -tags "elastic gocdk sqlite ydb tarantool tikv rclone" -v ./...
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
name: "test s3 over https using aws-cli"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master, test-https-s3-awscli]
|
||||
pull_request:
|
||||
branches: [master, test-https-s3-awscli]
|
||||
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: some_access_key1
|
||||
AWS_SECRET_ACCESS_KEY: some_secret_key1
|
||||
AWS_ENDPOINT_URL: https://localhost:8443
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: weed
|
||||
|
||||
jobs:
|
||||
awscli-tests:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ^1.24
|
||||
|
||||
- name: Build SeaweedFS
|
||||
run: |
|
||||
go build
|
||||
|
||||
- name: Start SeaweedFS
|
||||
run: |
|
||||
set -e
|
||||
mkdir -p /tmp/data
|
||||
./weed server -s3 -dir=/tmp/data -s3.config=../docker/compose/s3.json &
|
||||
until curl -s http://localhost:8333/ > /dev/null; do sleep 1; done
|
||||
|
||||
- name: Setup Caddy
|
||||
run: |
|
||||
curl -fsSL "https://caddyserver.com/api/download?os=linux&arch=amd64" -o caddy
|
||||
chmod +x caddy
|
||||
./caddy version
|
||||
echo "{
|
||||
auto_https disable_redirects
|
||||
local_certs
|
||||
}
|
||||
localhost:8443 {
|
||||
tls internal
|
||||
reverse_proxy localhost:8333
|
||||
}" > Caddyfile
|
||||
|
||||
- name: Start Caddy
|
||||
run: |
|
||||
./caddy start
|
||||
until curl -fsS --insecure https://localhost:8443 > /dev/null; do sleep 1; done
|
||||
|
||||
- name: Create Bucket
|
||||
run: |
|
||||
aws --no-verify-ssl s3api create-bucket --bucket bucket
|
||||
|
||||
- name: Test PutObject
|
||||
run: |
|
||||
set -e
|
||||
dd if=/dev/urandom of=generated bs=1M count=2
|
||||
aws --no-verify-ssl s3api put-object --bucket bucket --key test-putobject --body generated
|
||||
aws --no-verify-ssl s3api get-object --bucket bucket --key test-putobject downloaded
|
||||
diff -q generated downloaded
|
||||
rm -f generated downloaded
|
||||
|
||||
- name: Test Multi-part Upload
|
||||
run: |
|
||||
set -e
|
||||
dd if=/dev/urandom of=generated bs=1M count=32
|
||||
aws --no-verify-ssl s3 cp --no-progress generated s3://bucket/test-multipart
|
||||
aws --no-verify-ssl s3 cp --no-progress s3://bucket/test-multipart downloaded
|
||||
diff -q generated downloaded
|
||||
rm -f generated downloaded
|
||||
+1
-5
@@ -87,7 +87,6 @@ other/java/hdfs/dependency-reduced-pom.xml
|
||||
|
||||
# binary file
|
||||
weed/weed
|
||||
weed/mq/client/cmd/weed_pub_kv/weed_pub
|
||||
docker/weed
|
||||
|
||||
# test generated files
|
||||
@@ -95,7 +94,4 @@ weed/*/*.jpg
|
||||
docker/weed_sub
|
||||
docker/weed_pub
|
||||
weed/mq/schema/example.parquet
|
||||
docker/weed_pub_kv
|
||||
docker/weed_pub_record
|
||||
docker/weed_sub_kv
|
||||
docker/weed_sub_record
|
||||
docker/agent_sub_record
|
||||
|
||||
@@ -14,7 +14,7 @@ warp_install:
|
||||
go install github.com/minio/warp@v0.7.6
|
||||
|
||||
full_install:
|
||||
cd weed; go install -tags "elastic gocdk sqlite ydb tikv rclone"
|
||||
cd weed; go install -tags "elastic gocdk sqlite ydb tarantool tikv rclone"
|
||||
|
||||
server: install
|
||||
weed -v 0 server -s3 -filer -filer.maxMB=64 -volume.max=0 -master.volumeSizeLimitMB=1024 -volume.preStopSeconds=1 -s3.port=8000 -s3.allowEmptyFolder=false -s3.allowDeleteBucketNotEmpty=true -s3.config=./docker/compose/s3.json -metricsPort=9324
|
||||
@@ -34,4 +34,4 @@ benchmark_with_pprof: debug = 1
|
||||
benchmark_with_pprof: benchmark
|
||||
|
||||
test:
|
||||
cd weed; go test -tags "elastic gocdk sqlite ydb tikv rclone" -v ./...
|
||||
cd weed; go test -tags "elastic gocdk sqlite ydb tarantool tikv rclone" -v ./...
|
||||
|
||||
@@ -46,6 +46,7 @@ Your support will be really appreciated by me and other supporters!
|
||||
- [SeaweedFS Mailing List](https://groups.google.com/d/forum/seaweedfs)
|
||||
- [Wiki Documentation](https://github.com/seaweedfs/seaweedfs/wiki)
|
||||
- [SeaweedFS White Paper](https://github.com/seaweedfs/seaweedfs/wiki/SeaweedFS_Architecture.pdf)
|
||||
- [SeaweedFS Introduction Slides 2025.5](https://docs.google.com/presentation/d/1tdkp45J01oRV68dIm4yoTXKJDof-EhainlA0LMXexQE/edit?usp=sharing)
|
||||
- [SeaweedFS Introduction Slides 2021.5](https://docs.google.com/presentation/d/1DcxKWlINc-HNCjhYeERkpGXXm6nTCES8mi2W5G0Z4Ts/edit?usp=sharing)
|
||||
- [SeaweedFS Introduction Slides 2019.3](https://www.slideshare.net/chrislusf/seaweedfs-introduction)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.22-alpine as builder
|
||||
FROM golang:1.24-alpine as builder
|
||||
RUN apk add git g++ fuse
|
||||
RUN mkdir -p /go/src/github.com/seaweedfs/
|
||||
RUN git clone https://github.com/seaweedfs/seaweedfs /go/src/github.com/seaweedfs/seaweedfs
|
||||
@@ -6,7 +6,7 @@ ARG BRANCH=${BRANCH:-master}
|
||||
ARG TAGS
|
||||
RUN cd /go/src/github.com/seaweedfs/seaweedfs && git checkout $BRANCH
|
||||
RUN cd /go/src/github.com/seaweedfs/seaweedfs/weed \
|
||||
&& export LDFLAGS="-X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=$(git rev-parse --short HEAD)" \
|
||||
&& export LDFLAGS="-X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=$(git rev-parse --short HEAD)" \
|
||||
&& CGO_ENABLED=0 go install -tags "$TAGS" -ldflags "-extldflags -static ${LDFLAGS}"
|
||||
|
||||
FROM alpine AS final
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
FROM golang:1.22 as builder
|
||||
FROM golang:1.24 as builder
|
||||
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y build-essential libsnappy-dev zlib1g-dev libbz2-dev libgflags-dev liblz4-dev libzstd-dev
|
||||
|
||||
ENV ROCKSDB_VERSION v8.10.0
|
||||
ENV ROCKSDB_VERSION v10.2.1
|
||||
|
||||
# build RocksDB
|
||||
RUN cd /tmp && \
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
FROM golang:1.22 as builder
|
||||
FROM golang:1.24 as builder
|
||||
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y build-essential libsnappy-dev zlib1g-dev libbz2-dev libgflags-dev liblz4-dev libzstd-dev
|
||||
|
||||
ENV ROCKSDB_VERSION v8.10.0
|
||||
ENV ROCKSDB_VERSION v10.2.1
|
||||
|
||||
# build RocksDB
|
||||
RUN cd /tmp && \
|
||||
@@ -21,7 +21,7 @@ RUN git clone https://github.com/seaweedfs/seaweedfs /go/src/github.com/seaweedf
|
||||
ARG BRANCH=${BRANCH:-master}
|
||||
RUN cd /go/src/github.com/seaweedfs/seaweedfs && git checkout $BRANCH
|
||||
RUN cd /go/src/github.com/seaweedfs/seaweedfs/weed \
|
||||
&& export LDFLAGS="-X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=$(git rev-parse --short HEAD)" \
|
||||
&& export LDFLAGS="-X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=$(git rev-parse --short HEAD)" \
|
||||
&& go install -tags "5BytesOffset rocksdb" -ldflags "-extldflags -static ${LDFLAGS}"
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ RUN mkdir -p /go/src/github.com/seaweedfs/
|
||||
ADD . /go/src/github.com/seaweedfs/seaweedfs
|
||||
RUN ls -al /go/src/github.com/seaweedfs/ && \
|
||||
cd /go/src/github.com/seaweedfs/seaweedfs/weed \
|
||||
&& export LDFLAGS="-X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=$(git rev-parse --short HEAD)" \
|
||||
&& export LDFLAGS="-X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=$(git rev-parse --short HEAD)" \
|
||||
&& go install -tags "5BytesOffset rocksdb" -ldflags "-extldflags -static ${LDFLAGS}"
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
FROM tarantool/tarantool:3.3.1 AS builder
|
||||
|
||||
# install dependencies
|
||||
RUN apt update && \
|
||||
apt install -y git unzip cmake tt=2.7.0
|
||||
|
||||
# init tt dir structure, create dir for app, create symlink
|
||||
RUN tt init && \
|
||||
mkdir app && \
|
||||
ln -sfn ${PWD}/app/ ${PWD}/instances.enabled/app
|
||||
|
||||
# copy cluster configs
|
||||
COPY tarantool /opt/tarantool/app
|
||||
|
||||
# build app
|
||||
RUN tt build app
|
||||
|
||||
+14
-7
@@ -7,12 +7,10 @@ gen: dev
|
||||
cgo ?= 0
|
||||
binary:
|
||||
export SWCOMMIT=$(shell git rev-parse --short HEAD)
|
||||
export SWLDFLAGS="-X github.com/seaweedfs/seaweedfs/weed/util.COMMIT=$(SWCOMMIT)"
|
||||
export SWLDFLAGS="-X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=$(SWCOMMIT)"
|
||||
cd ../weed && CGO_ENABLED=$(cgo) GOOS=linux go build $(options) -tags "$(tags)" -ldflags "-s -w -extldflags -static $(SWLDFLAGS)" && mv weed ../docker/
|
||||
cd ../weed/mq/client/cmd/weed_pub_kv && CGO_ENABLED=$(cgo) GOOS=linux go build && mv weed_pub_kv ../../../../../docker/
|
||||
cd ../weed/mq/client/cmd/weed_pub_record && CGO_ENABLED=$(cgo) GOOS=linux go build && mv weed_pub_record ../../../../../docker/
|
||||
cd ../weed/mq/client/cmd/weed_sub_kv && CGO_ENABLED=$(cgo) GOOS=linux go build && mv weed_sub_kv ../../../../../docker/
|
||||
cd ../weed/mq/client/cmd/weed_sub_record && CGO_ENABLED=$(cgo) GOOS=linux go build && mv weed_sub_record ../../../../../docker/
|
||||
cd ../other/mq_client_example/agent_pub_record && CGO_ENABLED=$(cgo) GOOS=linux go build && mv agent_pub_record ../../../docker/
|
||||
cd ../other/mq_client_example/agent_sub_record && CGO_ENABLED=$(cgo) GOOS=linux go build && mv agent_sub_record ../../../docker/
|
||||
|
||||
binary_race: options = -race
|
||||
binary_race: cgo = 1
|
||||
@@ -24,7 +22,7 @@ build: binary
|
||||
build_e2e: binary_race
|
||||
docker build --no-cache -t chrislusf/seaweedfs:e2e -f Dockerfile.e2e .
|
||||
|
||||
go_build: # make go_build tags=elastic,ydb,gocdk,hdfs,5BytesOffset
|
||||
go_build: # make go_build tags=elastic,ydb,gocdk,hdfs,5BytesOffset,tarantool
|
||||
docker build --build-arg TAGS=$(tags) --no-cache -t chrislusf/seaweedfs:go_build -f Dockerfile.go_build .
|
||||
|
||||
go_build_large_disk:
|
||||
@@ -39,6 +37,9 @@ build_rocksdb_local: build_rocksdb_dev_env
|
||||
build_rocksdb:
|
||||
docker build --no-cache -t chrislusf/seaweedfs:rocksdb -f Dockerfile.rocksdb_large .
|
||||
|
||||
build_tarantool_dev_env:
|
||||
docker build --no-cache -t chrislusf/tarantool_dev_env -f Dockerfile.tarantool.dev_env .
|
||||
|
||||
s3tests_build:
|
||||
docker build --no-cache -t chrislusf/ceph-s3-tests:local -f Dockerfile.s3tests .
|
||||
|
||||
@@ -97,6 +98,9 @@ s3tests: build s3tests_build
|
||||
brokers: build
|
||||
docker compose -f compose/local-brokers-compose.yml -p seaweedfs up
|
||||
|
||||
agent: build
|
||||
docker compose -f compose/local-mq-test.yml -p seaweedfs up
|
||||
|
||||
filer_etcd: build
|
||||
docker stack deploy -c compose/swarm-etcd.yml fs
|
||||
|
||||
@@ -105,9 +109,12 @@ test_etcd: build
|
||||
|
||||
test_ydb: tags = ydb
|
||||
test_ydb: build
|
||||
export
|
||||
docker compose -f compose/test-ydb-filer.yml -p seaweedfs up
|
||||
|
||||
test_tarantool: tags = tarantool
|
||||
test_tarantool: build_tarantool_dev_env build
|
||||
docker compose -f compose/test-tarantool-filer.yml -p seaweedfs up
|
||||
|
||||
clean:
|
||||
rm ./weed
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<source>
|
||||
@type forward
|
||||
port 24224
|
||||
</source>
|
||||
|
||||
<match **>
|
||||
@type stdout # Output logs to container's stdout (visible via `docker logs`)
|
||||
</match>
|
||||
@@ -19,7 +19,9 @@ services:
|
||||
depends_on:
|
||||
- fluent
|
||||
fluent:
|
||||
image: fluent/fluentd:v1.14
|
||||
image: fluent/fluentd:v1.17
|
||||
volumes:
|
||||
- ./fluent.conf:/fluentd/etc/fluent.conf
|
||||
ports:
|
||||
- 24224:24224
|
||||
#s3tests:
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
version: '3.9'
|
||||
|
||||
services:
|
||||
server:
|
||||
image: chrislusf/seaweedfs:local
|
||||
@@ -19,9 +17,16 @@ services:
|
||||
depends_on:
|
||||
server:
|
||||
condition: service_healthy
|
||||
mq_agent:
|
||||
image: chrislusf/seaweedfs:local
|
||||
ports:
|
||||
- 16777:16777
|
||||
command: "mq.agent -broker=mq_broker:17777 -port=16777"
|
||||
depends_on:
|
||||
- mq_broker
|
||||
mq_client:
|
||||
image: chrislusf/seaweedfs:local
|
||||
# run a custom command instead of entrypoint
|
||||
command: "ls -al"
|
||||
depends_on:
|
||||
- mq_broker
|
||||
- mq_agent
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
version: '3.9'
|
||||
|
||||
services:
|
||||
tarantool:
|
||||
image: chrislusf/tarantool_dev_env
|
||||
entrypoint: "tt start app -i"
|
||||
environment:
|
||||
APP_USER_PASSWORD: "app"
|
||||
CLIENT_USER_PASSWORD: "client"
|
||||
REPLICATOR_USER_PASSWORD: "replicator"
|
||||
STORAGE_USER_PASSWORD: "storage"
|
||||
network_mode: "host"
|
||||
ports:
|
||||
- "3303:3303"
|
||||
|
||||
s3:
|
||||
image: chrislusf/seaweedfs:local
|
||||
command: "server -ip=127.0.0.1 -filer -master.volumeSizeLimitMB=16 -volume.max=0 -volume -volume.preStopSeconds=1 -s3 -s3.config=/etc/seaweedfs/s3.json -s3.port=8000 -s3.allowEmptyFolder=false -s3.allowDeleteBucketNotEmpty=false"
|
||||
volumes:
|
||||
- ./s3.json:/etc/seaweedfs/s3.json
|
||||
environment:
|
||||
WEED_LEVELDB2_ENABLED: "false"
|
||||
WEED_TARANTOOL_ENABLED: "true"
|
||||
WEED_TARANTOOL_ADDRESS: "127.0.0.1:3303"
|
||||
WEED_TARANTOOL_USER: "client"
|
||||
WEED_TARANTOOL_PASSWORD: "client"
|
||||
WEED_MASTER_VOLUME_GROWTH_COPY_OTHER: 1
|
||||
network_mode: "host"
|
||||
depends_on:
|
||||
- tarantool
|
||||
@@ -0,0 +1,37 @@
|
||||
[
|
||||
{
|
||||
"Username": "admin",
|
||||
"Password": "myadminpassword",
|
||||
"PublicKeys": [
|
||||
],
|
||||
"HomeDir": "/",
|
||||
"Permissions": {
|
||||
"/": ["*"]
|
||||
},
|
||||
"Uid": 0,
|
||||
"Gid": 0
|
||||
},
|
||||
{
|
||||
"Username": "user1",
|
||||
"Password": "myuser1password",
|
||||
"PublicKeys": [""],
|
||||
"HomeDir": "/user1",
|
||||
"Permissions": {
|
||||
"/user1": ["*"],
|
||||
"/public": ["read", "list","write"]
|
||||
},
|
||||
"Uid": 1111,
|
||||
"Gid": 1111
|
||||
},
|
||||
{
|
||||
"Username": "readonly",
|
||||
"Password": "myreadonlypassword",
|
||||
"PublicKeys": [],
|
||||
"HomeDir": "/public",
|
||||
"Permissions": {
|
||||
"/public": ["read", "list"]
|
||||
},
|
||||
"Uid": 1112,
|
||||
"Gid": 1112
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,14 @@
|
||||
package = 'app'
|
||||
version = 'scm-1'
|
||||
source = {
|
||||
url = '/dev/null',
|
||||
}
|
||||
dependencies = {
|
||||
'crud == 1.5.2-1',
|
||||
'expirationd == 1.6.0-1',
|
||||
'metrics-export-role == 0.3.0-1',
|
||||
'vshard == 0.1.32-1'
|
||||
}
|
||||
build = {
|
||||
type = 'none';
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
config:
|
||||
context:
|
||||
app_user_password:
|
||||
from: env
|
||||
env: APP_USER_PASSWORD
|
||||
client_user_password:
|
||||
from: env
|
||||
env: CLIENT_USER_PASSWORD
|
||||
replicator_user_password:
|
||||
from: env
|
||||
env: REPLICATOR_USER_PASSWORD
|
||||
storage_user_password:
|
||||
from: env
|
||||
env: STORAGE_USER_PASSWORD
|
||||
|
||||
credentials:
|
||||
roles:
|
||||
crud-role:
|
||||
privileges:
|
||||
- permissions: [ "execute" ]
|
||||
lua_call: [ "crud.delete", "crud.get", "crud.upsert" ]
|
||||
users:
|
||||
app:
|
||||
password: '{{ context.app_user_password }}'
|
||||
roles: [ public, crud-role ]
|
||||
client:
|
||||
password: '{{ context.client_user_password }}'
|
||||
roles: [ super ]
|
||||
replicator:
|
||||
password: '{{ context.replicator_user_password }}'
|
||||
roles: [ replication ]
|
||||
storage:
|
||||
password: '{{ context.storage_user_password }}'
|
||||
roles: [ sharding ]
|
||||
|
||||
iproto:
|
||||
advertise:
|
||||
peer:
|
||||
login: replicator
|
||||
sharding:
|
||||
login: storage
|
||||
|
||||
sharding:
|
||||
bucket_count: 10000
|
||||
|
||||
metrics:
|
||||
include: [ all ]
|
||||
exclude: [ vinyl ]
|
||||
labels:
|
||||
alias: '{{ instance_name }}'
|
||||
|
||||
|
||||
groups:
|
||||
storages:
|
||||
roles:
|
||||
- roles.crud-storage
|
||||
- roles.expirationd
|
||||
- roles.metrics-export
|
||||
roles_cfg:
|
||||
roles.expirationd:
|
||||
cfg:
|
||||
metrics: true
|
||||
filer_metadata_task:
|
||||
space: filer_metadata
|
||||
is_expired: filer_metadata.is_expired
|
||||
options:
|
||||
atomic_iteration: true
|
||||
force: true
|
||||
index: 'expire_at_idx'
|
||||
iterator_type: GT
|
||||
start_key:
|
||||
- 0
|
||||
tuples_per_iteration: 10000
|
||||
app:
|
||||
module: storage
|
||||
sharding:
|
||||
roles: [ storage ]
|
||||
replication:
|
||||
failover: election
|
||||
database:
|
||||
use_mvcc_engine: true
|
||||
replicasets:
|
||||
storage-001:
|
||||
instances:
|
||||
storage-001-a:
|
||||
roles_cfg:
|
||||
roles.metrics-export:
|
||||
http:
|
||||
- listen: '0.0.0.0:8081'
|
||||
endpoints:
|
||||
- path: /metrics/prometheus/
|
||||
format: prometheus
|
||||
- path: /metrics/json
|
||||
format: json
|
||||
iproto:
|
||||
listen:
|
||||
- uri: 127.0.0.1:3301
|
||||
advertise:
|
||||
client: 127.0.0.1:3301
|
||||
storage-001-b:
|
||||
roles_cfg:
|
||||
roles.metrics-export:
|
||||
http:
|
||||
- listen: '0.0.0.0:8082'
|
||||
endpoints:
|
||||
- path: /metrics/prometheus/
|
||||
format: prometheus
|
||||
- path: /metrics/json
|
||||
format: json
|
||||
iproto:
|
||||
listen:
|
||||
- uri: 127.0.0.1:3302
|
||||
advertise:
|
||||
client: 127.0.0.1:3302
|
||||
routers:
|
||||
roles:
|
||||
- roles.crud-router
|
||||
- roles.metrics-export
|
||||
roles_cfg:
|
||||
roles.crud-router:
|
||||
stats: true
|
||||
stats_driver: metrics
|
||||
stats_quantiles: true
|
||||
app:
|
||||
module: router
|
||||
sharding:
|
||||
roles: [ router ]
|
||||
replicasets:
|
||||
router-001:
|
||||
instances:
|
||||
router-001-a:
|
||||
roles_cfg:
|
||||
roles.metrics-export:
|
||||
http:
|
||||
- listen: '0.0.0.0:8083'
|
||||
endpoints:
|
||||
- path: /metrics/prometheus/
|
||||
format: prometheus
|
||||
- path: /metrics/json
|
||||
format: json
|
||||
iproto:
|
||||
listen:
|
||||
- uri: 127.0.0.1:3303
|
||||
advertise:
|
||||
client: 127.0.0.1:3303
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
storage-001-a:
|
||||
|
||||
storage-001-b:
|
||||
|
||||
router-001-a:
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
local vshard = require('vshard')
|
||||
local log = require('log')
|
||||
|
||||
-- Bootstrap the vshard router.
|
||||
while true do
|
||||
local ok, err = vshard.router.bootstrap({
|
||||
if_not_bootstrapped = true,
|
||||
})
|
||||
if ok then
|
||||
break
|
||||
end
|
||||
log.info(('Router bootstrap error: %s'):format(err))
|
||||
end
|
||||
|
||||
-- functions for filer_metadata space
|
||||
local filer_metadata = {
|
||||
delete_by_directory_idx = function(directory)
|
||||
-- find all storages
|
||||
local storages = require('vshard').router.routeall()
|
||||
-- on each storage
|
||||
for _, storage in pairs(storages) do
|
||||
-- call local function
|
||||
local result, err = storage:callrw('filer_metadata.delete_by_directory_idx', { directory })
|
||||
-- check for error
|
||||
if err then
|
||||
error("Failed to call function on storage: " .. tostring(err))
|
||||
end
|
||||
end
|
||||
-- return
|
||||
return true
|
||||
end,
|
||||
find_by_directory_idx_and_name = function(dirPath, startFileName, includeStartFile, limit)
|
||||
-- init results
|
||||
local results = {}
|
||||
-- find all storages
|
||||
local storages = require('vshard').router.routeall()
|
||||
-- on each storage
|
||||
for _, storage in pairs(storages) do
|
||||
-- call local function
|
||||
local result, err = storage:callro('filer_metadata.find_by_directory_idx_and_name', {
|
||||
dirPath,
|
||||
startFileName,
|
||||
includeStartFile,
|
||||
limit
|
||||
})
|
||||
-- check for error
|
||||
if err then
|
||||
error("Failed to call function on storage: " .. tostring(err))
|
||||
end
|
||||
-- add to results
|
||||
for _, tuple in ipairs(result) do
|
||||
table.insert(results, tuple)
|
||||
end
|
||||
end
|
||||
-- sort
|
||||
table.sort(results, function(a, b) return a[3] < b[3] end)
|
||||
-- apply limit
|
||||
if #results > limit then
|
||||
local limitedResults = {}
|
||||
for i = 1, limit do
|
||||
table.insert(limitedResults, results[i])
|
||||
end
|
||||
results = limitedResults
|
||||
end
|
||||
-- return
|
||||
return results
|
||||
end,
|
||||
}
|
||||
|
||||
rawset(_G, 'filer_metadata', filer_metadata)
|
||||
|
||||
-- register functions for filer_metadata space, set grants
|
||||
for name, _ in pairs(filer_metadata) do
|
||||
box.schema.func.create('filer_metadata.' .. name, { if_not_exists = true })
|
||||
box.schema.user.grant('app', 'execute', 'function', 'filer_metadata.' .. name, { if_not_exists = true })
|
||||
box.schema.user.grant('client', 'execute', 'function', 'filer_metadata.' .. name, { if_not_exists = true })
|
||||
end
|
||||
@@ -0,0 +1,97 @@
|
||||
box.watch('box.status', function()
|
||||
if box.info.ro then
|
||||
return
|
||||
end
|
||||
|
||||
-- ====================================
|
||||
-- key_value space
|
||||
-- ====================================
|
||||
box.schema.create_space('key_value', {
|
||||
format = {
|
||||
{ name = 'key', type = 'string' },
|
||||
{ name = 'bucket_id', type = 'unsigned' },
|
||||
{ name = 'value', type = 'string' }
|
||||
},
|
||||
if_not_exists = true
|
||||
})
|
||||
|
||||
-- create key_value space indexes
|
||||
box.space.key_value:create_index('id', {type = 'tree', parts = { 'key' }, unique = true, if_not_exists = true})
|
||||
box.space.key_value:create_index('bucket_id', { type = 'tree', parts = { 'bucket_id' }, unique = false, if_not_exists = true })
|
||||
|
||||
-- ====================================
|
||||
-- filer_metadata space
|
||||
-- ====================================
|
||||
box.schema.create_space('filer_metadata', {
|
||||
format = {
|
||||
{ name = 'directory', type = 'string' },
|
||||
{ name = 'bucket_id', type = 'unsigned' },
|
||||
{ name = 'name', type = 'string' },
|
||||
{ name = 'expire_at', type = 'unsigned' },
|
||||
{ name = 'data', type = 'string' }
|
||||
},
|
||||
if_not_exists = true
|
||||
})
|
||||
|
||||
-- create filer_metadata space indexes
|
||||
box.space.filer_metadata:create_index('id', {type = 'tree', parts = { 'directory', 'name' }, unique = true, if_not_exists = true})
|
||||
box.space.filer_metadata:create_index('bucket_id', { type = 'tree', parts = { 'bucket_id' }, unique = false, if_not_exists = true })
|
||||
box.space.filer_metadata:create_index('directory_idx', { type = 'tree', parts = { 'directory' }, unique = false, if_not_exists = true })
|
||||
box.space.filer_metadata:create_index('name_idx', { type = 'tree', parts = { 'name' }, unique = false, if_not_exists = true })
|
||||
box.space.filer_metadata:create_index('expire_at_idx', { type = 'tree', parts = { 'expire_at' }, unique = false, if_not_exists = true})
|
||||
end)
|
||||
|
||||
-- functions for filer_metadata space
|
||||
local filer_metadata = {
|
||||
delete_by_directory_idx = function(directory)
|
||||
local space = box.space.filer_metadata
|
||||
local index = space.index.directory_idx
|
||||
-- for each finded directories
|
||||
for _, tuple in index:pairs({ directory }, { iterator = 'EQ' }) do
|
||||
space:delete({ tuple[1], tuple[3] })
|
||||
end
|
||||
return true
|
||||
end,
|
||||
find_by_directory_idx_and_name = function(dirPath, startFileName, includeStartFile, limit)
|
||||
local space = box.space.filer_metadata
|
||||
local directory_idx = space.index.directory_idx
|
||||
-- choose filter name function
|
||||
local filter_filename_func
|
||||
if includeStartFile then
|
||||
filter_filename_func = function(value) return value >= startFileName end
|
||||
else
|
||||
filter_filename_func = function(value) return value > startFileName end
|
||||
end
|
||||
-- init results
|
||||
local results = {}
|
||||
-- for each finded directories
|
||||
for _, tuple in directory_idx:pairs({ dirPath }, { iterator = 'EQ' }) do
|
||||
-- filter by name
|
||||
if filter_filename_func(tuple[3]) then
|
||||
table.insert(results, tuple)
|
||||
end
|
||||
end
|
||||
-- sort
|
||||
table.sort(results, function(a, b) return a[3] < b[3] end)
|
||||
-- apply limit
|
||||
if #results > limit then
|
||||
local limitedResults = {}
|
||||
for i = 1, limit do
|
||||
table.insert(limitedResults, results[i])
|
||||
end
|
||||
results = limitedResults
|
||||
end
|
||||
-- return
|
||||
return results
|
||||
end,
|
||||
is_expired = function(args, tuple)
|
||||
return (tuple[4] > 0) and (require('fiber').time() > tuple[4])
|
||||
end
|
||||
}
|
||||
|
||||
-- register functions for filer_metadata space, set grants
|
||||
rawset(_G, 'filer_metadata', filer_metadata)
|
||||
for name, _ in pairs(filer_metadata) do
|
||||
box.schema.func.create('filer_metadata.' .. name, { setuid = true, if_not_exists = true })
|
||||
box.schema.user.grant('storage', 'execute', 'function', 'filer_metadata.' .. name, { if_not_exists = true })
|
||||
end
|
||||
@@ -1,15 +1,17 @@
|
||||
module github.com/seaweedfs/seaweedfs
|
||||
|
||||
go 1.22.0
|
||||
go 1.24
|
||||
|
||||
toolchain go1.24.1
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.116.0 // indirect
|
||||
cloud.google.com/go/pubsub v1.45.3
|
||||
cloud.google.com/go/storage v1.50.0
|
||||
cloud.google.com/go v0.121.0 // indirect
|
||||
cloud.google.com/go/pubsub v1.49.0
|
||||
cloud.google.com/go/storage v1.54.0
|
||||
github.com/Azure/azure-pipeline-go v0.2.3
|
||||
github.com/Azure/azure-storage-blob-go v0.15.0
|
||||
github.com/Shopify/sarama v1.38.1
|
||||
github.com/aws/aws-sdk-go v1.55.6
|
||||
github.com/aws/aws-sdk-go v1.55.7
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bwmarrin/snowflake v0.3.0
|
||||
github.com/cenkalti/backoff/v4 v4.3.0
|
||||
@@ -27,41 +29,37 @@ require (
|
||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect
|
||||
github.com/facebookgo/stats v0.0.0-20151006221625-1b76add642e4
|
||||
github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 // indirect
|
||||
github.com/fclairamb/ftpserverlib v0.25.0
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.8.0 // indirect
|
||||
github.com/go-redsync/redsync/v4 v4.13.0
|
||||
github.com/go-sql-driver/mysql v1.8.1
|
||||
github.com/go-sql-driver/mysql v1.9.2
|
||||
github.com/go-zookeeper/zk v1.0.3 // indirect
|
||||
github.com/gocql/gocql v1.7.0
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||
github.com/golang/protobuf v1.5.4
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/btree v1.1.3
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/google/wire v0.6.0 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.14.1 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.14.2 // indirect
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/jcmturner/gofork v1.7.6 // indirect
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect
|
||||
github.com/jinzhu/copier v0.4.0
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/karlseguin/ccache/v2 v2.0.8
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/klauspost/reedsolomon v1.12.4
|
||||
github.com/kurin/blazer v0.5.3
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/linxGnu/grocksdb v1.9.8
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/linxGnu/grocksdb v1.10.1
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-ieproxy v0.0.11 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/olivere/elastic/v7 v7.0.32
|
||||
@@ -70,18 +68,18 @@ require (
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/posener/complete v1.2.3
|
||||
github.com/pquerna/cachecontrol v0.2.0
|
||||
github.com/prometheus/client_golang v1.20.5
|
||||
github.com/prometheus/client_golang v1.22.0
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.55.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1
|
||||
github.com/prometheus/common v0.62.0 // indirect
|
||||
github.com/prometheus/procfs v0.16.1
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/seaweedfs/goexif v1.0.3
|
||||
github.com/seaweedfs/raft v1.1.3
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
github.com/spf13/cast v1.6.0 // indirect
|
||||
github.com/spf13/viper v1.19.0
|
||||
github.com/spf13/afero v1.12.0 // indirect
|
||||
github.com/spf13/cast v1.7.1 // indirect
|
||||
github.com/spf13/viper v1.20.1
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965
|
||||
@@ -96,90 +94,93 @@ require (
|
||||
github.com/xdg-go/scram v1.1.2 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.18
|
||||
go.mongodb.org/mongo-driver v1.17.2
|
||||
go.etcd.io/etcd/client/v3 v3.6.0
|
||||
go.mongodb.org/mongo-driver v1.17.3
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
gocloud.dev v0.40.0
|
||||
gocloud.dev/pubsub/natspubsub v0.40.0
|
||||
gocloud.dev/pubsub/rabbitpubsub v0.40.0
|
||||
golang.org/x/crypto v0.32.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
|
||||
golang.org/x/image v0.23.0
|
||||
golang.org/x/net v0.34.0
|
||||
golang.org/x/oauth2 v0.25.0 // indirect
|
||||
golang.org/x/sys v0.29.0
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
golang.org/x/tools v0.27.0
|
||||
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect
|
||||
google.golang.org/api v0.218.0
|
||||
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 // indirect
|
||||
google.golang.org/grpc v1.69.4
|
||||
google.golang.org/protobuf v1.36.3
|
||||
gocloud.dev v0.41.0
|
||||
gocloud.dev/pubsub/natspubsub v0.41.0
|
||||
gocloud.dev/pubsub/rabbitpubsub v0.41.0
|
||||
golang.org/x/crypto v0.38.0
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0
|
||||
golang.org/x/image v0.27.0
|
||||
golang.org/x/net v0.40.0
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
golang.org/x/sys v0.33.0
|
||||
golang.org/x/text v0.25.0 // indirect
|
||||
golang.org/x/tools v0.33.0
|
||||
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
|
||||
google.golang.org/api v0.234.0
|
||||
google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 // indirect
|
||||
google.golang.org/grpc v1.72.1
|
||||
google.golang.org/protobuf v1.36.6
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
modernc.org/b v1.0.0 // indirect
|
||||
modernc.org/mathutil v1.7.1
|
||||
modernc.org/memory v1.8.0 // indirect
|
||||
modernc.org/sqlite v1.34.5
|
||||
modernc.org/strutil v1.2.0
|
||||
modernc.org/memory v1.11.0 // indirect
|
||||
modernc.org/sqlite v1.37.1
|
||||
modernc.org/strutil v1.2.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Jille/raft-grpc-transport v1.6.1
|
||||
github.com/arangodb/go-driver v1.6.5
|
||||
github.com/arangodb/go-driver v1.6.6
|
||||
github.com/armon/go-metrics v0.4.1
|
||||
github.com/aws/aws-sdk-go-v2 v1.34.0
|
||||
github.com/aws/aws-sdk-go-v2/config v1.29.1
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.54
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.72.0
|
||||
github.com/cognusion/imaging v1.0.1
|
||||
github.com/fluent/fluent-logger-golang v1.9.0
|
||||
github.com/aws/aws-sdk-go-v2 v1.36.3
|
||||
github.com/aws/aws-sdk-go-v2/config v1.29.14
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.67
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.80.0
|
||||
github.com/cognusion/imaging v1.0.2
|
||||
github.com/fluent/fluent-logger-golang v1.10.0
|
||||
github.com/getsentry/sentry-go v0.31.1
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2
|
||||
github.com/google/flatbuffers/go v0.0.0-20230108230133-3b8644d32c50
|
||||
github.com/hanwen/go-fuse/v2 v2.7.2
|
||||
github.com/hashicorp/raft v1.7.2
|
||||
github.com/hanwen/go-fuse/v2 v2.7.3-0.20250605191109-50f6569d1a7d
|
||||
github.com/hashicorp/raft v1.7.3
|
||||
github.com/hashicorp/raft-boltdb/v2 v2.3.1
|
||||
github.com/minio/crc64nvme v1.0.1
|
||||
github.com/orcaman/concurrent-map/v2 v2.0.1
|
||||
github.com/parquet-go/parquet-go v0.24.0
|
||||
github.com/pkg/sftp v1.13.7
|
||||
github.com/rabbitmq/amqp091-go v1.10.0
|
||||
github.com/rclone/rclone v1.68.2
|
||||
github.com/rclone/rclone v1.69.3
|
||||
github.com/rdleal/intervalst v1.4.1
|
||||
github.com/redis/go-redis/v9 v9.7.0
|
||||
github.com/schollz/progressbar/v3 v3.17.1
|
||||
github.com/redis/go-redis/v9 v9.8.0
|
||||
github.com/schollz/progressbar/v3 v3.18.0
|
||||
github.com/shirou/gopsutil/v3 v3.24.5
|
||||
github.com/tarantool/go-tarantool/v2 v2.3.2
|
||||
github.com/tikv/client-go/v2 v2.0.7
|
||||
github.com/ydb-platform/ydb-go-sdk-auth-environ v0.5.0
|
||||
github.com/ydb-platform/ydb-go-sdk/v3 v3.98.0
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.18
|
||||
github.com/ydb-platform/ydb-go-sdk/v3 v3.108.3
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.6.0
|
||||
go.uber.org/atomic v1.11.0
|
||||
golang.org/x/sync v0.10.0
|
||||
golang.org/x/sync v0.14.0
|
||||
google.golang.org/grpc/security/advancedtls v1.0.0
|
||||
)
|
||||
|
||||
require (
|
||||
cel.dev/expr v0.16.2 // indirect
|
||||
cloud.google.com/go/auth v0.14.0 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.6.0 // indirect
|
||||
cloud.google.com/go/iam v1.2.2 // indirect
|
||||
cloud.google.com/go/monitoring v1.21.2 // indirect
|
||||
cel.dev/expr v0.22.1 // indirect
|
||||
cloud.google.com/go/auth v0.16.1 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.7.0 // indirect
|
||||
cloud.google.com/go/iam v1.5.2 // indirect
|
||||
cloud.google.com/go/monitoring v1.24.2 // indirect
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.1 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.2 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azfile v1.2.2 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azfile v1.4.0 // indirect
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
|
||||
github.com/Files-com/files-sdk-go/v3 v3.2.34 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.48.1 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.1 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect
|
||||
github.com/Files-com/files-sdk-go/v3 v3.2.97 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 // indirect
|
||||
github.com/Max-Sum/base32768 v0.0.0-20230304063302-18e6ce5945fd // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf // indirect
|
||||
github.com/ProtonMail/gluon v0.17.1-0.20230724134000-308be39be96e // indirect
|
||||
github.com/ProtonMail/go-crypto v1.0.0 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.1.3 // indirect
|
||||
github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f // indirect
|
||||
github.com/ProtonMail/go-srp v0.0.7 // indirect
|
||||
github.com/ProtonMail/gopenpgp/v2 v2.7.4 // indirect
|
||||
@@ -189,63 +190,68 @@ require (
|
||||
github.com/andybalholm/cascadia v1.3.2 // indirect
|
||||
github.com/appscode/go-querystring v0.0.0-20170504095604-0126cfb3f1dc // indirect
|
||||
github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.24 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.28 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.28 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sns v1.31.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sqs v1.34.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.24.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.9 // indirect
|
||||
github.com/aws/smithy-go v1.22.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.69 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sns v1.34.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sqs v1.38.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 // indirect
|
||||
github.com/aws/smithy-go v1.22.3 // indirect
|
||||
github.com/boltdb/bolt v1.3.1 // indirect
|
||||
github.com/bradenaw/juniper v0.15.2 // indirect
|
||||
github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 // indirect
|
||||
github.com/buengese/sgzip v0.1.1 // indirect
|
||||
github.com/calebcase/tmpfile v1.0.3 // indirect
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
|
||||
github.com/chilts/sid v0.0.0-20190607042430-660e94789ec9 // indirect
|
||||
github.com/cloudflare/circl v1.3.7 // indirect
|
||||
github.com/cloudsoda/go-smb2 v0.0.0-20231124195312-f3ec8ae2c891 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 // indirect
|
||||
github.com/cloudinary/cloudinary-go/v2 v2.9.0 // indirect
|
||||
github.com/cloudsoda/go-smb2 v0.0.0-20241223203758-52b943b88fd6 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f // indirect
|
||||
github.com/colinmarc/hdfs/v2 v2.4.0 // indirect
|
||||
github.com/creasty/defaults v1.7.0 // indirect
|
||||
github.com/cronokirby/saferith v0.33.0 // indirect
|
||||
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 // indirect
|
||||
github.com/d4l3k/messagediff v1.2.1 // indirect
|
||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 // indirect
|
||||
github.com/dropbox/dropbox-sdk-go-unofficial/v6 v6.0.5 // indirect
|
||||
github.com/ebitengine/purego v0.8.3 // indirect
|
||||
github.com/elastic/gosigar v0.14.2 // indirect
|
||||
github.com/emersion/go-message v0.18.0 // indirect
|
||||
github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594 // indirect
|
||||
github.com/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9 // indirect
|
||||
github.com/envoyproxy/go-control-plane v0.13.1 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/fclairamb/go-log v0.5.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/flynn/noise v1.0.1 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.4 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.7 // indirect
|
||||
github.com/geoffgarside/ber v1.1.0 // indirect
|
||||
github.com/go-chi/chi/v5 v5.1.0 // indirect
|
||||
github.com/go-darwin/apfs v0.0.0-20211011131704-f84b94dbf348 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/go-resty/resty/v2 v2.11.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
|
||||
github.com/gofrs/flock v0.8.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.1 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
||||
github.com/gorilla/schema v1.4.1 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
@@ -259,12 +265,12 @@ require (
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
|
||||
github.com/jcmturner/goidentity/v6 v6.0.1 // indirect
|
||||
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
|
||||
github.com/jlaffaye/ftp v0.2.0 // indirect
|
||||
github.com/jonboulle/clockwork v0.3.0 // indirect
|
||||
github.com/jlaffaye/ftp v0.2.1-0.20240918233326-1b970516f5d3 // indirect
|
||||
github.com/jonboulle/clockwork v0.5.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/jtolio/noiseconn v0.0.0-20231127013910-f6d9ecbf1de7 // indirect
|
||||
github.com/jzelinskie/whirlpool v0.0.0-20201016144138-0675e54bb004 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
|
||||
github.com/koofr/go-httpclient v0.0.0-20240520111329-e20f8f203988 // indirect
|
||||
github.com/koofr/go-koofrclient v0.0.0-20221207135200-cbd7fc9ad6a6 // indirect
|
||||
github.com/kr/fs v0.1.0 // indirect
|
||||
@@ -277,28 +283,29 @@ require (
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/montanaflynn/stats v0.7.1 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/nats-io/nats.go v1.37.0 // indirect
|
||||
github.com/nats-io/nkeys v0.4.7 // indirect
|
||||
github.com/nats-io/nats.go v1.40.1 // indirect
|
||||
github.com/nats-io/nkeys v0.4.10 // indirect
|
||||
github.com/nats-io/nuid v1.0.1 // indirect
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/ncw/swift/v2 v2.0.3 // indirect
|
||||
github.com/nxadm/tail v1.4.11 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.19.0 // indirect
|
||||
github.com/onsi/gomega v1.34.1 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/oracle/oci-go-sdk/v65 v65.69.2 // indirect
|
||||
github.com/oracle/oci-go-sdk/v65 v65.80.0 // indirect
|
||||
github.com/panjf2000/ants/v2 v2.9.1 // indirect
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||
github.com/pengsrc/go-shared v0.2.1-0.20190131101655-1999055a4a14 // indirect
|
||||
github.com/philhofer/fwd v1.1.2 // indirect
|
||||
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.21 // indirect
|
||||
github.com/pingcap/errors v0.11.5-0.20211224045212-9687c2b0f87c // indirect
|
||||
github.com/pingcap/failpoint v0.0.0-20220801062533-2eaa32854a6c // indirect
|
||||
github.com/pingcap/kvproto v0.0.0-20230403051650-e166ae588106 // indirect
|
||||
github.com/pingcap/log v1.1.1-0.20221110025148-ca232912c9f3 // indirect
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||
github.com/pkg/sftp v1.13.6 // indirect
|
||||
github.com/pkg/xattr v0.4.9 // indirect
|
||||
github.com/pkg/xattr v0.4.10 // indirect
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
|
||||
github.com/putdotio/go-putio/putio v0.0.0-20200123120452-16d982cac2b8 // indirect
|
||||
@@ -306,25 +313,29 @@ require (
|
||||
github.com/rfjakob/eme v1.1.2 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.7.0 // indirect
|
||||
github.com/samber/lo v1.47.0 // indirect
|
||||
github.com/shirou/gopsutil/v4 v4.24.12 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
|
||||
github.com/smartystreets/goconvey v1.8.1 // indirect
|
||||
github.com/sony/gobreaker v0.5.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spacemonkeygo/monkit/v3 v3.0.22 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/t3rm1n4l/go-mega v0.0.0-20240219080617-d494b6a8ace7 // indirect
|
||||
github.com/t3rm1n4l/go-mega v0.0.0-20241213150454-ec0027fb0002 // indirect
|
||||
github.com/tarantool/go-iproto v1.1.0 // indirect
|
||||
github.com/tiancaiamao/gp v0.0.0-20221230034425-4025bc8a4d4a // indirect
|
||||
github.com/tikv/pd/client v0.0.0-20230329114254-1948c247c2b1 // indirect
|
||||
github.com/tinylib/msgp v1.1.8 // indirect
|
||||
github.com/tinylib/msgp v1.3.0 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.13 // indirect
|
||||
github.com/tklauser/numcpus v0.7.0 // indirect
|
||||
github.com/twmb/murmur3 v1.1.3 // indirect
|
||||
github.com/unknwon/goconfig v1.0.0 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
github.com/yandex-cloud/go-genproto v0.0.0-20211115083454-9ca41db5ed9e // indirect
|
||||
github.com/ydb-platform/ydb-go-genproto v0.0.0-20241112172322-ea1f63298f77 // indirect
|
||||
@@ -333,30 +344,29 @@ require (
|
||||
github.com/yunify/qingstor-sdk-go/v3 v3.2.0 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
github.com/zeebo/blake3 v0.2.3 // indirect
|
||||
github.com/zeebo/errs v1.3.0 // indirect
|
||||
github.com/zeebo/errs v1.4.0 // indirect
|
||||
go.etcd.io/bbolt v1.3.10 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.18 // indirect
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.31.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
|
||||
go.opentelemetry.io/otel v1.31.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.31.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.31.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.31.0 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.6.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.35.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
|
||||
go.opentelemetry.io/otel v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.35.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/mod v0.22.0 // indirect
|
||||
golang.org/x/term v0.28.0 // indirect
|
||||
golang.org/x/time v0.9.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
golang.org/x/term v0.32.0 // indirect
|
||||
golang.org/x/time v0.11.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250512202823-5a2f75b736a9 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/validator.v2 v2.0.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
modernc.org/libc v1.55.3 // indirect
|
||||
modernc.org/libc v1.65.7 // indirect
|
||||
moul.io/http2curl/v2 v2.3.0 // indirect
|
||||
storj.io/common v0.0.0-20240812101423-26b53789c348 // indirect
|
||||
storj.io/drpc v0.0.35-0.20240709171858-0075ac871661 // indirect
|
||||
@@ -367,8 +377,3 @@ require (
|
||||
)
|
||||
|
||||
// replace github.com/seaweedfs/raft => /Users/chrislu/go/src/github.com/seaweedfs/raft
|
||||
|
||||
replace (
|
||||
github.com/boltdb/bolt => go.etcd.io/bbolt v1.3.10
|
||||
go.etcd.io/bbolt => github.com/etcd-io/bbolt v1.3.10
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
apiVersion: v1
|
||||
description: SeaweedFS
|
||||
name: seaweedfs
|
||||
appVersion: "3.83"
|
||||
appVersion: "3.90"
|
||||
# Dev note: Trigger a helm chart release by `git tag -a helm-<version>`
|
||||
version: 4.0.383
|
||||
version: 4.0.390
|
||||
|
||||
@@ -73,6 +73,16 @@ Inject extra environment vars in the format key:value, if populated
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* Return the proper sftp image */}}
|
||||
{{- define "sftp.image" -}}
|
||||
{{- if .Values.sftp.imageOverride -}}
|
||||
{{- $imageOverride := .Values.sftp.imageOverride -}}
|
||||
{{- printf "%s" $imageOverride -}}
|
||||
{{- else -}}
|
||||
{{- include "common.image" . }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* Return the proper volume image */}}
|
||||
{{- define "volume.image" -}}
|
||||
{{- if .Values.volume.imageOverride -}}
|
||||
@@ -88,7 +98,7 @@ Inject extra environment vars in the format key:value, if populated
|
||||
{{- $registryName := default .Values.image.registry .Values.global.registry | toString -}}
|
||||
{{- $repositoryName := .Values.image.repository | toString -}}
|
||||
{{- $name := .Values.global.imageName | toString -}}
|
||||
{{- $tag := .Chart.AppVersion | toString -}}
|
||||
{{- $tag := default .Chart.AppVersion .Values.image.tag | toString -}}
|
||||
{{- if $registryName -}}
|
||||
{{- printf "%s/%s%s:%s" $registryName $repositoryName $name $tag -}}
|
||||
{{- else -}}
|
||||
@@ -134,14 +144,17 @@ Inject extra environment vars in the format key:value, if populated
|
||||
|
||||
{{/* Return the proper imagePullSecrets */}}
|
||||
{{- define "seaweedfs.imagePullSecrets" -}}
|
||||
{{- if .Values.global.imagePullSecrets }}
|
||||
{{- if kindIs "string" .Values.global.imagePullSecrets }}
|
||||
{{- with .Values.global.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
- name: {{ .Values.global.imagePullSecrets }}
|
||||
{{- else }}
|
||||
imagePullSecrets:
|
||||
{{- range .Values.global.imagePullSecrets }}
|
||||
{{- if kindIs "string" . }}
|
||||
- name: {{ . }}
|
||||
{{- else }}
|
||||
{{- range . }}
|
||||
{{- if kindIs "string" . }}
|
||||
- name: {{ . }}
|
||||
{{- else }}
|
||||
- {{ toYaml . }}
|
||||
{{- end}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -165,3 +178,45 @@ Usage:
|
||||
{{- $value }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
|
||||
{{/*
|
||||
getOrGeneratePassword will check if a password exists in a secret and return it,
|
||||
or generate a new random password if it doesn't exist.
|
||||
*/}}
|
||||
{{- define "getOrGeneratePassword" -}}
|
||||
{{- $params := . -}}
|
||||
{{- $namespace := $params.namespace -}}
|
||||
{{- $secretName := $params.secretName -}}
|
||||
{{- $key := $params.key -}}
|
||||
{{- $length := default 16 $params.length -}}
|
||||
|
||||
{{- $existingSecret := lookup "v1" "Secret" $namespace $secretName -}}
|
||||
{{- if and $existingSecret (index $existingSecret.data $key) -}}
|
||||
{{- index $existingSecret.data $key | b64dec -}}
|
||||
{{- else -}}
|
||||
{{- randAlphaNum $length -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- /*
|
||||
Render a component’s topologySpreadConstraints exactly as given in values,
|
||||
respecting string vs. list, and providing the component name for tpl lookups.
|
||||
|
||||
Usage:
|
||||
{{ include "seaweedfs.topologySpreadConstraints" (dict "Values" .Values "component" "filer") | nindent 8 }}
|
||||
*/ -}}
|
||||
{{- define "seaweedfs.topologySpreadConstraints" -}}
|
||||
{{- $vals := .Values -}}
|
||||
{{- $comp := .component -}}
|
||||
{{- $section := index $vals $comp | default dict -}}
|
||||
{{- $tsp := index $section "topologySpreadConstraints" -}}
|
||||
{{- with $tsp }}
|
||||
topologySpreadConstraints:
|
||||
{{- if kindIs "string" $tsp }}
|
||||
{{ tpl $tsp (dict "Values" $vals "component" $comp) }}
|
||||
{{- else }}
|
||||
{{ toYaml $tsp }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,427 @@
|
||||
{{- if .Values.allInOne.enabled }}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ template "seaweedfs.name" . }}-all-in-one
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: seaweedfs-all-in-one
|
||||
{{- if .Values.allInOne.annotations }}
|
||||
annotations:
|
||||
{{- toYaml .Values.allInOne.annotations | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: seaweedfs-all-in-one
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: seaweedfs-all-in-one
|
||||
{{- with .Values.podLabels }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.allInOne.podLabels }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
annotations:
|
||||
{{- with .Values.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.allInOne.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
restartPolicy: {{ default .Values.global.restartPolicy .Values.allInOne.restartPolicy }}
|
||||
{{- if .Values.allInOne.affinity }}
|
||||
affinity:
|
||||
{{ tpl .Values.allInOne.affinity . | nindent 8 | trim }}
|
||||
{{- end }}
|
||||
{{- if .Values.allInOne.topologySpreadConstraints }}
|
||||
{{- include "seaweedfs.topologySpreadConstraints" (dict "Values" .Values "component" "all-in-one") | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- if .Values.allInOne.tolerations }}
|
||||
tolerations:
|
||||
{{- tpl .Values.allInOne.tolerations . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- include "seaweedfs.imagePullSecrets" . | nindent 6 }}
|
||||
terminationGracePeriodSeconds: 60
|
||||
enableServiceLinks: false
|
||||
{{- if .Values.allInOne.priorityClassName }}
|
||||
priorityClassName: {{ .Values.allInOne.priorityClassName | quote }}
|
||||
{{- end }}
|
||||
{{- if .Values.allInOne.serviceAccountName }}
|
||||
serviceAccountName: {{ .Values.allInOne.serviceAccountName | quote }}
|
||||
{{- end }}
|
||||
{{- if .Values.allInOne.initContainers }}
|
||||
initContainers:
|
||||
{{- tpl .Values.allInOne.initContainers . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.allInOne.podSecurityContext.enabled }}
|
||||
securityContext:
|
||||
{{- omit .Values.allInOne.podSecurityContext "enabled" | toYaml | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: seaweedfs
|
||||
image: {{ template "master.image" . }}
|
||||
imagePullPolicy: {{ default "IfNotPresent" .Values.global.imagePullPolicy }}
|
||||
env:
|
||||
- name: POD_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: SEAWEEDFS_FULLNAME
|
||||
value: "{{ template "seaweedfs.name" . }}"
|
||||
{{- if .Values.allInOne.extraEnvironmentVars }}
|
||||
{{- range $key, $value := .Values.allInOne.extraEnvironmentVars }}
|
||||
- name: {{ $key }}
|
||||
{{- if kindIs "string" $value }}
|
||||
value: {{ $value | quote }}
|
||||
{{- else }}
|
||||
valueFrom:
|
||||
{{ toYaml $value | nindent 16 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.global.extraEnvironmentVars }}
|
||||
{{- range $key, $value := .Values.global.extraEnvironmentVars }}
|
||||
- name: {{ $key }}
|
||||
{{- if kindIs "string" $value }}
|
||||
value: {{ $value | quote }}
|
||||
{{- else }}
|
||||
valueFrom:
|
||||
{{ toYaml $value | nindent 16 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
command:
|
||||
- "/bin/sh"
|
||||
- "-ec"
|
||||
- |
|
||||
/usr/bin/weed \
|
||||
-v={{ .Values.global.loggingLevel }} \
|
||||
server \
|
||||
-dir=/data \
|
||||
-master \
|
||||
-volume \
|
||||
-ip=${POD_IP} \
|
||||
-ip.bind=0.0.0.0 \
|
||||
{{- if .Values.allInOne.idleTimeout }}
|
||||
-idleTimeout={{ .Values.allInOne.idleTimeout }} \
|
||||
{{- end }}
|
||||
{{- if .Values.allInOne.dataCenter }}
|
||||
-dataCenter={{ .Values.allInOne.dataCenter }} \
|
||||
{{- end }}
|
||||
{{- if .Values.allInOne.rack }}
|
||||
-rack={{ .Values.allInOne.rack }} \
|
||||
{{- end }}
|
||||
{{- if .Values.allInOne.whiteList }}
|
||||
-whiteList={{ .Values.allInOne.whiteList }} \
|
||||
{{- end }}
|
||||
{{- if .Values.allInOne.disableHttp }}
|
||||
-disableHttp={{ .Values.allInOne.disableHttp }} \
|
||||
{{- end }}
|
||||
-master.port={{ .Values.master.port }} \
|
||||
{{- if .Values.global.enableReplication }}
|
||||
-master.defaultReplication={{ .Values.global.replicationPlacement }} \
|
||||
{{- else }}
|
||||
-master.defaultReplication={{ .Values.master.defaultReplication }} \
|
||||
{{- end }}
|
||||
{{- if .Values.master.volumePreallocate }}
|
||||
-master.volumePreallocate \
|
||||
{{- end }}
|
||||
-master.volumeSizeLimitMB={{ .Values.master.volumeSizeLimitMB }} \
|
||||
{{- if .Values.master.garbageThreshold }}
|
||||
-master.garbageThreshold={{ .Values.master.garbageThreshold }} \
|
||||
{{- end }}
|
||||
-volume.port={{ .Values.volume.port }} \
|
||||
-volume.readMode={{ .Values.volume.readMode }} \
|
||||
{{- if .Values.volume.imagesFixOrientation }}
|
||||
-volume.images.fix.orientation \
|
||||
{{- end }}
|
||||
{{- if .Values.volume.index }}
|
||||
-volume.index={{ .Values.volume.index }} \
|
||||
{{- end }}
|
||||
{{- if .Values.volume.fileSizeLimitMB }}
|
||||
-volume.fileSizeLimitMB={{ .Values.volume.fileSizeLimitMB }} \
|
||||
{{- end }}
|
||||
-volume.minFreeSpacePercent={{ .Values.volume.minFreeSpacePercent }} \
|
||||
-volume.compactionMBps={{ .Values.volume.compactionMBps }} \
|
||||
{{- if .Values.allInOne.metricsPort }}
|
||||
-metricsPort={{ .Values.allInOne.metricsPort }} \
|
||||
{{- else if .Values.master.metricsPort }}
|
||||
-metricsPort={{ .Values.master.metricsPort }} \
|
||||
{{- end }}
|
||||
-filer \
|
||||
-filer.port={{ .Values.filer.port }} \
|
||||
{{- if .Values.filer.disableDirListing }}
|
||||
-filer.disableDirListing \
|
||||
{{- end }}
|
||||
-filer.dirListLimit={{ .Values.filer.dirListLimit }} \
|
||||
{{- if .Values.global.enableReplication }}
|
||||
-filer.defaultReplicaPlacement={{ .Values.global.replicationPlacement }} \
|
||||
{{- else }}
|
||||
-filer.defaultReplicaPlacement={{ .Values.filer.defaultReplicaPlacement }} \
|
||||
{{- end }}
|
||||
{{- if .Values.filer.maxMB }}
|
||||
-filer.maxMB={{ .Values.filer.maxMB }} \
|
||||
{{- end }}
|
||||
{{- if .Values.filer.encryptVolumeData }}
|
||||
-filer.encryptVolumeData \
|
||||
{{- end }}
|
||||
{{- if .Values.filer.filerGroup}}
|
||||
-filer.filerGroup={{ .Values.filer.filerGroup}} \
|
||||
{{- end }}
|
||||
{{- if .Values.filer.rack }}
|
||||
-filer.rack={{ .Values.filer.rack }} \
|
||||
{{- end }}
|
||||
{{- if .Values.filer.dataCenter }}
|
||||
-filer.dataCenter={{ .Values.filer.dataCenter }} \
|
||||
{{- end }}
|
||||
{{- if .Values.allInOne.s3.enabled }}
|
||||
-s3 \
|
||||
-s3.port={{ .Values.s3.port }} \
|
||||
{{- if .Values.s3.domainName }}
|
||||
-s3.domainName={{ .Values.s3.domainName }} \
|
||||
{{- end }}
|
||||
{{- if .Values.global.enableSecurity }}
|
||||
{{- if .Values.s3.httpsPort }}
|
||||
-s3.port.https={{ .Values.s3.httpsPort }} \
|
||||
{{- end }}
|
||||
-s3.cert.file=/usr/local/share/ca-certificates/client/tls.crt \
|
||||
-s3.key.file=/usr/local/share/ca-certificates/client/tls.key \
|
||||
{{- end }}
|
||||
{{- if eq (typeOf .Values.s3.allowEmptyFolder) "bool" }}
|
||||
-s3.allowEmptyFolder={{ .Values.s3.allowEmptyFolder }} \
|
||||
{{- end }}
|
||||
{{- if .Values.s3.enableAuth }}
|
||||
-s3.config=/etc/sw/s3/seaweedfs_s3_config \
|
||||
{{- end }}
|
||||
{{- if .Values.s3.auditLogConfig }}
|
||||
-s3.auditLogConfig=/etc/sw/s3/s3_auditLogConfig.json \
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.allInOne.sftp.enabled }}
|
||||
-sftp \
|
||||
-sftp.port={{ .Values.sftp.port }} \
|
||||
{{- if .Values.sftp.sshPrivateKey }}
|
||||
-sftp.sshPrivateKey={{ .Values.sftp.sshPrivateKey }} \
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.hostKeysFolder }}
|
||||
-sftp.hostKeysFolder={{ .Values.sftp.hostKeysFolder }} \
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.authMethods }}
|
||||
-sftp.authMethods={{ .Values.sftp.authMethods }} \
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.maxAuthTries }}
|
||||
-sftp.maxAuthTries={{ .Values.sftp.maxAuthTries }} \
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.bannerMessage }}
|
||||
-sftp.bannerMessage="{{ .Values.sftp.bannerMessage }}" \
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.loginGraceTime }}
|
||||
-sftp.loginGraceTime={{ .Values.sftp.loginGraceTime }} \
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.clientAliveInterval }}
|
||||
-sftp.clientAliveInterval={{ .Values.sftp.clientAliveInterval }} \
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.clientAliveCountMax }}
|
||||
-sftp.clientAliveCountMax={{ .Values.sftp.clientAliveCountMax }} \
|
||||
{{- end }}
|
||||
-sftp.userStoreFile=/etc/sw/sftp/seaweedfs_sftp_config \
|
||||
{{- end }}
|
||||
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
{{- if and .Values.allInOne.s3.enabled (or .Values.s3.enableAuth .Values.filer.s3.enableAuth) }}
|
||||
- name: config-s3-users
|
||||
mountPath: /etc/sw/s3
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- if .Values.allInOne.sftp.enabled }}
|
||||
- name: config-ssh
|
||||
mountPath: /etc/sw/ssh
|
||||
readOnly: true
|
||||
- mountPath: /etc/sw/sftp
|
||||
name: config-users
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- if .Values.filer.notificationConfig }}
|
||||
- name: notification-config
|
||||
mountPath: /etc/seaweedfs/notification.toml
|
||||
subPath: notification.toml
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
- name: master-config
|
||||
mountPath: /etc/seaweedfs/master.toml
|
||||
subPath: master.toml
|
||||
readOnly: true
|
||||
{{- if .Values.global.enableSecurity }}
|
||||
- name: security-config
|
||||
mountPath: /etc/seaweedfs/security.toml
|
||||
subPath: security.toml
|
||||
readOnly: true
|
||||
- name: ca-cert
|
||||
mountPath: /usr/local/share/ca-certificates/ca/
|
||||
readOnly: true
|
||||
- name: master-cert
|
||||
mountPath: /usr/local/share/ca-certificates/master/
|
||||
readOnly: true
|
||||
- name: volume-cert
|
||||
mountPath: /usr/local/share/ca-certificates/volume/
|
||||
readOnly: true
|
||||
- name: filer-cert
|
||||
mountPath: /usr/local/share/ca-certificates/filer/
|
||||
readOnly: true
|
||||
- name: client-cert
|
||||
mountPath: /usr/local/share/ca-certificates/client/
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{ tpl .Values.allInOne.extraVolumeMounts . | nindent 12 }}
|
||||
ports:
|
||||
- containerPort: {{ .Values.master.port }}
|
||||
name: swfs-mas
|
||||
- containerPort: {{ .Values.master.grpcPort }}
|
||||
name: swfs-mas-grpc
|
||||
- containerPort: {{ .Values.volume.port }}
|
||||
name: swfs-vol
|
||||
- containerPort: {{ .Values.volume.grpcPort }}
|
||||
name: swfs-vol-grpc
|
||||
- containerPort: {{ .Values.filer.port }}
|
||||
name: swfs-fil
|
||||
- containerPort: {{ .Values.filer.grpcPort }}
|
||||
name: swfs-fil-grpc
|
||||
{{- if .Values.allInOne.s3.enabled }}
|
||||
- containerPort: {{ .Values.s3.port }}
|
||||
name: swfs-s3
|
||||
{{- if .Values.s3.httpsPort }}
|
||||
- containerPort: {{ .Values.s3.httpsPort }}
|
||||
name: swfs-s3-tls
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.allInOne.sftp.enabled }}
|
||||
- containerPort: {{ .Values.sftp.port }}
|
||||
name: swfs-sftp
|
||||
{{- end }}
|
||||
{{- if .Values.allInOne.metricsPort }}
|
||||
- containerPort: {{ .Values.allInOne.metricsPort }}
|
||||
name: server-metrics
|
||||
{{- end }}
|
||||
{{- if .Values.allInOne.readinessProbe.enabled }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: {{ .Values.allInOne.readinessProbe.httpGet.path }}
|
||||
port: {{ .Values.master.port }}
|
||||
scheme: {{ .Values.allInOne.readinessProbe.scheme }}
|
||||
initialDelaySeconds: {{ .Values.allInOne.readinessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.allInOne.readinessProbe.periodSeconds }}
|
||||
successThreshold: {{ .Values.allInOne.readinessProbe.successThreshold }}
|
||||
failureThreshold: {{ .Values.allInOne.readinessProbe.failureThreshold }}
|
||||
timeoutSeconds: {{ .Values.allInOne.readinessProbe.timeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- if .Values.allInOne.livenessProbe.enabled }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: {{ .Values.allInOne.livenessProbe.httpGet.path }}
|
||||
port: {{ .Values.master.port }}
|
||||
scheme: {{ .Values.allInOne.livenessProbe.scheme }}
|
||||
initialDelaySeconds: {{ .Values.allInOne.livenessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.allInOne.livenessProbe.periodSeconds }}
|
||||
successThreshold: {{ .Values.allInOne.livenessProbe.successThreshold }}
|
||||
failureThreshold: {{ .Values.allInOne.livenessProbe.failureThreshold }}
|
||||
timeoutSeconds: {{ .Values.allInOne.livenessProbe.timeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- with .Values.allInOne.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.allInOne.containerSecurityContext.enabled }}
|
||||
securityContext:
|
||||
{{- omit .Values.allInOne.containerSecurityContext "enabled" | toYaml | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.allInOne.sidecars }}
|
||||
{{- include "common.tplvalues.render" (dict "value" .Values.allInOne.sidecars "context" $) | nindent 8 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: data
|
||||
{{- if eq .Values.allInOne.data.type "hostPath" }}
|
||||
hostPath:
|
||||
path: {{ .Values.allInOne.data.hostPathPrefix }}/seaweedfs-all-in-one-data/
|
||||
type: DirectoryOrCreate
|
||||
{{- else if eq .Values.allInOne.data.type "persistentVolumeClaim" }}
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Values.allInOne.data.claimName }}
|
||||
{{- else if eq .Values.allInOne.data.type "emptyDir" }}
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- if and .Values.allInOne.s3.enabled (or .Values.s3.enableAuth .Values.filer.s3.enableAuth) }}
|
||||
- name: config-s3-users
|
||||
secret:
|
||||
defaultMode: 420
|
||||
secretName: {{ default (printf "%s-s3-secret" (include "seaweedfs.name" .)) (or .Values.s3.existingConfigSecret .Values.filer.s3.existingConfigSecret) }}
|
||||
{{- end }}
|
||||
{{- if .Values.allInOne.sftp.enabled }}
|
||||
- name: config-ssh
|
||||
secret:
|
||||
defaultMode: 420
|
||||
secretName: {{ default (printf "%s-sftp-ssh-secret" (include "seaweedfs.name" .)) .Values.sftp.existingSshConfigSecret }}
|
||||
- name: config-users
|
||||
secret:
|
||||
defaultMode: 420
|
||||
secretName: {{ default (printf "%s-sftp-secret" (include "seaweedfs.name" .)) .Values.sftp.existingConfigSecret }}
|
||||
{{- end }}
|
||||
{{- if .Values.filer.notificationConfig }}
|
||||
- name: notification-config
|
||||
configMap:
|
||||
name: {{ template "seaweedfs.name" . }}-notification-config
|
||||
{{- end }}
|
||||
- name: master-config
|
||||
configMap:
|
||||
name: {{ template "seaweedfs.name" . }}-master-config
|
||||
{{- if .Values.global.enableSecurity }}
|
||||
- name: security-config
|
||||
configMap:
|
||||
name: {{ template "seaweedfs.name" . }}-security-config
|
||||
- name: ca-cert
|
||||
secret:
|
||||
secretName: {{ template "seaweedfs.name" . }}-ca-cert
|
||||
- name: master-cert
|
||||
secret:
|
||||
secretName: {{ template "seaweedfs.name" . }}-master-cert
|
||||
- name: volume-cert
|
||||
secret:
|
||||
secretName: {{ template "seaweedfs.name" . }}-volume-cert
|
||||
- name: filer-cert
|
||||
secret:
|
||||
secretName: {{ template "seaweedfs.name" . }}-filer-cert
|
||||
- name: client-cert
|
||||
secret:
|
||||
secretName: {{ template "seaweedfs.name" . }}-client-cert
|
||||
{{- end }}
|
||||
{{ tpl .Values.allInOne.extraVolumes . | nindent 8 }}
|
||||
{{- if .Values.allInOne.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{ tpl .Values.allInOne.nodeSelector . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,21 @@
|
||||
{{- if and .Values.allInOne.enabled (eq .Values.allInOne.data.type "persistentVolumeClaim") }}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Values.allInOne.data.claimName }}
|
||||
labels:
|
||||
app.kubernetes.io/component: seaweedfs-all-in-one
|
||||
{{- if .Values.allInOne.annotations }}
|
||||
annotations:
|
||||
{{- toYaml .Values.allInOne.annotations | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.allInOne.data.size }}
|
||||
{{- if .Values.allInOne.data.storageClass }}
|
||||
storageClassName: {{ .Values.allInOne.data.storageClass }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,83 @@
|
||||
{{- if .Values.allInOne.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ template "seaweedfs.name" . }}-all-in-one
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: seaweedfs-all-in-one
|
||||
{{- if .Values.allInOne.service.annotations }}
|
||||
annotations:
|
||||
{{- toYaml .Values.allInOne.service.annotations | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
internalTrafficPolicy: {{ .Values.allInOne.service.internalTrafficPolicy | default "Cluster" }}
|
||||
ports:
|
||||
# Master ports
|
||||
- name: "swfs-master"
|
||||
port: {{ .Values.master.port }}
|
||||
targetPort: {{ .Values.master.port }}
|
||||
protocol: TCP
|
||||
- name: "swfs-master-grpc"
|
||||
port: {{ .Values.master.grpcPort }}
|
||||
targetPort: {{ .Values.master.grpcPort }}
|
||||
protocol: TCP
|
||||
|
||||
# Volume ports
|
||||
- name: "swfs-volume"
|
||||
port: {{ .Values.volume.port }}
|
||||
targetPort: {{ .Values.volume.port }}
|
||||
protocol: TCP
|
||||
- name: "swfs-volume-grpc"
|
||||
port: {{ .Values.volume.grpcPort }}
|
||||
targetPort: {{ .Values.volume.grpcPort }}
|
||||
protocol: TCP
|
||||
|
||||
# Filer ports
|
||||
- name: "swfs-filer"
|
||||
port: {{ .Values.filer.port }}
|
||||
targetPort: {{ .Values.filer.port }}
|
||||
protocol: TCP
|
||||
- name: "swfs-filer-grpc"
|
||||
port: {{ .Values.filer.grpcPort }}
|
||||
targetPort: {{ .Values.filer.grpcPort }}
|
||||
protocol: TCP
|
||||
|
||||
# S3 ports (if enabled)
|
||||
{{- if .Values.allInOne.s3.enabled }}
|
||||
- name: "swfs-s3"
|
||||
port: {{ if .Values.allInOne.s3.enabled }}{{ .Values.s3.port }}{{ else }}{{ .Values.filer.s3.port }}{{ end }}
|
||||
targetPort: {{ if .Values.allInOne.s3.enabled }}{{ .Values.s3.port }}{{ else }}{{ .Values.filer.s3.port }}{{ end }}
|
||||
protocol: TCP
|
||||
{{- if and .Values.allInOne.s3.enabled .Values.s3.httpsPort }}
|
||||
- name: "swfs-s3-tls"
|
||||
port: {{ .Values.s3.httpsPort }}
|
||||
targetPort: {{ .Values.s3.httpsPort }}
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
# SFTP ports (if enabled)
|
||||
{{- if .Values.allInOne.sftp.enabled }}
|
||||
- name: "swfs-sftp"
|
||||
port: {{ .Values.sftp.port }}
|
||||
targetPort: {{ .Values.sftp.port }}
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
|
||||
# Server metrics port (single metrics endpoint for all services)
|
||||
{{- if .Values.allInOne.metricsPort }}
|
||||
- name: "server-metrics"
|
||||
port: {{ .Values.allInOne.metricsPort }}
|
||||
targetPort: {{ .Values.allInOne.metricsPort }}
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
|
||||
selector:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
|
||||
app.kubernetes.io/component: seaweedfs-all-in-one
|
||||
{{- end }}
|
||||
@@ -0,0 +1,29 @@
|
||||
{{- if .Values.allInOne.enabled }}
|
||||
{{- if .Values.global.monitoring.enabled }}
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: ServiceMonitor
|
||||
metadata:
|
||||
name: {{ template "seaweedfs.name" . }}-all-in-one
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: all-in-one
|
||||
{{- with .Values.global.monitoring.additionalLabels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
endpoints:
|
||||
{{- if .Values.allInOne.metricsPort }}
|
||||
- interval: 30s
|
||||
port: server-metrics
|
||||
scrapeTimeout: 5s
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
|
||||
app.kubernetes.io/component: seaweedfs-all-in-one
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -9,6 +9,7 @@ metadata:
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: objectstorage-provisioner
|
||||
spec:
|
||||
replicas: {{ .Values.cosi.replicas }}
|
||||
selector:
|
||||
@@ -39,6 +40,13 @@ spec:
|
||||
{{- end }}
|
||||
spec:
|
||||
restartPolicy: {{ default .Values.global.restartPolicy .Values.cosi.restartPolicy }}
|
||||
{{- if .Values.cosi.affinity }}
|
||||
affinity:
|
||||
{{ tpl .Values.cosi.affinity . | nindent 8 | trim }}
|
||||
{{- end }}
|
||||
{{- if .Values.cosi.topologySpreadConstraints }}
|
||||
{{- include "seaweedfs.topologySpreadConstraints" (dict "Values" .Values "component" "objectstorage-provisioner") | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- if .Values.cosi.tolerations }}
|
||||
tolerations:
|
||||
{{ tpl .Values.cosi.tolerations . | nindent 8 | trim }}
|
||||
@@ -140,6 +148,10 @@ spec:
|
||||
mountPath: /usr/local/share/ca-certificates/client/
|
||||
{{- end }}
|
||||
{{ tpl .Values.cosi.extraVolumeMounts . | nindent 12 | trim }}
|
||||
{{- with .Values.cosi.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
- name: seaweedfs-cosi-sidecar
|
||||
image: "{{ .Values.cosi.sidecar.image }}"
|
||||
imagePullPolicy: {{ default "IfNotPresent" .Values.global.imagePullPolicy }}
|
||||
@@ -153,7 +165,7 @@ spec:
|
||||
volumeMounts:
|
||||
- mountPath: /var/lib/cosi
|
||||
name: socket
|
||||
{{- with .Values.cosi.resources }}
|
||||
{{- with .Values.cosi.sidecar.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
@@ -173,7 +185,7 @@ spec:
|
||||
{{- if .Values.cosi.existingConfigSecret }}
|
||||
secretName: {{ .Values.cosi.existingConfigSecret }}
|
||||
{{- else }}
|
||||
secretName: seaweedfs-client-cert
|
||||
secretName: seaweedfs-s3-secret
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.global.enableSecurity }}
|
||||
|
||||
@@ -61,9 +61,9 @@ spec:
|
||||
affinity:
|
||||
{{ tpl .Values.filer.affinity . | nindent 8 | trim }}
|
||||
{{- end }}
|
||||
{{- with .Values.filer.topologySpreadConstraints }}
|
||||
{{- if .Values.filer.topologySpreadConstraints }}
|
||||
topologySpreadConstraints:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- include "seaweedfs.topologySpreadConstraints" (dict "Values" .Values "component" "filer") | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- if .Values.filer.tolerations }}
|
||||
tolerations:
|
||||
@@ -173,7 +173,7 @@ spec:
|
||||
{{- end }}
|
||||
-dirListLimit={{ .Values.filer.dirListLimit }} \
|
||||
{{- if .Values.global.enableReplication }}
|
||||
-defaultReplicaPlacement={{ .Values.global.replicationPlacment }} \
|
||||
-defaultReplicaPlacement={{ .Values.global.replicationPlacement }} \
|
||||
{{- else }}
|
||||
-defaultReplicaPlacement={{ .Values.filer.defaultReplicaPlacement }} \
|
||||
{{- end }}
|
||||
@@ -209,7 +209,7 @@ spec:
|
||||
-s3.cert.file=/usr/local/share/ca-certificates/client/tls.crt \
|
||||
-s3.key.file=/usr/local/share/ca-certificates/client/tls.key \
|
||||
{{- end }}
|
||||
{{- if .Values.filer.s3.allowEmptyFolder }}
|
||||
{{- if eq (typeOf .Values.filer.s3.allowEmptyFolder) "bool" }}
|
||||
-s3.allowEmptyFolder={{ .Values.filer.s3.allowEmptyFolder }} \
|
||||
{{- end }}
|
||||
{{- if .Values.filer.s3.enableAuth }}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{{- if .Values.master.enabled }}
|
||||
{{- if or .Values.master.enabled .Values.allInOne.enabled }}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
|
||||
@@ -9,6 +9,7 @@ metadata:
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: master
|
||||
{{- if .Values.master.annotations }}
|
||||
annotations:
|
||||
{{- toYaml .Values.master.annotations | nindent 4 }}
|
||||
@@ -54,9 +55,8 @@ spec:
|
||||
affinity:
|
||||
{{ tpl .Values.master.affinity . | nindent 8 | trim }}
|
||||
{{- end }}
|
||||
{{- with .Values.master.topologySpreadConstraints }}
|
||||
topologySpreadConstraints:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- if .Values.master.topologySpreadConstraints }}
|
||||
{{- include "seaweedfs.topologySpreadConstraints" (dict "Values" .Values "component" "master") | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- if .Values.master.tolerations }}
|
||||
tolerations:
|
||||
@@ -139,7 +139,7 @@ spec:
|
||||
-mdir=/data \
|
||||
-ip.bind={{ .Values.master.ipBind }} \
|
||||
{{- if .Values.global.enableReplication }}
|
||||
-defaultReplication={{ .Values.global.replicationPlacment }} \
|
||||
-defaultReplication={{ .Values.global.replicationPlacement }} \
|
||||
{{- else }}
|
||||
-defaultReplication={{ .Values.master.defaultReplication }} \
|
||||
{{- end }}
|
||||
|
||||
@@ -9,6 +9,7 @@ metadata:
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: s3
|
||||
{{- if .Values.s3.annotations }}
|
||||
annotations:
|
||||
{{- toYaml .Values.s3.annotations | nindent 4 }}
|
||||
@@ -42,6 +43,13 @@ spec:
|
||||
{{- end }}
|
||||
spec:
|
||||
restartPolicy: {{ default .Values.global.restartPolicy .Values.s3.restartPolicy }}
|
||||
{{- if .Values.s3.affinity }}
|
||||
affinity:
|
||||
{{ tpl .Values.s3.affinity . | nindent 8 | trim }}
|
||||
{{- end }}
|
||||
{{- if .Values.s3.topologySpreadConstraints }}
|
||||
{{- include "seaweedfs.topologySpreadConstraints" (dict "Values" .Values "component" "s3") | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- if .Values.s3.tolerations }}
|
||||
tolerations:
|
||||
{{ tpl .Values.s3.tolerations . | nindent 8 | trim }}
|
||||
@@ -134,7 +142,7 @@ spec:
|
||||
{{- if .Values.s3.domainName }}
|
||||
-domainName={{ .Values.s3.domainName }} \
|
||||
{{- end }}
|
||||
{{- if .Values.s3.allowEmptyFolder }}
|
||||
{{- if eq (typeOf .Values.s3.allowEmptyFolder) "bool" }}
|
||||
-allowEmptyFolder={{ .Values.s3.allowEmptyFolder }} \
|
||||
{{- end }}
|
||||
{{- if .Values.s3.enableAuth }}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{{- if or (and .Values.filer.s3.enabled .Values.filer.s3.enableAuth (not .Values.filer.s3.existingConfigSecret)) (and .Values.s3.enabled .Values.s3.enableAuth (not .Values.s3.existingConfigSecret)) }}
|
||||
{{- $access_key_admin := randAlphaNum 16 -}}
|
||||
{{- $secret_key_admin := randAlphaNum 32 -}}
|
||||
{{- $access_key_read := randAlphaNum 16 -}}
|
||||
{{- $secret_key_read := randAlphaNum 32 -}}
|
||||
{{- if or (and (or .Values.s3.enabled .Values.allInOne.enabled) .Values.s3.enableAuth (not .Values.s3.existingConfigSecret)) (and .Values.filer.s3.enabled .Values.filer.s3.enableAuth (not .Values.filer.s3.existingConfigSecret)) }}
|
||||
{{- $access_key_admin := include "getOrGeneratePassword" (dict "namespace" .Release.Namespace "secretName" "seaweedfs-s3-secret" "key" "admin_access_key_id" "length" 20) -}}
|
||||
{{- $secret_key_admin := include "getOrGeneratePassword" (dict "namespace" .Release.Namespace "secretName" "seaweedfs-s3-secret" "key" "admin_secret_access_key" "length" 40) -}}
|
||||
{{- $access_key_read := include "getOrGeneratePassword" (dict "namespace" .Release.Namespace "secretName" "seaweedfs-s3-secret" "key" "read_access_key_id" "length" 20) -}}
|
||||
{{- $secret_key_read := include "getOrGeneratePassword" (dict "namespace" .Release.Namespace "secretName" "seaweedfs-s3-secret" "key" "read_secret_access_key" "length" 40) -}}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
@@ -11,7 +11,7 @@ metadata:
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
"helm.sh/resource-policy": keep
|
||||
"helm.sh/hook": "pre-install"
|
||||
"helm.sh/hook": "pre-install,pre-upgrade"
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
|
||||
@@ -32,4 +32,4 @@ stringData:
|
||||
s3_auditLogConfig.json: |
|
||||
{{ toJson .Values.s3.auditLogConfig | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,20 +1,19 @@
|
||||
{{- if .Values.global.monitoring.enabled }}
|
||||
{{- $files := .Files.Glob "dashboards/*.json" }}
|
||||
{{- if $files }}
|
||||
apiVersion: v1
|
||||
kind: ConfigMapList
|
||||
items:
|
||||
{{- range $path, $fileContents := $files }}
|
||||
{{- range $path, $file := $files }}
|
||||
{{- $dashboardName := regexReplaceAll "(^.*/)(.*)\\.json$" $path "${2}" }}
|
||||
- apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ printf "%s" $dashboardName | lower | replace "_" "-" }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
grafana_dashboard: "1"
|
||||
data:
|
||||
{{ $dashboardName }}.json: {{ $.Files.Get $path | toJson }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ printf "%s" $dashboardName | lower | replace "_" "-" }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
grafana_dashboard: "1"
|
||||
data:
|
||||
{{ $dashboardName }}.json: |-
|
||||
{{ toString $file | indent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,300 @@
|
||||
{{- if .Values.sftp.enabled }}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ template "seaweedfs.name" . }}-sftp
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: sftp
|
||||
{{- if .Values.sftp.annotations }}
|
||||
annotations:
|
||||
{{- toYaml .Values.sftp.annotations | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
replicas: {{ .Values.sftp.replicas }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: sftp
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: sftp
|
||||
{{ with .Values.podLabels }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.sftp.podLabels }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
annotations:
|
||||
{{ with .Values.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.sftp.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
restartPolicy: {{ default .Values.global.restartPolicy .Values.sftp.restartPolicy }}
|
||||
{{- if .Values.sftp.affinity }}
|
||||
affinity:
|
||||
{{ tpl .Values.sftp.affinity . | nindent 8 | trim }}
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.topologySpreadConstraints }}
|
||||
{{- include "seaweedfs.topologySpreadConstraints" (dict "Values" .Values "component" "sftp") | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.tolerations }}
|
||||
tolerations:
|
||||
{{ tpl .Values.sftp.tolerations . | nindent 8 | trim }}
|
||||
{{- end }}
|
||||
{{- include "seaweedfs.imagePullSecrets" . | nindent 6 }}
|
||||
terminationGracePeriodSeconds: 10
|
||||
{{- if .Values.sftp.priorityClassName }}
|
||||
priorityClassName: {{ .Values.sftp.priorityClassName | quote }}
|
||||
{{- end }}
|
||||
enableServiceLinks: false
|
||||
{{- if .Values.sftp.serviceAccountName }}
|
||||
serviceAccountName: {{ .Values.sftp.serviceAccountName | quote }}
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.initContainers }}
|
||||
initContainers:
|
||||
{{ tpl .Values.sftp.initContainers . | nindent 8 | trim }}
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.podSecurityContext.enabled }}
|
||||
securityContext: {{- omit .Values.sftp.podSecurityContext "enabled" | toYaml | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: seaweedfs
|
||||
image: {{ template "sftp.image" . }}
|
||||
imagePullPolicy: {{ default "IfNotPresent" .Values.global.imagePullPolicy }}
|
||||
env:
|
||||
- name: POD_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: SEAWEEDFS_FULLNAME
|
||||
value: "{{ template "seaweedfs.name" . }}"
|
||||
{{- if .Values.sftp.extraEnvironmentVars }}
|
||||
{{- range $key, $value := .Values.sftp.extraEnvironmentVars }}
|
||||
- name: {{ $key }}
|
||||
{{- if kindIs "string" $value }}
|
||||
value: {{ $value | quote }}
|
||||
{{- else }}
|
||||
valueFrom:
|
||||
{{ toYaml $value | nindent 16 | trim }}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.global.extraEnvironmentVars }}
|
||||
{{- range $key, $value := .Values.global.extraEnvironmentVars }}
|
||||
- name: {{ $key }}
|
||||
{{- if kindIs "string" $value }}
|
||||
value: {{ $value | quote }}
|
||||
{{- else }}
|
||||
valueFrom:
|
||||
{{ toYaml $value | nindent 16 | trim }}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
command:
|
||||
- "/bin/sh"
|
||||
- "-ec"
|
||||
- |
|
||||
exec /usr/bin/weed \
|
||||
{{- if or (eq .Values.sftp.logs.type "hostPath") (eq .Values.sftp.logs.type "emptyDir") }}
|
||||
-logdir=/logs \
|
||||
{{- else }}
|
||||
-logtostderr=true \
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.loggingOverrideLevel }}
|
||||
-v={{ .Values.sftp.loggingOverrideLevel }} \
|
||||
{{- else }}
|
||||
-v={{ .Values.global.loggingLevel }} \
|
||||
{{- end }}
|
||||
sftp \
|
||||
-ip.bind={{ .Values.sftp.bindAddress }} \
|
||||
-port={{ .Values.sftp.port }} \
|
||||
{{- if .Values.sftp.metricsPort }}
|
||||
-metricsPort={{ .Values.sftp.metricsPort }} \
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.metricsIp }}
|
||||
-metricsIp={{ .Values.sftp.metricsIp }} \
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.sshPrivateKey }}
|
||||
-sshPrivateKey={{ .Values.sftp.sshPrivateKey }} \
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.hostKeysFolder }}
|
||||
-hostKeysFolder={{ .Values.sftp.hostKeysFolder }} \
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.authMethods }}
|
||||
-authMethods={{ .Values.sftp.authMethods }} \
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.maxAuthTries }}
|
||||
-maxAuthTries={{ .Values.sftp.maxAuthTries }} \
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.bannerMessage }}
|
||||
-bannerMessage="{{ .Values.sftp.bannerMessage }}" \
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.loginGraceTime }}
|
||||
-loginGraceTime={{ .Values.sftp.loginGraceTime }} \
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.clientAliveInterval }}
|
||||
-clientAliveInterval={{ .Values.sftp.clientAliveInterval }} \
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.clientAliveCountMax }}
|
||||
-clientAliveCountMax={{ .Values.sftp.clientAliveCountMax }} \
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.dataCenter }}
|
||||
-dataCenter={{ .Values.sftp.dataCenter }} \
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.localSocket }}
|
||||
-localSocket={{ .Values.sftp.localSocket }} \
|
||||
{{- end }}
|
||||
{{- if .Values.global.enableSecurity }}
|
||||
-cert.file=/usr/local/share/ca-certificates/client/tls.crt \
|
||||
-key.file=/usr/local/share/ca-certificates/client/tls.key \
|
||||
{{- end }}
|
||||
-userStoreFile=/etc/sw/seaweedfs_sftp_config \
|
||||
-filer={{ template "seaweedfs.name" . }}-filer-client.{{ .Release.Namespace }}:{{ .Values.filer.port }}
|
||||
volumeMounts:
|
||||
{{- if or (eq .Values.sftp.logs.type "hostPath") (eq .Values.sftp.logs.type "emptyDir") }}
|
||||
- name: logs
|
||||
mountPath: "/logs/"
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.enableAuth }}
|
||||
- mountPath: /etc/sw
|
||||
name: config-users
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
- mountPath: /etc/sw/ssh
|
||||
name: config-ssh
|
||||
readOnly: true
|
||||
{{- if .Values.global.enableSecurity }}
|
||||
- name: security-config
|
||||
readOnly: true
|
||||
mountPath: /etc/seaweedfs/security.toml
|
||||
subPath: security.toml
|
||||
- name: ca-cert
|
||||
readOnly: true
|
||||
mountPath: /usr/local/share/ca-certificates/ca/
|
||||
- name: master-cert
|
||||
readOnly: true
|
||||
mountPath: /usr/local/share/ca-certificates/master/
|
||||
- name: volume-cert
|
||||
readOnly: true
|
||||
mountPath: /usr/local/share/ca-certificates/volume/
|
||||
- name: filer-cert
|
||||
readOnly: true
|
||||
mountPath: /usr/local/share/ca-certificates/filer/
|
||||
- name: client-cert
|
||||
readOnly: true
|
||||
mountPath: /usr/local/share/ca-certificates/client/
|
||||
{{- end }}
|
||||
{{ tpl .Values.sftp.extraVolumeMounts . | nindent 12 | trim }}
|
||||
ports:
|
||||
- containerPort: {{ .Values.sftp.port }}
|
||||
name: swfs-sftp
|
||||
{{- if .Values.sftp.metricsPort }}
|
||||
- containerPort: {{ .Values.sftp.metricsPort }}
|
||||
name: metrics
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.readinessProbe.enabled }}
|
||||
readinessProbe:
|
||||
tcpSocket:
|
||||
port: {{ .Values.sftp.port }}
|
||||
initialDelaySeconds: {{ .Values.sftp.readinessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.sftp.readinessProbe.periodSeconds }}
|
||||
successThreshold: {{ .Values.sftp.readinessProbe.successThreshold }}
|
||||
failureThreshold: {{ .Values.sftp.readinessProbe.failureThreshold }}
|
||||
timeoutSeconds: {{ .Values.sftp.readinessProbe.timeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.livenessProbe.enabled }}
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
port: {{ .Values.sftp.port }}
|
||||
initialDelaySeconds: {{ .Values.sftp.livenessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.sftp.livenessProbe.periodSeconds }}
|
||||
successThreshold: {{ .Values.sftp.livenessProbe.successThreshold }}
|
||||
failureThreshold: {{ .Values.sftp.livenessProbe.failureThreshold }}
|
||||
timeoutSeconds: {{ .Values.sftp.livenessProbe.timeoutSeconds }}
|
||||
{{- end }}
|
||||
{{- with .Values.sftp.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.containerSecurityContext.enabled }}
|
||||
securityContext: {{- omit .Values.sftp.containerSecurityContext "enabled" | toYaml | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.sidecars }}
|
||||
{{- include "common.tplvalues.render" (dict "value" .Values.sftp.sidecars "context" $) | nindent 8 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
{{- if .Values.sftp.enableAuth }}
|
||||
- name: config-users
|
||||
secret:
|
||||
defaultMode: 420
|
||||
{{- if .Values.sftp.existingConfigSecret }}
|
||||
secretName: {{ .Values.sftp.existingConfigSecret }}
|
||||
{{- else }}
|
||||
secretName: seaweedfs-sftp-secret
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
- name: config-ssh
|
||||
secret:
|
||||
defaultMode: 420
|
||||
{{- if .Values.sftp.existingSshConfigSecret }}
|
||||
secretName: {{ .Values.sftp.existingSshConfigSecret }}
|
||||
{{- else }}
|
||||
secretName: seaweedfs-sftp-ssh-secret
|
||||
{{- end }}
|
||||
{{- if eq .Values.sftp.logs.type "hostPath" }}
|
||||
- name: logs
|
||||
hostPath:
|
||||
path: {{ .Values.sftp.logs.hostPathPrefix }}/logs/seaweedfs/sftp
|
||||
type: DirectoryOrCreate
|
||||
{{- end }}
|
||||
{{- if eq .Values.sftp.logs.type "emptyDir" }}
|
||||
- name: logs
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- if .Values.global.enableSecurity }}
|
||||
- name: security-config
|
||||
configMap:
|
||||
name: {{ template "seaweedfs.name" . }}-security-config
|
||||
- name: ca-cert
|
||||
secret:
|
||||
secretName: {{ template "seaweedfs.name" . }}-ca-cert
|
||||
- name: master-cert
|
||||
secret:
|
||||
secretName: {{ template "seaweedfs.name" . }}-master-cert
|
||||
- name: volume-cert
|
||||
secret:
|
||||
secretName: {{ template "seaweedfs.name" . }}-volume-cert
|
||||
- name: filer-cert
|
||||
secret:
|
||||
secretName: {{ template "seaweedfs.name" . }}-filer-cert
|
||||
- name: client-cert
|
||||
secret:
|
||||
secretName: {{ template "seaweedfs.name" . }}-client-cert
|
||||
{{- end }}
|
||||
{{ tpl .Values.sftp.extraVolumes . | indent 8 | trim }}
|
||||
{{- if .Values.sftp.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{ tpl .Values.sftp.nodeSelector . | indent 8 | trim }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,33 @@
|
||||
{{- if or .Values.sftp.enabled .Values.allInOne.enabled }}
|
||||
{{- $admin_pwd := include "getOrGeneratePassword" (dict "namespace" .Release.Namespace "secretName" "seaweedfs-sftp-secret" "key" "admin_password" 20) -}}
|
||||
{{- $read_user_pwd := include "getOrGeneratePassword" (dict "namespace" .Release.Namespace "secretName" "seaweedfs-sftp-secret" "key" "readonly_password" 20) -}}
|
||||
{{- $public_user_pwd := include "getOrGeneratePassword" (dict "namespace" .Release.Namespace "secretName" "seaweedfs-sftp-secret" "key" "public_user_password" 20) -}}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
metadata:
|
||||
name: seaweedfs-sftp-secret
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
"helm.sh/resource-policy": keep
|
||||
"helm.sh/hook": "pre-install,pre-upgrade"
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: sftp
|
||||
stringData:
|
||||
admin_password: {{ $admin_pwd }}
|
||||
readonly_password: {{ $read_user_pwd }}
|
||||
public_user_password: {{ $public_user_pwd }}
|
||||
seaweedfs_sftp_config: '[{"Username":"admin","Password":"{{ $admin_pwd }}","PublicKeys":[],"HomeDir":"/","Permissions":{"/":["read","write","list"]},"Uid":0,"Gid":0},{"Username":"readonly_user","Password":"{{ $read_user_pwd }}","PublicKeys":[],"HomeDir":"/","Permissions":{"/":["read","list"]},"Uid":1112,"Gid":1112},{"Username":"public_user","Password":"{{ $public_user_pwd }}","PublicKeys":[],"HomeDir":"/public","Permissions":{"/public":["write","read","list"]},"Uid":1113,"Gid":1113}]'
|
||||
seaweedfs_sftp_ssh_private_key: |
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||
QyNTUxOQAAACDH4McwcDphteXVullu6q7ephEN1N60z+w0qZw0UVW8OwAAAJDjxkmk48ZJ
|
||||
pAAAAAtzc2gtZWQyNTUxOQAAACDH4McwcDphteXVullu6q7ephEN1N60z+w0qZw0UVW8Ow
|
||||
AAAEAeVy/4+gf6rjj2jla/AHqJpC1LcS5hn04IUs4q+iVq/MfgxzBwOmG15dW6WW7qrt6m
|
||||
EQ3U3rTP7DSpnDRRVbw7AAAADHNla291ckAwMDY2NwE=
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
{{- end }}
|
||||
@@ -0,0 +1,32 @@
|
||||
{{- if .Values.sftp.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ template "seaweedfs.name" . }}-sftp
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
|
||||
app.kubernetes.io/component: sftp
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- if .Values.sftp.annotations }}
|
||||
annotations:
|
||||
{{- toYaml .Values.sftp.annotations | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
internalTrafficPolicy: {{ .Values.sftp.internalTrafficPolicy | default "Cluster" }}
|
||||
ports:
|
||||
- name: "swfs-sftp"
|
||||
port: {{ .Values.sftp.port }}
|
||||
targetPort: {{ .Values.sftp.port }}
|
||||
protocol: TCP
|
||||
{{- if .Values.sftp.metricsPort }}
|
||||
- name: "metrics"
|
||||
port: {{ .Values.sftp.metricsPort }}
|
||||
targetPort: {{ .Values.sftp.metricsPort }}
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
selector:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
|
||||
app.kubernetes.io/component: sftp
|
||||
{{- end }}
|
||||
@@ -0,0 +1,33 @@
|
||||
{{- if .Values.sftp.enabled }}
|
||||
{{- if .Values.sftp.metricsPort }}
|
||||
{{- if .Values.global.monitoring.enabled }}
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: ServiceMonitor
|
||||
metadata:
|
||||
name: {{ template "seaweedfs.name" . }}-sftp
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: sftp
|
||||
{{- with .Values.global.monitoring.additionalLabels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- if .Values.sftp.annotations }}
|
||||
annotations:
|
||||
{{- toYaml .Values.sftp.annotations | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
endpoints:
|
||||
- interval: 30s
|
||||
port: metrics
|
||||
scrapeTimeout: 5s
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
|
||||
app.kubernetes.io/component: sftp
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -9,6 +9,7 @@ metadata:
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: volume
|
||||
{{- if .Values.volume.annotations }}
|
||||
annotations:
|
||||
{{- toYaml .Values.volume.annotations | nindent 4 }}
|
||||
@@ -47,9 +48,8 @@ spec:
|
||||
affinity:
|
||||
{{ tpl .Values.volume.affinity . | nindent 8 | trim }}
|
||||
{{- end }}
|
||||
{{- with .Values.volume.topologySpreadConstraints }}
|
||||
topologySpreadConstraints:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- if .Values.volume.topologySpreadConstraints }}
|
||||
{{- include "seaweedfs.topologySpreadConstraints" (dict "Values" .Values "component" "volume") | nindent 6 }}
|
||||
{{- end }}
|
||||
restartPolicy: {{ default .Values.global.restartPolicy .Values.volume.restartPolicy }}
|
||||
{{- if .Values.volume.tolerations }}
|
||||
@@ -351,7 +351,9 @@ spec:
|
||||
volumeClaimTemplates:
|
||||
{{- range $dir := .Values.volume.dataDirs }}
|
||||
{{- if eq $dir.type "persistentVolumeClaim" }}
|
||||
- metadata:
|
||||
- apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ $dir.name }}
|
||||
{{- with $dir.annotations }}
|
||||
annotations:
|
||||
@@ -367,7 +369,9 @@ spec:
|
||||
{{- end }}
|
||||
|
||||
{{- if and .Values.volume.idx (eq .Values.volume.idx.type "persistentVolumeClaim") }}
|
||||
- metadata:
|
||||
- apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: idx
|
||||
{{- with .Values.volume.idx.annotations }}
|
||||
annotations:
|
||||
@@ -381,7 +385,9 @@ spec:
|
||||
storage: {{ .Values.volume.idx.size }}
|
||||
{{- end }}
|
||||
{{- if and .Values.volume.logs (eq .Values.volume.logs.type "persistentVolumeClaim") }}
|
||||
- metadata:
|
||||
- apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: logs
|
||||
{{- with .Values.volume.logs.annotations }}
|
||||
annotations:
|
||||
|
||||
@@ -27,13 +27,13 @@ global:
|
||||
gatewayHost: null
|
||||
gatewayPort: null
|
||||
additionalLabels: {}
|
||||
# if enabled will use global.replicationPlacment and override master & filer defaultReplicaPlacement config
|
||||
# if enabled will use global.replicationPlacement and override master & filer defaultReplicaPlacement config
|
||||
enableReplication: false
|
||||
# replication type is XYZ:
|
||||
# X number of replica in other data centers
|
||||
# Y number of replica in other racks in the same data center
|
||||
# Z number of replica in other servers in the same rack
|
||||
replicationPlacment: "001"
|
||||
replicationPlacement: "001"
|
||||
extraEnvironmentVars:
|
||||
WEED_CLUSTER_DEFAULT: "sw"
|
||||
WEED_CLUSTER_SW_MASTER: "seaweedfs-master.seaweedfs:9333"
|
||||
@@ -46,6 +46,7 @@ global:
|
||||
image:
|
||||
registry: ""
|
||||
repository: ""
|
||||
tag: ""
|
||||
|
||||
master:
|
||||
enabled: true
|
||||
@@ -172,7 +173,7 @@ master:
|
||||
# Topology Spread Constraints Settings
|
||||
# This should map directly to the value of the topologySpreadConstraints
|
||||
# for a PodSpec. By Default no constraints are set.
|
||||
topologySpreadConstraints: {}
|
||||
topologySpreadConstraints: null
|
||||
|
||||
# Toleration Settings for master pods
|
||||
# This should be a multi-line string matching the Toleration array
|
||||
@@ -291,7 +292,7 @@ volume:
|
||||
# For each data disk you may use ANY storage-class, example with local-path-provisioner
|
||||
# Annotations are optional.
|
||||
# dataDirs:
|
||||
# - name: data:
|
||||
# - name: data
|
||||
# type: "persistentVolumeClaim"
|
||||
# size: "24Ti"
|
||||
# storageClass: "local-path-provisioner"
|
||||
@@ -435,7 +436,7 @@ volume:
|
||||
# Topology Spread Constraints Settings
|
||||
# This should map directly to the value of the topologySpreadConstraints
|
||||
# for a PodSpec. By Default no constraints are set.
|
||||
topologySpreadConstraints: {}
|
||||
topologySpreadConstraints: null
|
||||
|
||||
# Resource requests, limits, etc. for the server cluster placement. This
|
||||
# should map directly to the value of the resources field for a PodSpec,
|
||||
@@ -654,7 +655,7 @@ filer:
|
||||
# Topology Spread Constraints Settings
|
||||
# This should map directly to the value of the topologySpreadConstraints
|
||||
# for a PodSpec. By Default no constraints are set.
|
||||
topologySpreadConstraints: {}
|
||||
topologySpreadConstraints: null
|
||||
|
||||
# updatePartition is used to control a careful rolling update of SeaweedFS
|
||||
# masters.
|
||||
@@ -949,6 +950,215 @@ s3:
|
||||
annotations: {}
|
||||
tls: []
|
||||
|
||||
sftp:
|
||||
enabled: false
|
||||
imageOverride: null
|
||||
restartPolicy: null
|
||||
replicas: 1
|
||||
bindAddress: 0.0.0.0
|
||||
port: 2022 # Default SFTP port
|
||||
metricsPort: 9327
|
||||
metricsIp: "" # If empty, defaults to bindAddress
|
||||
loggingOverrideLevel: null
|
||||
|
||||
# SSH server configuration
|
||||
sshPrivateKey: "/etc/sw/seaweedfs_sftp_ssh_private_key" # Path to the SSH private key file for host authentication
|
||||
hostKeysFolder: "/etc/sw/ssh" # path to folder containing SSH private key files for host authentication
|
||||
authMethods: "password,publickey" # Comma-separated list of allowed auth methods: password, publickey, keyboard-interactive
|
||||
maxAuthTries: 6 # Maximum number of authentication attempts per connection
|
||||
bannerMessage: "SeaweedFS SFTP Server" # Message displayed before authentication
|
||||
loginGraceTime: "2m" # Timeout for authentication
|
||||
clientAliveInterval: "5s" # Interval for sending keep-alive messages
|
||||
clientAliveCountMax: 3 # Maximum number of missed keep-alive messages before disconnecting
|
||||
dataCenter: "" # Prefer to read and write to volumes in this data center
|
||||
localSocket: "" # Default to /tmp/seaweedfs-sftp-<port>.sock
|
||||
|
||||
# User authentication
|
||||
enableAuth: false
|
||||
# Set to the name of an existing kubernetes Secret with the sftp json config file
|
||||
# Should have a secret key called seaweedfs_sftp_config with an inline json config
|
||||
existingConfigSecret: null
|
||||
# Set to the name of an existing kubernetes Secret with the list of ssh private keys for sftp
|
||||
existingSshConfigSecret: null
|
||||
|
||||
# Additional resources
|
||||
sidecars: []
|
||||
initContainers: ""
|
||||
extraVolumes: ""
|
||||
extraVolumeMounts: ""
|
||||
podLabels: {}
|
||||
podAnnotations: {}
|
||||
annotations: {}
|
||||
resources: {}
|
||||
tolerations: ""
|
||||
nodeSelector: |
|
||||
kubernetes.io/arch: amd64
|
||||
priorityClassName: ""
|
||||
serviceAccountName: ""
|
||||
podSecurityContext: {}
|
||||
containerSecurityContext: {}
|
||||
|
||||
logs:
|
||||
type: "hostPath"
|
||||
hostPathPrefix: /storage
|
||||
|
||||
extraEnvironmentVars: {}
|
||||
|
||||
# Health checks
|
||||
# Health checks for SFTP - using tcpSocket instead of httpGet
|
||||
livenessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 60
|
||||
successThreshold: 1
|
||||
failureThreshold: 20
|
||||
timeoutSeconds: 10
|
||||
|
||||
# Health checks for SFTP - using tcpSocket instead of httpGet
|
||||
readinessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
failureThreshold: 100
|
||||
timeoutSeconds: 10
|
||||
|
||||
# All-in-one deployment configuration
|
||||
allInOne:
|
||||
enabled: false
|
||||
imageOverride: null
|
||||
restartPolicy: Always
|
||||
replicas: 1
|
||||
|
||||
# Core configuration
|
||||
idleTimeout: 30 # Connection idle seconds
|
||||
dataCenter: "" # Current volume server's data center name
|
||||
rack: "" # Current volume server's rack name
|
||||
whiteList: "" # Comma separated IP addresses having write permission
|
||||
disableHttp: false # Disable HTTP requests, only gRPC operations are allowed
|
||||
metricsPort: 9324 # Prometheus metrics listen port
|
||||
metricsIp: "" # Metrics listen IP. If empty, defaults to bindAddress
|
||||
loggingOverrideLevel: null # Override logging level
|
||||
|
||||
# Service configuration
|
||||
s3:
|
||||
enabled: false # Whether to enable S3 gateway
|
||||
sftp:
|
||||
enabled: false # Whether to enable SFTP server
|
||||
|
||||
# Service settings
|
||||
service:
|
||||
annotations: {} # Annotations for the service
|
||||
type: ClusterIP # Service type (ClusterIP, NodePort, LoadBalancer)
|
||||
|
||||
# Storage configuration
|
||||
data:
|
||||
type: "emptyDir" # Options: "hostPath", "persistentVolumeClaim", "emptyDir"
|
||||
hostPathPrefix: /mnt/data # Path prefix for hostPath volumes
|
||||
claimName: seaweedfs-data-pvc # Name of the PVC to use
|
||||
size: "" # Size of the PVC
|
||||
storageClass: "" # Storage class for the PVC
|
||||
|
||||
# Health checks
|
||||
readinessProbe:
|
||||
enabled: true
|
||||
httpGet:
|
||||
path: /cluster/status
|
||||
port: 9333
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
failureThreshold: 3
|
||||
timeoutSeconds: 5
|
||||
|
||||
livenessProbe:
|
||||
enabled: true
|
||||
httpGet:
|
||||
path: /cluster/status
|
||||
port: 9333
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 30
|
||||
successThreshold: 1
|
||||
failureThreshold: 5
|
||||
timeoutSeconds: 5
|
||||
|
||||
# Additional resources
|
||||
extraEnvironmentVars: {} # Additional environment variables
|
||||
extraVolumeMounts: "" # Additional volume mounts
|
||||
extraVolumes: "" # Additional volumes
|
||||
initContainers: "" # Init containers
|
||||
sidecars: "" # Sidecar containers
|
||||
annotations: {} # Annotations for the deployment
|
||||
podAnnotations: {} # Annotations for the pods
|
||||
podLabels: {} # Labels for the pods
|
||||
|
||||
# Scheduling configuration
|
||||
# Affinity Settings
|
||||
# Commenting out or setting as empty the affinity variable, will allow
|
||||
# deployment to single node services such as Minikube
|
||||
affinity: |
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: master
|
||||
topologyKey: kubernetes.io/hostname
|
||||
|
||||
# Topology Spread Constraints Settings
|
||||
# This should map directly to the value of the topologySpreadConstraints
|
||||
# for a PodSpec. By Default no constraints are set.
|
||||
topologySpreadConstraints: null
|
||||
|
||||
# Toleration Settings for master pods
|
||||
# This should be a multi-line string matching the Toleration array
|
||||
# in a PodSpec.
|
||||
tolerations: ""
|
||||
|
||||
# nodeSelector labels for master pod assignment, formatted as a muli-line string.
|
||||
# ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
|
||||
nodeSelector: |
|
||||
kubernetes.io/arch: amd64
|
||||
|
||||
# Used to assign priority to master pods
|
||||
# ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/
|
||||
priorityClassName: ""
|
||||
|
||||
# Used to assign a service account.
|
||||
# ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
|
||||
serviceAccountName: ""
|
||||
|
||||
# Configure security context for Pod
|
||||
# ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
|
||||
# Example:
|
||||
# podSecurityContext:
|
||||
# enabled: true
|
||||
# runAsUser: 1000
|
||||
# runAsGroup: 3000
|
||||
# fsGroup: 2000
|
||||
podSecurityContext: {}
|
||||
|
||||
# Configure security context for Container
|
||||
# ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
|
||||
# Example:
|
||||
# containerSecurityContext:
|
||||
# enabled: true
|
||||
# runAsUser: 2000
|
||||
# allowPrivilegeEscalation: false
|
||||
containerSecurityContext: {}
|
||||
|
||||
# Resource management
|
||||
resources:
|
||||
limits:
|
||||
cpu: "2"
|
||||
memory: "2Gi"
|
||||
requests:
|
||||
cpu: "500m"
|
||||
memory: "1Gi"
|
||||
|
||||
# Deploy Kubernetes COSI Driver for SeaweedFS
|
||||
# Requires COSI CRDs and controller to be installed in the cluster
|
||||
# For more information, visit: https://container-object-storage-interface.github.io/docs/deployment-guide
|
||||
@@ -962,6 +1172,11 @@ cosi:
|
||||
|
||||
sidecar:
|
||||
image: gcr.io/k8s-staging-sig-storage/objectstorage-sidecar/objectstorage-sidecar:v20230130-v0.1.0-24-gc0cf995
|
||||
# Resource requests, limits, etc. for the server cluster placement. This
|
||||
# should map directly to the value of the resources field for a PodSpec,
|
||||
# formatted as a multi-line string. By default no direct resource request
|
||||
# is made.
|
||||
resources: {}
|
||||
|
||||
# enable user & permission to s3 (need to inject to all services)
|
||||
enableAuth: false
|
||||
@@ -975,6 +1190,12 @@ cosi:
|
||||
extraVolumes: ""
|
||||
extraVolumeMounts: ""
|
||||
|
||||
# Resource requests, limits, etc. for the server cluster placement. This
|
||||
# should map directly to the value of the resources field for a PodSpec,
|
||||
# formatted as a multi-line string. By default no direct resource request
|
||||
# is made.
|
||||
resources: {}
|
||||
|
||||
certificates:
|
||||
commonName: "SeaweedFS CA"
|
||||
ipAddresses: []
|
||||
|
||||
@@ -14,11 +14,13 @@ public class FilerClient extends FilerGrpcClient {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(FilerClient.class);
|
||||
|
||||
public FilerClient(String filerHost, int filerGrpcPort) {
|
||||
super(filerHost, filerGrpcPort-10000, filerGrpcPort);
|
||||
this(filerHost, filerGrpcPort-10000, filerGrpcPort, "");
|
||||
}
|
||||
public FilerClient(String filerHost, int filerGrpcPort, String cn) { this(filerHost, filerGrpcPort-10000, filerGrpcPort, cn); }
|
||||
public FilerClient(String filerHost, int filerPort, int filerGrpcPort) { this(filerHost, filerPort, filerGrpcPort, ""); }
|
||||
|
||||
public FilerClient(String filerHost, int filerPort, int filerGrpcPort) {
|
||||
super(filerHost, filerPort, filerGrpcPort);
|
||||
public FilerClient(String filerHost, int filerPort, int filerGrpcPort, String cn) {
|
||||
super(filerHost, filerPort, filerGrpcPort, cn);
|
||||
}
|
||||
|
||||
public static String toFileId(FilerProto.FileId fid) {
|
||||
|
||||
@@ -8,7 +8,6 @@ import io.grpc.netty.shaded.io.netty.handler.ssl.SslContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.net.ssl.SSLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
@@ -17,14 +16,12 @@ import java.util.concurrent.TimeUnit;
|
||||
public class FilerGrpcClient {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(FilerGrpcClient.class);
|
||||
static SslContext sslContext;
|
||||
private static final SslContext sslContext;
|
||||
private static final String protocol;
|
||||
|
||||
static {
|
||||
try {
|
||||
sslContext = FilerSslContext.loadSslContext();
|
||||
} catch (SSLException e) {
|
||||
logger.warn("failed to load ssl context", e);
|
||||
}
|
||||
sslContext = FilerSecurityContext.getGrpcSslContext();
|
||||
protocol = FilerSecurityContext.isHttpSecurityEnabled() ? "https" : "http";
|
||||
}
|
||||
|
||||
public final int VOLUME_SERVER_ACCESS_DIRECT = 0;
|
||||
@@ -42,19 +39,27 @@ public class FilerGrpcClient {
|
||||
private int volumeServerAccess = VOLUME_SERVER_ACCESS_DIRECT;
|
||||
private String filerAddress;
|
||||
|
||||
public FilerGrpcClient(String host, int port, int grpcPort) {
|
||||
this(host, port, grpcPort, sslContext);
|
||||
public FilerGrpcClient(String host, int port, int grpcPort, String cn) {
|
||||
this(host, port, grpcPort, cn, sslContext);
|
||||
}
|
||||
|
||||
public FilerGrpcClient(String host, int port, int grpcPort, SslContext sslContext) {
|
||||
public FilerGrpcClient(String host, int port, int grpcPort, String cn, SslContext sslContext) {
|
||||
|
||||
this(sslContext == null ?
|
||||
ManagedChannelBuilder.forAddress(host, grpcPort).usePlaintext()
|
||||
ManagedChannelBuilder.forAddress(host, grpcPort)
|
||||
.usePlaintext()
|
||||
.maxInboundMessageSize(1024 * 1024 * 1024) :
|
||||
NettyChannelBuilder.forAddress(host, grpcPort)
|
||||
.maxInboundMessageSize(1024 * 1024 * 1024)
|
||||
.negotiationType(NegotiationType.TLS)
|
||||
.sslContext(sslContext));
|
||||
cn.isEmpty() ?
|
||||
NettyChannelBuilder.forAddress(host, grpcPort)
|
||||
.maxInboundMessageSize(1024 * 1024 * 1024)
|
||||
.negotiationType(NegotiationType.TLS)
|
||||
.sslContext(sslContext) :
|
||||
NettyChannelBuilder.forAddress(host, grpcPort)
|
||||
.maxInboundMessageSize(1024 * 1024 * 1024)
|
||||
.negotiationType(NegotiationType.TLS)
|
||||
.overrideAuthority(cn) //will not check hostname of the filer server
|
||||
.sslContext(sslContext)
|
||||
);
|
||||
|
||||
filerAddress = SeaweedUtil.joinHostPort(host, port);
|
||||
|
||||
@@ -130,12 +135,11 @@ public class FilerGrpcClient {
|
||||
public String getChunkUrl(String chunkId, String url, String publicUrl) {
|
||||
switch (this.volumeServerAccess) {
|
||||
case VOLUME_SERVER_ACCESS_PUBLIC_URL:
|
||||
return String.format("http://%s/%s", publicUrl, chunkId);
|
||||
return String.format("%s://%s/%s", protocol, publicUrl, chunkId);
|
||||
case VOLUME_SERVER_ACCESS_FILER_PROXY:
|
||||
return String.format("http://%s/?proxyChunkId=%s", this.filerAddress, chunkId);
|
||||
return String.format("%s://%s/?proxyChunkId=%s", protocol, this.filerAddress, chunkId);
|
||||
default:
|
||||
return String.format("http://%s/%s", url, chunkId);
|
||||
return String.format("%s://%s/%s", protocol, url, chunkId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
package seaweedfs.client;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.moandjiezana.toml.Toml;
|
||||
import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts;
|
||||
import io.grpc.netty.shaded.io.netty.handler.ssl.SslContext;
|
||||
import io.grpc.netty.shaded.io.netty.handler.ssl.SslContextBuilder;
|
||||
import io.grpc.netty.shaded.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import org.apache.http.ssl.SSLContextBuilder;
|
||||
import org.apache.http.ssl.SSLContexts;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
public abstract class FilerSecurityContext extends SslContext {
|
||||
//extends Netty SslContext to access its protected static utility methods in
|
||||
//buildHttpSslContext()
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(FilerSecurityContext.class);
|
||||
private static boolean grpcSecurityEnabled;
|
||||
private static boolean httpSecurityEnabled;
|
||||
private static SslContext grpcSslContext;
|
||||
private static SSLContext httpSslContext;
|
||||
|
||||
private static String grpcTrustCertCollectionFilePath;
|
||||
private static String grpcClientCertChainFilePath;
|
||||
private static String grpcClientPrivateKeyFilePath;
|
||||
|
||||
private static String httpTrustCertCollectionFilePath;
|
||||
private static String httpClientCertChainFilePath;
|
||||
private static String httpClientPrivateKeyFilePath;
|
||||
|
||||
|
||||
static {
|
||||
String securityFileName = "security.toml";
|
||||
String home = System.getProperty("user.home");
|
||||
File f1 = new File("./"+securityFileName);
|
||||
File f2 = new File(home + "/.seaweedfs/"+securityFileName);
|
||||
File f3 = new File("/etc/seaweedfs/"+securityFileName);
|
||||
|
||||
File securityFile = f1.exists()? f1 : f2.exists() ? f2 : f3.exists()? f3 : null;
|
||||
|
||||
if (securityFile==null){
|
||||
logger.debug("Security file not found");
|
||||
grpcSecurityEnabled = false;
|
||||
httpSecurityEnabled = false;
|
||||
} else {
|
||||
|
||||
Toml toml = new Toml().read(securityFile);
|
||||
logger.debug("reading ssl setup from {}", securityFile);
|
||||
|
||||
grpcTrustCertCollectionFilePath = toml.getString("grpc.ca");
|
||||
logger.debug("loading gRPC ca from {}", grpcTrustCertCollectionFilePath);
|
||||
grpcClientCertChainFilePath = toml.getString("grpc.client.cert");
|
||||
logger.debug("loading gRPC client ca from {}", grpcClientCertChainFilePath);
|
||||
grpcClientPrivateKeyFilePath = toml.getString("grpc.client.key");
|
||||
logger.debug("loading gRPC client key from {}", grpcClientPrivateKeyFilePath);
|
||||
|
||||
if (Strings.isNullOrEmpty(grpcClientCertChainFilePath) && Strings.isNullOrEmpty(grpcClientPrivateKeyFilePath)) {
|
||||
logger.debug("gRPC private key file locations not set");
|
||||
grpcSecurityEnabled = false;
|
||||
} else {
|
||||
try {
|
||||
grpcSslContext = buildGrpcSslContext();
|
||||
grpcSecurityEnabled = true;
|
||||
} catch (Exception e) {
|
||||
logger.warn("Couldn't initialize gRPC security context, filer operations are likely to fail!", e);
|
||||
grpcSslContext = null;
|
||||
grpcSecurityEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (toml.getBoolean("https.client.enabled")) {
|
||||
httpTrustCertCollectionFilePath = toml.getString("https.client.ca");
|
||||
logger.debug("loading HTTP ca from {}", httpTrustCertCollectionFilePath);
|
||||
httpClientCertChainFilePath = toml.getString("https.client.cert");
|
||||
logger.debug("loading HTTP client ca from {}", httpClientCertChainFilePath);
|
||||
httpClientPrivateKeyFilePath = toml.getString("https.client.key");
|
||||
logger.debug("loading HTTP client key from {}", httpClientPrivateKeyFilePath);
|
||||
|
||||
if (Strings.isNullOrEmpty(httpClientCertChainFilePath) && Strings.isNullOrEmpty(httpClientPrivateKeyFilePath)) {
|
||||
logger.debug("HTTP private key file locations not set");
|
||||
httpSecurityEnabled = false;
|
||||
} else {
|
||||
try {
|
||||
httpSslContext = buildHttpSslContext();
|
||||
httpSecurityEnabled = true;
|
||||
} catch (Exception e) {
|
||||
logger.warn("Couldn't initialize HTTP security context, volume operations are likely to fail!", e);
|
||||
httpSslContext = null;
|
||||
httpSecurityEnabled = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
httpSecurityEnabled = false;
|
||||
}
|
||||
}
|
||||
// possibly fix the format https://netty.io/wiki/sslcontextbuilder-and-private-key.html
|
||||
}
|
||||
|
||||
public static boolean isGrpcSecurityEnabled() {
|
||||
return grpcSecurityEnabled;
|
||||
}
|
||||
|
||||
public static boolean isHttpSecurityEnabled() {
|
||||
return httpSecurityEnabled;
|
||||
}
|
||||
|
||||
public static SslContext getGrpcSslContext() {
|
||||
return grpcSslContext;
|
||||
}
|
||||
|
||||
public static SSLContext getHttpSslContext() {
|
||||
return httpSslContext;
|
||||
}
|
||||
|
||||
private static SslContext buildGrpcSslContext() throws SSLException {
|
||||
SslContextBuilder builder = GrpcSslContexts.forClient();
|
||||
if (grpcTrustCertCollectionFilePath != null) {
|
||||
builder.trustManager(new File(grpcTrustCertCollectionFilePath));
|
||||
}
|
||||
if (grpcClientCertChainFilePath != null && grpcClientPrivateKeyFilePath != null) {
|
||||
builder.keyManager(new File(grpcClientCertChainFilePath), new File(grpcClientPrivateKeyFilePath));
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static SSLContext buildHttpSslContext() throws GeneralSecurityException, IOException {
|
||||
SSLContextBuilder builder = SSLContexts.custom();
|
||||
|
||||
if (httpTrustCertCollectionFilePath != null) {
|
||||
final X509Certificate[] trustCerts = toX509Certificates(new File(httpTrustCertCollectionFilePath));
|
||||
final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
ks.load(null, null);
|
||||
|
||||
int i = 0;
|
||||
for (X509Certificate cert: trustCerts) {
|
||||
String alias = Integer.toString(++i);
|
||||
ks.setCertificateEntry(alias, cert);
|
||||
}
|
||||
|
||||
builder.loadTrustMaterial(ks, null);
|
||||
}
|
||||
|
||||
if (httpClientCertChainFilePath != null && httpClientPrivateKeyFilePath != null) {
|
||||
final X509Certificate[] keyCerts = toX509Certificates(new File(httpClientCertChainFilePath));
|
||||
final PrivateKey key = toPrivateKey(new File(httpClientPrivateKeyFilePath), null);
|
||||
char[] emptyPassword = new char[0];
|
||||
final KeyStore ks = buildKeyStore(keyCerts, key, emptyPassword, null);
|
||||
logger.debug("Loaded {} key certificates", ks.size());
|
||||
builder.loadKeyMaterial(ks, emptyPassword);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package seaweedfs.client;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.moandjiezana.toml.Toml;
|
||||
import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts;
|
||||
import io.grpc.netty.shaded.io.netty.handler.ssl.SslContext;
|
||||
import io.grpc.netty.shaded.io.netty.handler.ssl.SslContextBuilder;
|
||||
import io.grpc.netty.shaded.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.net.ssl.SSLException;
|
||||
import java.io.File;
|
||||
|
||||
public class FilerSslContext {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(FilerSslContext.class);
|
||||
|
||||
public static SslContext loadSslContext() throws SSLException {
|
||||
String securityFileName = "security.toml";
|
||||
String home = System.getProperty("user.home");
|
||||
File f1 = new File("./"+securityFileName);
|
||||
File f2 = new File(home + "/.seaweedfs/"+securityFileName);
|
||||
File f3 = new File("/etc/seaweedfs/"+securityFileName);
|
||||
|
||||
File securityFile = f1.exists()? f1 : f2.exists() ? f2 : f3.exists()? f3 : null;
|
||||
|
||||
if (securityFile==null){
|
||||
return null;
|
||||
}
|
||||
|
||||
Toml toml = new Toml().read(securityFile);
|
||||
logger.debug("reading ssl setup from {}", securityFile);
|
||||
|
||||
String trustCertCollectionFilePath = toml.getString("grpc.ca");
|
||||
logger.debug("loading ca from {}", trustCertCollectionFilePath);
|
||||
String clientCertChainFilePath = toml.getString("grpc.client.cert");
|
||||
logger.debug("loading client ca from {}", clientCertChainFilePath);
|
||||
String clientPrivateKeyFilePath = toml.getString("grpc.client.key");
|
||||
logger.debug("loading client key from {}", clientPrivateKeyFilePath);
|
||||
|
||||
if (Strings.isNullOrEmpty(clientPrivateKeyFilePath) && Strings.isNullOrEmpty(clientPrivateKeyFilePath)){
|
||||
return null;
|
||||
}
|
||||
|
||||
// possibly fix the format https://netty.io/wiki/sslcontextbuilder-and-private-key.html
|
||||
|
||||
return buildSslContext(trustCertCollectionFilePath, clientCertChainFilePath, clientPrivateKeyFilePath);
|
||||
}
|
||||
|
||||
|
||||
private static SslContext buildSslContext(String trustCertCollectionFilePath,
|
||||
String clientCertChainFilePath,
|
||||
String clientPrivateKeyFilePath) throws SSLException {
|
||||
SslContextBuilder builder = GrpcSslContexts.forClient();
|
||||
if (trustCertCollectionFilePath != null) {
|
||||
builder.trustManager(new File(trustCertCollectionFilePath));
|
||||
}
|
||||
if (clientCertChainFilePath != null && clientPrivateKeyFilePath != null) {
|
||||
builder.keyManager(new File(clientCertChainFilePath), new File(clientPrivateKeyFilePath));
|
||||
}
|
||||
return builder.trustManager(InsecureTrustManagerFactory.INSTANCE).build();
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,64 @@
|
||||
package seaweedfs.client;
|
||||
|
||||
import org.apache.http.config.Registry;
|
||||
import org.apache.http.config.RegistryBuilder;
|
||||
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
||||
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.impl.DefaultConnectionReuseStrategy;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
public class SeaweedUtil {
|
||||
|
||||
static PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
|
||||
private static final Logger logger = LoggerFactory.getLogger(SeaweedUtil.class);
|
||||
static PoolingHttpClientConnectionManager cm;
|
||||
static CloseableHttpClient httpClient;
|
||||
|
||||
static {
|
||||
//Apache HTTP client has a terrible API that makes you configure everything twice
|
||||
//NoopHostnameVerifier is required because SeaweedFS doesn't verify hostnames
|
||||
//and the servers are likely to have TLS certificates that do not match their hosts
|
||||
if (FilerSecurityContext.isHttpSecurityEnabled()) {
|
||||
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
|
||||
FilerSecurityContext.getHttpSslContext(),
|
||||
NoopHostnameVerifier.INSTANCE);
|
||||
|
||||
Registry<ConnectionSocketFactory> socketFactoryRegistry =
|
||||
RegistryBuilder.<ConnectionSocketFactory>create()
|
||||
.register("https", sslSocketFactory)
|
||||
.register("http", new PlainConnectionSocketFactory())
|
||||
.build();
|
||||
cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
|
||||
} else {
|
||||
cm = new PoolingHttpClientConnectionManager();
|
||||
}
|
||||
|
||||
// Increase max total connection to 200
|
||||
cm.setMaxTotal(200);
|
||||
// Increase default max connection per route to 20
|
||||
cm.setDefaultMaxPerRoute(20);
|
||||
|
||||
httpClient = HttpClientBuilder.create()
|
||||
HttpClientBuilder builder = HttpClientBuilder.create()
|
||||
.setConnectionManager(cm)
|
||||
.setConnectionReuseStrategy(DefaultConnectionReuseStrategy.INSTANCE)
|
||||
.setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE)
|
||||
.build();
|
||||
.setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE);
|
||||
|
||||
if (FilerSecurityContext.isHttpSecurityEnabled()) {
|
||||
builder.setSSLContext(FilerSecurityContext.getHttpSslContext());
|
||||
builder.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);
|
||||
}
|
||||
|
||||
httpClient = builder.build();
|
||||
}
|
||||
|
||||
public static CloseableHttpClient getClosableHttpClient() {
|
||||
|
||||
@@ -29,6 +29,7 @@ public class SeaweedFileSystem extends FileSystem {
|
||||
public static final String FS_SEAWEED_REPLICATION = "fs.seaweed.replication";
|
||||
public static final String FS_SEAWEED_VOLUME_SERVER_ACCESS = "fs.seaweed.volume.server.access";
|
||||
public static final int FS_SEAWEED_DEFAULT_BUFFER_SIZE = 4 * 1024 * 1024;
|
||||
public static final String FS_SEAWEED_FILER_CN = "fs.seaweed.filer.cn";
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SeaweedFileSystem.class);
|
||||
|
||||
@@ -63,8 +64,9 @@ public class SeaweedFileSystem extends FileSystem {
|
||||
setConf(conf);
|
||||
this.uri = uri;
|
||||
|
||||
seaweedFileSystemStore = new SeaweedFileSystemStore(host, port, grpcPort, conf);
|
||||
String cn = conf.get(FS_SEAWEED_FILER_CN, "");
|
||||
|
||||
seaweedFileSystemStore = new SeaweedFileSystemStore(host, port, grpcPort, cn, conf);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,8 +27,8 @@ public class SeaweedFileSystemStore {
|
||||
private FilerClient filerClient;
|
||||
private Configuration conf;
|
||||
|
||||
public SeaweedFileSystemStore(String host, int port, int grpcPort, Configuration conf) {
|
||||
filerClient = new FilerClient(host, port, grpcPort);
|
||||
public SeaweedFileSystemStore(String host, int port, int grpcPort, String cn, Configuration conf) {
|
||||
filerClient = new FilerClient(host, port, grpcPort, cn);
|
||||
this.conf = conf;
|
||||
String volumeServerAccessMode = this.conf.get(FS_SEAWEED_VOLUME_SERVER_ACCESS, "direct");
|
||||
if (volumeServerAccessMode.equals("publicUrl")) {
|
||||
@@ -36,7 +36,6 @@ public class SeaweedFileSystemStore {
|
||||
} else if (volumeServerAccessMode.equals("filerProxy")) {
|
||||
filerClient.setAccessVolumeServerByFilerProxy();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void close() {
|
||||
|
||||
@@ -29,6 +29,7 @@ public class SeaweedFileSystem extends FileSystem {
|
||||
public static final String FS_SEAWEED_REPLICATION = "fs.seaweed.replication";
|
||||
public static final String FS_SEAWEED_VOLUME_SERVER_ACCESS = "fs.seaweed.volume.server.access";
|
||||
public static final int FS_SEAWEED_DEFAULT_BUFFER_SIZE = 4 * 1024 * 1024;
|
||||
public static final String FS_SEAWEED_FILER_CN = "fs.seaweed.filer.cn";
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SeaweedFileSystem.class);
|
||||
|
||||
@@ -63,8 +64,9 @@ public class SeaweedFileSystem extends FileSystem {
|
||||
setConf(conf);
|
||||
this.uri = uri;
|
||||
|
||||
seaweedFileSystemStore = new SeaweedFileSystemStore(host, port, grpcPort, conf);
|
||||
String cn = conf.get(FS_SEAWEED_FILER_CN, "");
|
||||
|
||||
seaweedFileSystemStore = new SeaweedFileSystemStore(host, port, grpcPort, cn, conf);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,8 +27,8 @@ public class SeaweedFileSystemStore {
|
||||
private FilerClient filerClient;
|
||||
private Configuration conf;
|
||||
|
||||
public SeaweedFileSystemStore(String host, int port, int grpcPort, Configuration conf) {
|
||||
filerClient = new FilerClient(host, port, grpcPort);
|
||||
public SeaweedFileSystemStore(String host, int port, int grpcPort, String cn, Configuration conf) {
|
||||
filerClient = new FilerClient(host, port, grpcPort, cn);
|
||||
this.conf = conf;
|
||||
String volumeServerAccessMode = this.conf.get(FS_SEAWEED_VOLUME_SERVER_ACCESS, "direct");
|
||||
if (volumeServerAccessMode.equals("publicUrl")) {
|
||||
@@ -36,7 +36,6 @@ public class SeaweedFileSystemStore {
|
||||
} else if (volumeServerAccessMode.equals("filerProxy")) {
|
||||
filerClient.setAccessVolumeServerByFilerProxy();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void close() {
|
||||
|
||||
+19
-52
@@ -3,9 +3,9 @@ package main
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/other/mq_client_example/example"
|
||||
"github.com/seaweedfs/seaweedfs/weed/mq/client/agent_client"
|
||||
"github.com/seaweedfs/seaweedfs/weed/mq/schema"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/schema_pb"
|
||||
"log"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
@@ -20,13 +20,26 @@ var (
|
||||
|
||||
clientName = flag.String("client", "c1", "client name")
|
||||
|
||||
namespace = flag.String("ns", "test", "namespace")
|
||||
t = flag.String("t", "test", "t")
|
||||
seedBrokers = flag.String("brokers", "localhost:17777", "seed brokers")
|
||||
namespace = flag.String("ns", "test", "namespace")
|
||||
t = flag.String("t", "test", "t")
|
||||
agent = flag.String("agent", "localhost:16777", "mq agent address")
|
||||
|
||||
counter int32
|
||||
)
|
||||
|
||||
func genMyRecord(id int32) *example.MyRecord {
|
||||
return &example.MyRecord{
|
||||
Key: []byte(fmt.Sprintf("key-%s-%d", *clientName, id)),
|
||||
Field1: []byte(fmt.Sprintf("field1-%s-%d", *clientName, id)),
|
||||
Field2: fmt.Sprintf("field2-%s-%d", *clientName, id),
|
||||
Field3: id,
|
||||
Field4: int64(id),
|
||||
Field5: float32(id),
|
||||
Field6: float64(id),
|
||||
Field7: id%2 == 0,
|
||||
}
|
||||
}
|
||||
|
||||
func doPublish(publisher *agent_client.PublishSession, id int) {
|
||||
startTime := time.Now()
|
||||
for {
|
||||
@@ -49,58 +62,12 @@ func doPublish(publisher *agent_client.PublishSession, id int) {
|
||||
log.Printf("Publisher %s-%d finished in %s", *clientName, id, elapsed)
|
||||
}
|
||||
|
||||
type MyRecord struct {
|
||||
Key []byte
|
||||
Field1 []byte
|
||||
Field2 string
|
||||
Field3 int32
|
||||
Field4 int64
|
||||
Field5 float32
|
||||
Field6 float64
|
||||
Field7 bool
|
||||
}
|
||||
|
||||
func genMyRecord(id int32) *MyRecord {
|
||||
return &MyRecord{
|
||||
Key: []byte(fmt.Sprintf("key-%s-%d", *clientName, id)),
|
||||
Field1: []byte(fmt.Sprintf("field1-%s-%d", *clientName, id)),
|
||||
Field2: fmt.Sprintf("field2-%s-%d", *clientName, id),
|
||||
Field3: id,
|
||||
Field4: int64(id),
|
||||
Field5: float32(id),
|
||||
Field6: float64(id),
|
||||
Field7: id%2 == 0,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *MyRecord) ToRecordValue() *schema_pb.RecordValue {
|
||||
return schema.RecordBegin().
|
||||
SetBytes("key", r.Key).
|
||||
SetBytes("field1", r.Field1).
|
||||
SetString("field2", r.Field2).
|
||||
SetInt32("field3", r.Field3).
|
||||
SetInt64("field4", r.Field4).
|
||||
SetFloat("field5", r.Field5).
|
||||
SetDouble("field6", r.Field6).
|
||||
SetBool("field7", r.Field7).
|
||||
RecordEnd()
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
recordType := schema.RecordTypeBegin().
|
||||
WithField("key", schema.TypeBytes).
|
||||
WithField("field1", schema.TypeBytes).
|
||||
WithField("field2", schema.TypeString).
|
||||
WithField("field3", schema.TypeInt32).
|
||||
WithField("field4", schema.TypeInt64).
|
||||
WithField("field5", schema.TypeFloat).
|
||||
WithField("field6", schema.TypeDouble).
|
||||
WithField("field7", schema.TypeBoolean).
|
||||
RecordTypeEnd()
|
||||
recordType := example.MyRecordType()
|
||||
|
||||
session, err := agent_client.NewPublishSession("localhost:16777", schema.NewSchema(*namespace, *t, recordType), *partitionCount, *clientName)
|
||||
session, err := agent_client.NewPublishSession(*agent, schema.NewSchema(*namespace, *t, recordType), *partitionCount, *clientName)
|
||||
if err != nil {
|
||||
log.Printf("failed to create session: %v", err)
|
||||
return
|
||||
@@ -0,0 +1,62 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/other/mq_client_example/example"
|
||||
"github.com/seaweedfs/seaweedfs/weed/mq/client/agent_client"
|
||||
"github.com/seaweedfs/seaweedfs/weed/mq/topic"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/schema_pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/util"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
namespace = flag.String("ns", "test", "namespace")
|
||||
t = flag.String("topic", "test", "topic")
|
||||
agent = flag.String("agent", "localhost:16777", "mq agent address")
|
||||
maxPartitionCount = flag.Int("maxPartitionCount", 3, "max partition count")
|
||||
slidingWindowSize = flag.Int("slidingWindowSize", 1, "per partition concurrency")
|
||||
timeAgo = 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\"")
|
||||
|
||||
clientId = flag.Uint("client_id", uint(util.RandomInt32()), "client id")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
// determine the start of the messages
|
||||
var startTsNs int64
|
||||
startType := schema_pb.OffsetType_RESUME_OR_EARLIEST
|
||||
if *timeAgo > 0 {
|
||||
startTsNs = time.Now().Add(-*timeAgo).UnixNano()
|
||||
startType = schema_pb.OffsetType_EXACT_TS_NS
|
||||
}
|
||||
|
||||
session, err := agent_client.NewSubscribeSession(*agent, &agent_client.SubscribeOption{
|
||||
ConsumerGroup: "test",
|
||||
ConsumerGroupInstanceId: fmt.Sprintf("client-%d", *clientId),
|
||||
Topic: topic.NewTopic(*namespace, *t),
|
||||
OffsetType: startType,
|
||||
OffsetTsNs: startTsNs,
|
||||
Filter: "",
|
||||
MaxSubscribedPartitions: int32(*maxPartitionCount),
|
||||
SlidingWindowSize: int32(*slidingWindowSize),
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("new subscribe session: %v", err)
|
||||
return
|
||||
}
|
||||
defer session.CloseSession()
|
||||
|
||||
counter := 0
|
||||
session.SubscribeMessageRecord(func(key []byte, recordValue *schema_pb.RecordValue) {
|
||||
counter++
|
||||
record := example.FromRecordValue(recordValue)
|
||||
fmt.Printf("%d %s %v\n", counter, string(key), record.Field2)
|
||||
}, func() {
|
||||
log.Printf("done received %d messages", counter)
|
||||
})
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package example
|
||||
|
||||
import (
|
||||
"github.com/seaweedfs/seaweedfs/weed/mq/schema"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/schema_pb"
|
||||
)
|
||||
|
||||
type MyRecord struct {
|
||||
Key []byte
|
||||
Field1 []byte
|
||||
Field2 string
|
||||
Field3 int32
|
||||
Field4 int64
|
||||
Field5 float32
|
||||
Field6 float64
|
||||
Field7 bool
|
||||
}
|
||||
|
||||
func MyRecordType() *schema_pb.RecordType {
|
||||
return schema.RecordTypeBegin().
|
||||
WithField("key", schema.TypeBytes).
|
||||
WithField("field1", schema.TypeBytes).
|
||||
WithField("field2", schema.TypeString).
|
||||
WithField("field3", schema.TypeInt32).
|
||||
WithField("field4", schema.TypeInt64).
|
||||
WithField("field5", schema.TypeFloat).
|
||||
WithField("field6", schema.TypeDouble).
|
||||
WithField("field7", schema.TypeBoolean).
|
||||
RecordTypeEnd()
|
||||
}
|
||||
|
||||
func (r *MyRecord) ToRecordValue() *schema_pb.RecordValue {
|
||||
return schema.RecordBegin().
|
||||
SetBytes("key", r.Key).
|
||||
SetBytes("field1", r.Field1).
|
||||
SetString("field2", r.Field2).
|
||||
SetInt32("field3", r.Field3).
|
||||
SetInt64("field4", r.Field4).
|
||||
SetFloat("field5", r.Field5).
|
||||
SetDouble("field6", r.Field6).
|
||||
SetBool("field7", r.Field7).
|
||||
RecordEnd()
|
||||
}
|
||||
|
||||
func FromRecordValue(recordValue *schema_pb.RecordValue) *MyRecord {
|
||||
return &MyRecord{
|
||||
Key: recordValue.Fields["key"].GetBytesValue(),
|
||||
Field1: recordValue.Fields["field1"].GetBytesValue(),
|
||||
Field2: recordValue.Fields["field2"].GetStringValue(),
|
||||
Field3: recordValue.Fields["field3"].GetInt32Value(),
|
||||
Field4: recordValue.Fields["field4"].GetInt64Value(),
|
||||
Field5: recordValue.Fields["field5"].GetFloatValue(),
|
||||
Field6: recordValue.Fields["field6"].GetDoubleValue(),
|
||||
Field7: recordValue.Fields["field7"].GetBoolValue(),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
//go:build !windows && !openbsd && !netbsd && !plan9 && !solaris
|
||||
// +build !windows,!openbsd,!netbsd,!plan9,!solaris
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// go run unmaintained/disk/disk_status.go
|
||||
|
||||
type DiskStatus struct {
|
||||
Dir string `protobuf:"bytes,1,opt,name=dir,proto3" json:"dir,omitempty"`
|
||||
All uint64 `protobuf:"varint,2,opt,name=all,proto3" json:"all,omitempty"`
|
||||
Used uint64 `protobuf:"varint,3,opt,name=used,proto3" json:"used,omitempty"`
|
||||
Free uint64 `protobuf:"varint,4,opt,name=free,proto3" json:"free,omitempty"`
|
||||
PercentFree float32 `protobuf:"fixed32,5,opt,name=percent_free,json=percentFree,proto3" json:"percent_free,omitempty"`
|
||||
PercentUsed float32 `protobuf:"fixed32,6,opt,name=percent_used,json=percentUsed,proto3" json:"percent_used,omitempty"`
|
||||
DiskType string `protobuf:"bytes,7,opt,name=disk_type,json=diskType,proto3" json:"disk_type,omitempty"`
|
||||
|
||||
// new fields about avail blocks
|
||||
Avail uint64 `protobuf:"varint,4,opt,name=avail,proto3" json:"avail,omitempty"`
|
||||
PercentAvail float32 `protobuf:"fixed32,5,opt,name=percent_avail,json=percentAvail,proto3" json:"percent_avail,omitempty"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
dirs := []string{"/mnt/sdb", "/mnt/sdc", "/mnt/sdd", "/mnt/sde", "/mnt/sdf", "/mnt/sdg", "/mnt/sdh", "/mnt/sdi", "/mnt/sdj"}
|
||||
// dirs := []string{"/mnt/sdb"}
|
||||
for _, dir := range dirs {
|
||||
disk := &DiskStatus{Dir: dir}
|
||||
fillInDiskStatus(disk)
|
||||
|
||||
// bytes, _ := json.Marshal(disk)
|
||||
// log.Printf("disk status %s", bytes)
|
||||
log.Printf("disk: %s avail: %f free: %f", disk.Dir, disk.PercentAvail, disk.PercentFree)
|
||||
}
|
||||
}
|
||||
|
||||
func fillInDiskStatus(disk *DiskStatus) {
|
||||
fs := syscall.Statfs_t{}
|
||||
err := syscall.Statfs(disk.Dir, &fs)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
disk.All = fs.Blocks * uint64(fs.Bsize)
|
||||
disk.Free = fs.Bfree * uint64(fs.Bsize)
|
||||
disk.Used = disk.All - disk.Free
|
||||
disk.PercentFree = float32((float64(disk.Free) / float64(disk.All)) * 100)
|
||||
disk.PercentUsed = float32((float64(disk.Used) / float64(disk.All)) * 100)
|
||||
|
||||
// avail blocks
|
||||
disk.Avail = fs.Bavail * uint64(fs.Bsize)
|
||||
disk.PercentAvail = float32((float64(disk.Avail) / float64(disk.All)) * 100)
|
||||
return
|
||||
}
|
||||
@@ -1,18 +1,19 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"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/util"
|
||||
util_http "github.com/seaweedfs/seaweedfs/weed/util/http"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
util_http "github.com/seaweedfs/seaweedfs/weed/util/http"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -60,7 +61,7 @@ func startGenerateMetadata() {
|
||||
for i := 0; i < *n; i++ {
|
||||
name := fmt.Sprintf("file%d", i)
|
||||
glog.V(0).Infof("write %s/%s", *dir, name)
|
||||
if err := filer_pb.CreateEntry(client, &filer_pb.CreateEntryRequest{
|
||||
if err := filer_pb.CreateEntry(context.Background(), client, &filer_pb.CreateEntryRequest{
|
||||
Directory: *dir,
|
||||
Entry: &filer_pb.Entry{
|
||||
Name: name,
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb"
|
||||
"log"
|
||||
"math/rand"
|
||||
"time"
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
@@ -56,7 +56,7 @@ func main() {
|
||||
}
|
||||
|
||||
func genFile(grpcDialOption grpc.DialOption, i int) (*operation.AssignResult, string) {
|
||||
assignResult, err := operation.Assign(func(_ context.Context) pb.ServerAddress { return pb.ServerAddress(*master) }, grpcDialOption, &operation.VolumeAssignRequest{
|
||||
assignResult, err := operation.Assign(context.Background(), func(_ context.Context) pb.ServerAddress { return pb.ServerAddress(*master) }, grpcDialOption, &operation.VolumeAssignRequest{
|
||||
Count: 1,
|
||||
Replication: *replication,
|
||||
})
|
||||
@@ -84,7 +84,7 @@ func genFile(grpcDialOption grpc.DialOption, i int) (*operation.AssignResult, st
|
||||
log.Fatalf("upload: %v", err)
|
||||
}
|
||||
|
||||
_, err = uploader.UploadData(data, uploadOption)
|
||||
_, err = uploader.UploadData(context.Background(), data, uploadOption)
|
||||
if err != nil {
|
||||
log.Fatalf("upload: %v", err)
|
||||
}
|
||||
|
||||
@@ -41,6 +41,10 @@ debug_mq:
|
||||
go build -gcflags="all=-N -l"
|
||||
dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./weed -- -v=4 mq.broker
|
||||
|
||||
debug_mq_agent:
|
||||
go build -gcflags="all=-N -l"
|
||||
dlv --listen=:2346 --headless=true --api-version=2 --accept-multiclient exec ./weed -- -v=4 mq.agent -broker=localhost:17777
|
||||
|
||||
debug_filer_copy:
|
||||
go build -gcflags="all=-N -l"
|
||||
dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./weed -- -v=4 filer.backup -filer=localhost:8888 -filerProxy -timeAgo=10h
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/util/version"
|
||||
"io"
|
||||
"math"
|
||||
"math/rand"
|
||||
@@ -115,7 +116,7 @@ func runBenchmark(cmd *Command, args []string) bool {
|
||||
util.LoadSecurityConfiguration()
|
||||
b.grpcDialOption = security.LoadClientTLS(util.GetViper(), "grpc.client")
|
||||
|
||||
fmt.Printf("This is SeaweedFS version %s %s %s\n", util.Version(), runtime.GOOS, runtime.GOARCH)
|
||||
fmt.Printf("This is SeaweedFS version %s %s %s\n", version.Version(), runtime.GOOS, runtime.GOARCH)
|
||||
if *b.maxCpu < 1 {
|
||||
*b.maxCpu = runtime.NumCPU()
|
||||
}
|
||||
@@ -241,7 +242,7 @@ func writeFiles(idChan chan int, fileIdLineChan chan string, s *stat) {
|
||||
Replication: *b.replication,
|
||||
DiskType: *b.diskType,
|
||||
}
|
||||
if assignResult, err := operation.Assign(b.masterClient.GetMaster, b.grpcDialOption, ar); err == nil {
|
||||
if assignResult, err := operation.Assign(context.Background(), b.masterClient.GetMaster, b.grpcDialOption, ar); err == nil {
|
||||
fp.Server, fp.Fid, fp.Pref.Collection = assignResult.Url, assignResult.Fid, *b.collection
|
||||
if !isSecure && assignResult.Auth != "" {
|
||||
isSecure = true
|
||||
@@ -288,7 +289,7 @@ func readFiles(fileIdLineChan chan string, s *stat) {
|
||||
start := time.Now()
|
||||
var bytesRead int
|
||||
var err error
|
||||
urls, err := b.masterClient.LookupFileId(fid)
|
||||
urls, err := b.masterClient.LookupFileId(context.Background(), fid)
|
||||
if err != nil {
|
||||
s.failed++
|
||||
println("!!!! ", fid, " location not found!!!!!")
|
||||
|
||||
@@ -32,6 +32,7 @@ var Commands = []*Command{
|
||||
cmdMaster,
|
||||
cmdMasterFollower,
|
||||
cmdMount,
|
||||
cmdMqAgent,
|
||||
cmdMqBroker,
|
||||
cmdS3,
|
||||
cmdScaffold,
|
||||
@@ -42,6 +43,7 @@ var Commands = []*Command{
|
||||
cmdVersion,
|
||||
cmdVolume,
|
||||
cmdWebDav,
|
||||
cmdSftp,
|
||||
}
|
||||
|
||||
type Command struct {
|
||||
|
||||
+38
-3
@@ -5,6 +5,7 @@ import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/util/version"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -35,6 +36,8 @@ var (
|
||||
filerWebDavOptions WebDavOption
|
||||
filerStartIam *bool
|
||||
filerIamOptions IamOptions
|
||||
filerStartSftp *bool
|
||||
filerSftpOptions SftpOptions
|
||||
)
|
||||
|
||||
type FilerOptions struct {
|
||||
@@ -119,6 +122,10 @@ func init() {
|
||||
filerS3Options.allowEmptyFolder = cmdFiler.Flag.Bool("s3.allowEmptyFolder", true, "allow empty folders")
|
||||
filerS3Options.allowDeleteBucketNotEmpty = cmdFiler.Flag.Bool("s3.allowDeleteBucketNotEmpty", true, "allow recursive deleting all entries along with bucket")
|
||||
filerS3Options.localSocket = cmdFiler.Flag.String("s3.localSocket", "", "default to /tmp/seaweedfs-s3-<port>.sock")
|
||||
filerS3Options.tlsCACertificate = cmdFiler.Flag.String("s3.cacert.file", "", "path to the TLS CA certificate file")
|
||||
filerS3Options.tlsVerifyClientCert = cmdFiler.Flag.Bool("s3.tlsVerifyClientCert", false, "whether to verify the client's certificate")
|
||||
filerS3Options.bindIp = cmdFiler.Flag.String("s3.ip.bind", "", "ip address to bind to. If empty, default to same as -ip.bind option.")
|
||||
filerS3Options.idleTimeout = cmdFiler.Flag.Int("s3.idleTimeout", 10, "connection idle seconds")
|
||||
|
||||
// start webdav on filer
|
||||
filerStartWebDav = cmdFiler.Flag.Bool("webdav", false, "whether to start webdav gateway")
|
||||
@@ -137,6 +144,19 @@ func init() {
|
||||
filerStartIam = cmdFiler.Flag.Bool("iam", false, "whether to start IAM service")
|
||||
filerIamOptions.ip = cmdFiler.Flag.String("iam.ip", *f.ip, "iam server http listen ip address")
|
||||
filerIamOptions.port = cmdFiler.Flag.Int("iam.port", 8111, "iam server http listen port")
|
||||
|
||||
filerStartSftp = cmdFiler.Flag.Bool("sftp", false, "whether to start the SFTP server")
|
||||
filerSftpOptions.port = cmdFiler.Flag.Int("sftp.port", 2022, "SFTP server listen port")
|
||||
filerSftpOptions.sshPrivateKey = cmdFiler.Flag.String("sftp.sshPrivateKey", "", "path to the SSH private key file for host authentication")
|
||||
filerSftpOptions.hostKeysFolder = cmdFiler.Flag.String("sftp.hostKeysFolder", "", "path to folder containing SSH private key files for host authentication")
|
||||
filerSftpOptions.authMethods = cmdFiler.Flag.String("sftp.authMethods", "password,publickey", "comma-separated list of allowed auth methods: password, publickey, keyboard-interactive")
|
||||
filerSftpOptions.maxAuthTries = cmdFiler.Flag.Int("sftp.maxAuthTries", 6, "maximum number of authentication attempts per connection")
|
||||
filerSftpOptions.bannerMessage = cmdFiler.Flag.String("sftp.bannerMessage", "SeaweedFS SFTP Server - Unauthorized access is prohibited", "message displayed before authentication")
|
||||
filerSftpOptions.loginGraceTime = cmdFiler.Flag.Duration("sftp.loginGraceTime", 2*time.Minute, "timeout for authentication")
|
||||
filerSftpOptions.clientAliveInterval = cmdFiler.Flag.Duration("sftp.clientAliveInterval", 5*time.Second, "interval for sending keep-alive messages")
|
||||
filerSftpOptions.clientAliveCountMax = cmdFiler.Flag.Int("sftp.clientAliveCountMax", 3, "maximum number of missed keep-alive messages before disconnecting")
|
||||
filerSftpOptions.userStoreFile = cmdFiler.Flag.String("sftp.userStoreFile", "", "path to JSON file containing user credentials and permissions")
|
||||
filerSftpOptions.localSocket = cmdFiler.Flag.String("sftp.localSocket", "", "default to /tmp/seaweedfs-sftp-<port>.sock")
|
||||
}
|
||||
|
||||
func filerLongDesc() string {
|
||||
@@ -195,7 +215,9 @@ func runFiler(cmd *Command, args []string) bool {
|
||||
startDelay := time.Duration(2)
|
||||
if *filerStartS3 {
|
||||
filerS3Options.filer = &filerAddress
|
||||
filerS3Options.bindIp = f.bindIp
|
||||
if *filerS3Options.bindIp == "" {
|
||||
filerS3Options.bindIp = f.bindIp
|
||||
}
|
||||
filerS3Options.localFilerSocket = f.localSocket
|
||||
if *f.dataCenter != "" && *filerS3Options.dataCenter == "" {
|
||||
filerS3Options.dataCenter = f.dataCenter
|
||||
@@ -209,6 +231,7 @@ func runFiler(cmd *Command, args []string) bool {
|
||||
|
||||
if *filerStartWebDav {
|
||||
filerWebDavOptions.filer = &filerAddress
|
||||
filerWebDavOptions.ipBind = f.bindIp
|
||||
|
||||
if *filerWebDavOptions.disk == "" {
|
||||
filerWebDavOptions.disk = f.diskType
|
||||
@@ -228,6 +251,18 @@ func runFiler(cmd *Command, args []string) bool {
|
||||
time.Sleep(delay * time.Second)
|
||||
filerIamOptions.startIamServer()
|
||||
}(startDelay)
|
||||
startDelay++
|
||||
}
|
||||
|
||||
if *filerStartSftp {
|
||||
sftpOptions.filer = &filerAddress
|
||||
if *f.dataCenter != "" && *filerSftpOptions.dataCenter == "" {
|
||||
filerSftpOptions.dataCenter = f.dataCenter
|
||||
}
|
||||
go func(delay time.Duration) {
|
||||
time.Sleep(delay * time.Second)
|
||||
sftpOptions.startSftpServer()
|
||||
}(startDelay)
|
||||
}
|
||||
|
||||
f.masters = pb.ServerAddresses(*f.mastersString).ToServiceDiscovery()
|
||||
@@ -295,7 +330,7 @@ func (fo *FilerOptions) startFiler() {
|
||||
|
||||
if *fo.publicPort != 0 {
|
||||
publicListeningAddress := util.JoinHostPort(*fo.bindIp, *fo.publicPort)
|
||||
glog.V(0).Infoln("Start Seaweed filer server", util.Version(), "public at", publicListeningAddress)
|
||||
glog.V(0).Infoln("Start Seaweed filer server", version.Version(), "public at", publicListeningAddress)
|
||||
publicListener, localPublicListener, e := util.NewIpAndLocalListeners(*fo.bindIp, *fo.publicPort, 0)
|
||||
if e != nil {
|
||||
glog.Fatalf("Filer server public listener error on port %d:%v", *fo.publicPort, e)
|
||||
@@ -314,7 +349,7 @@ func (fo *FilerOptions) startFiler() {
|
||||
}
|
||||
}
|
||||
|
||||
glog.V(0).Infof("Start Seaweed Filer %s at %s:%d", util.Version(), *fo.ip, *fo.port)
|
||||
glog.V(0).Infof("Start Seaweed Filer %s at %s:%d", version.Version(), *fo.ip, *fo.port)
|
||||
filerListener, filerLocalListener, e := util.NewIpAndLocalListeners(
|
||||
*fo.bindIp, *fo.port,
|
||||
time.Duration(10)*time.Second,
|
||||
|
||||
@@ -28,9 +28,9 @@ type FilerCatOptions struct {
|
||||
}
|
||||
|
||||
func (fco *FilerCatOptions) GetLookupFileIdFunction() wdclient.LookupFileIdFunctionType {
|
||||
return func(fileId string) (targetUrls []string, err error) {
|
||||
return func(ctx context.Context, fileId string) (targetUrls []string, err error) {
|
||||
vid := filer.VolumeId(fileId)
|
||||
resp, err := fco.filerClient.LookupVolume(context.Background(), &filer_pb.LookupVolumeRequest{
|
||||
resp, err := fco.filerClient.LookupVolume(ctx, &filer_pb.LookupVolumeRequest{
|
||||
VolumeIds: []string{vid},
|
||||
})
|
||||
if err != nil {
|
||||
@@ -102,7 +102,7 @@ func runFilerCat(cmd *Command, args []string) bool {
|
||||
Name: name,
|
||||
Directory: dir,
|
||||
}
|
||||
respLookupEntry, err := filer_pb.LookupEntry(client, request)
|
||||
respLookupEntry, err := filer_pb.LookupEntry(context.Background(), client, request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -394,7 +394,7 @@ func (worker *FileCopyWorker) uploadFileAsOne(task FileCopyTask, f *os.File) err
|
||||
},
|
||||
}
|
||||
|
||||
if err := filer_pb.CreateEntry(client, request); err != nil {
|
||||
if err := filer_pb.CreateEntry(context.Background(), client, request); err != nil {
|
||||
return fmt.Errorf("update fh: %v", err)
|
||||
}
|
||||
return nil
|
||||
@@ -511,7 +511,7 @@ func (worker *FileCopyWorker) uploadFileInChunks(task FileCopyTask, f *os.File,
|
||||
},
|
||||
}
|
||||
|
||||
if err := filer_pb.CreateEntry(client, request); err != nil {
|
||||
if err := filer_pb.CreateEntry(context.Background(), client, request); err != nil {
|
||||
return fmt.Errorf("update fh: %v", err)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/filer"
|
||||
"github.com/seaweedfs/seaweedfs/weed/glog"
|
||||
@@ -408,7 +409,7 @@ func (option *RemoteGatewayOptions) collectRemoteStorageConf() (err error) {
|
||||
|
||||
option.remoteConfs = make(map[string]*remote_pb.RemoteConf)
|
||||
var lastConfName string
|
||||
err = filer_pb.List(option, filer.DirectoryEtcRemote, "", func(entry *filer_pb.Entry, isLast bool) error {
|
||||
err = filer_pb.List(context.Background(), option, filer.DirectoryEtcRemote, "", func(entry *filer_pb.Entry, isLast bool) error {
|
||||
if !strings.HasSuffix(entry.Name, filer.REMOTE_STORAGE_CONF_SUFFIX) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -230,7 +230,7 @@ func collectLastSyncOffset(filerClient filer_pb.FilerClient, grpcDialOption grpc
|
||||
// 3. directory creation time
|
||||
var lastOffsetTs time.Time
|
||||
if timeAgo == 0 {
|
||||
mountedDirEntry, err := filer_pb.GetEntry(filerClient, util.FullPath(mountedDir))
|
||||
mountedDirEntry, err := filer_pb.GetEntry(context.Background(), filerClient, util.FullPath(mountedDir))
|
||||
if err != nil {
|
||||
glog.V(0).Infof("get mounted directory %s: %v", mountedDir, err)
|
||||
return time.Now()
|
||||
|
||||
@@ -1,250 +1,9 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
cmdFuse.Run = runFuse // break init cycle
|
||||
}
|
||||
|
||||
type parameter struct {
|
||||
name string
|
||||
value string
|
||||
}
|
||||
|
||||
func runFuse(cmd *Command, args []string) bool {
|
||||
rawArgs := strings.Join(args, " ")
|
||||
rawArgsLen := len(rawArgs)
|
||||
option := strings.Builder{}
|
||||
options := []parameter{}
|
||||
masterProcess := true
|
||||
fusermountPath := ""
|
||||
|
||||
// first parameter
|
||||
i := 0
|
||||
for i = 0; i < rawArgsLen && rawArgs[i] != ' '; i++ {
|
||||
option.WriteByte(rawArgs[i])
|
||||
}
|
||||
options = append(options, parameter{"arg0", option.String()})
|
||||
option.Reset()
|
||||
|
||||
for i++; i < rawArgsLen; i++ {
|
||||
|
||||
// space separator check for filled option
|
||||
if rawArgs[i] == ' ' {
|
||||
if option.Len() > 0 {
|
||||
options = append(options, parameter{option.String(), "true"})
|
||||
option.Reset()
|
||||
}
|
||||
|
||||
// dash separator read option until next space
|
||||
} else if rawArgs[i] == '-' {
|
||||
for i++; i < rawArgsLen && rawArgs[i] != ' '; i++ {
|
||||
option.WriteByte(rawArgs[i])
|
||||
}
|
||||
// ignore "-o"
|
||||
if option.String() != "o" {
|
||||
options = append(options, parameter{option.String(), "true"})
|
||||
}
|
||||
option.Reset()
|
||||
|
||||
// equal separator start option with pending value
|
||||
} else if rawArgs[i] == '=' {
|
||||
name := option.String()
|
||||
option.Reset()
|
||||
|
||||
for i++; i < rawArgsLen && rawArgs[i] != ',' && rawArgs[i] != ' '; i++ {
|
||||
// double quote separator read option until next double quote
|
||||
if rawArgs[i] == '"' {
|
||||
for i++; i < rawArgsLen && rawArgs[i] != '"'; i++ {
|
||||
option.WriteByte(rawArgs[i])
|
||||
}
|
||||
|
||||
// single quote separator read option until next single quote
|
||||
} else if rawArgs[i] == '\'' {
|
||||
for i++; i < rawArgsLen && rawArgs[i] != '\''; i++ {
|
||||
option.WriteByte(rawArgs[i])
|
||||
}
|
||||
|
||||
// add chars before comma
|
||||
} else if rawArgs[i] != ' ' {
|
||||
option.WriteByte(rawArgs[i])
|
||||
}
|
||||
}
|
||||
|
||||
options = append(options, parameter{name, option.String()})
|
||||
option.Reset()
|
||||
|
||||
// comma separator just read current option
|
||||
} else if rawArgs[i] == ',' {
|
||||
options = append(options, parameter{option.String(), "true"})
|
||||
option.Reset()
|
||||
|
||||
// what is not a separator fill option buffer
|
||||
} else {
|
||||
option.WriteByte(rawArgs[i])
|
||||
}
|
||||
}
|
||||
|
||||
// get residual option data
|
||||
if option.Len() > 0 {
|
||||
// add value to pending option
|
||||
options = append(options, parameter{option.String(), "true"})
|
||||
option.Reset()
|
||||
}
|
||||
|
||||
// scan each parameter
|
||||
for i := 0; i < len(options); i++ {
|
||||
parameter := options[i]
|
||||
|
||||
switch parameter.name {
|
||||
case "child":
|
||||
masterProcess = false
|
||||
case "arg0":
|
||||
mountOptions.dir = ¶meter.value
|
||||
case "filer":
|
||||
mountOptions.filer = ¶meter.value
|
||||
case "filer.path":
|
||||
mountOptions.filerMountRootPath = ¶meter.value
|
||||
case "dirAutoCreate":
|
||||
if parsed, err := strconv.ParseBool(parameter.value); err == nil {
|
||||
mountOptions.dirAutoCreate = &parsed
|
||||
} else {
|
||||
panic(fmt.Errorf("dirAutoCreate: %s", err))
|
||||
}
|
||||
case "collection":
|
||||
mountOptions.collection = ¶meter.value
|
||||
case "replication":
|
||||
mountOptions.replication = ¶meter.value
|
||||
case "disk":
|
||||
mountOptions.diskType = ¶meter.value
|
||||
case "ttl":
|
||||
if parsed, err := strconv.ParseInt(parameter.value, 0, 32); err == nil {
|
||||
intValue := int(parsed)
|
||||
mountOptions.ttlSec = &intValue
|
||||
} else {
|
||||
panic(fmt.Errorf("ttl: %s", err))
|
||||
}
|
||||
case "chunkSizeLimitMB":
|
||||
if parsed, err := strconv.ParseInt(parameter.value, 0, 32); err == nil {
|
||||
intValue := int(parsed)
|
||||
mountOptions.chunkSizeLimitMB = &intValue
|
||||
} else {
|
||||
panic(fmt.Errorf("chunkSizeLimitMB: %s", err))
|
||||
}
|
||||
case "concurrentWriters":
|
||||
i++
|
||||
if parsed, err := strconv.ParseInt(parameter.value, 0, 32); err == nil {
|
||||
intValue := int(parsed)
|
||||
mountOptions.concurrentWriters = &intValue
|
||||
} else {
|
||||
panic(fmt.Errorf("concurrentWriters: %s", err))
|
||||
}
|
||||
case "cacheDir":
|
||||
mountOptions.cacheDirForRead = ¶meter.value
|
||||
case "cacheCapacityMB":
|
||||
if parsed, err := strconv.ParseInt(parameter.value, 0, 64); err == nil {
|
||||
mountOptions.cacheSizeMBForRead = &parsed
|
||||
} else {
|
||||
panic(fmt.Errorf("cacheCapacityMB: %s", err))
|
||||
}
|
||||
case "cacheDirWrite":
|
||||
mountOptions.cacheDirForWrite = ¶meter.value
|
||||
case "dataCenter":
|
||||
mountOptions.dataCenter = ¶meter.value
|
||||
case "allowOthers":
|
||||
if parsed, err := strconv.ParseBool(parameter.value); err == nil {
|
||||
mountOptions.allowOthers = &parsed
|
||||
} else {
|
||||
panic(fmt.Errorf("allowOthers: %s", err))
|
||||
}
|
||||
case "umask":
|
||||
mountOptions.umaskString = ¶meter.value
|
||||
case "nonempty":
|
||||
if parsed, err := strconv.ParseBool(parameter.value); err == nil {
|
||||
mountOptions.nonempty = &parsed
|
||||
} else {
|
||||
panic(fmt.Errorf("nonempty: %s", err))
|
||||
}
|
||||
case "volumeServerAccess":
|
||||
mountOptions.volumeServerAccess = ¶meter.value
|
||||
case "map.uid":
|
||||
mountOptions.uidMap = ¶meter.value
|
||||
case "map.gid":
|
||||
mountOptions.gidMap = ¶meter.value
|
||||
case "readOnly":
|
||||
if parsed, err := strconv.ParseBool(parameter.value); err == nil {
|
||||
mountOptions.readOnly = &parsed
|
||||
} else {
|
||||
panic(fmt.Errorf("readOnly: %s", err))
|
||||
}
|
||||
case "cpuprofile":
|
||||
mountCpuProfile = ¶meter.value
|
||||
case "memprofile":
|
||||
mountMemProfile = ¶meter.value
|
||||
case "readRetryTime":
|
||||
if parsed, err := time.ParseDuration(parameter.value); err == nil {
|
||||
mountReadRetryTime = &parsed
|
||||
} else {
|
||||
panic(fmt.Errorf("readRetryTime: %s", err))
|
||||
}
|
||||
case "fusermount.path":
|
||||
fusermountPath = parameter.value
|
||||
default:
|
||||
t := parameter.name
|
||||
if parameter.value != "true" {
|
||||
t = fmt.Sprintf("%s=%s", parameter.name, parameter.value)
|
||||
}
|
||||
mountOptions.extraOptions = append(mountOptions.extraOptions, t)
|
||||
}
|
||||
}
|
||||
|
||||
// the master start the child, release it then finish himself
|
||||
if masterProcess {
|
||||
arg0, err := os.Executable()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
argv := append(os.Args, "-o", "child")
|
||||
|
||||
attr := os.ProcAttr{}
|
||||
attr.Env = os.Environ()
|
||||
|
||||
child, err := os.StartProcess(arg0, argv, &attr)
|
||||
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("master process can not start child process: %s", err))
|
||||
}
|
||||
|
||||
err = child.Release()
|
||||
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("master process can not release child process: %s", err))
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
if fusermountPath != "" {
|
||||
if err := os.Setenv("PATH", fusermountPath); err != nil {
|
||||
panic(fmt.Errorf("setenv: %s", err))
|
||||
}
|
||||
} else if os.Getenv("PATH") == "" {
|
||||
if err := os.Setenv("PATH", "/bin:/sbin:/usr/bin:/usr/sbin"); err != nil {
|
||||
panic(fmt.Errorf("setenv: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
// just call "weed mount" command
|
||||
return runMount(cmdMount, []string{})
|
||||
}
|
||||
|
||||
var cmdFuse = &Command{
|
||||
UsageLine: "fuse /mnt/mount/point -o \"filer=localhost:8888,filer.path=/\"",
|
||||
Short: "Allow use weed with linux's mount command",
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
//go:build !linux && !darwin
|
||||
// +build !linux,!darwin
|
||||
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func runFuse(cmd *Command, args []string) bool {
|
||||
fmt.Printf("Fuse is not supported on %s %s\n", runtime.GOOS, runtime.GOARCH)
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
//go:build linux || darwin
|
||||
// +build linux darwin
|
||||
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
type parameter struct {
|
||||
name string
|
||||
value string
|
||||
}
|
||||
|
||||
func runFuse(cmd *Command, args []string) bool {
|
||||
rawArgs := strings.Join(args, " ")
|
||||
rawArgsLen := len(rawArgs)
|
||||
option := strings.Builder{}
|
||||
options := []parameter{}
|
||||
masterProcess := true
|
||||
fusermountPath := ""
|
||||
|
||||
// first parameter
|
||||
i := 0
|
||||
for i = 0; i < rawArgsLen && rawArgs[i] != ' '; i++ {
|
||||
option.WriteByte(rawArgs[i])
|
||||
}
|
||||
options = append(options, parameter{"arg0", option.String()})
|
||||
option.Reset()
|
||||
|
||||
for i++; i < rawArgsLen; i++ {
|
||||
|
||||
// space separator check for filled option
|
||||
if rawArgs[i] == ' ' {
|
||||
if option.Len() > 0 {
|
||||
options = append(options, parameter{option.String(), "true"})
|
||||
option.Reset()
|
||||
}
|
||||
|
||||
// dash separator read option until next space
|
||||
} else if rawArgs[i] == '-' {
|
||||
for i++; i < rawArgsLen && rawArgs[i] != ' '; i++ {
|
||||
option.WriteByte(rawArgs[i])
|
||||
}
|
||||
// ignore "-o"
|
||||
if option.String() != "o" {
|
||||
options = append(options, parameter{option.String(), "true"})
|
||||
}
|
||||
option.Reset()
|
||||
|
||||
// equal separator start option with pending value
|
||||
} else if rawArgs[i] == '=' {
|
||||
name := option.String()
|
||||
option.Reset()
|
||||
|
||||
for i++; i < rawArgsLen && rawArgs[i] != ',' && rawArgs[i] != ' '; i++ {
|
||||
// double quote separator read option until next double quote
|
||||
if rawArgs[i] == '"' {
|
||||
for i++; i < rawArgsLen && rawArgs[i] != '"'; i++ {
|
||||
option.WriteByte(rawArgs[i])
|
||||
}
|
||||
|
||||
// single quote separator read option until next single quote
|
||||
} else if rawArgs[i] == '\'' {
|
||||
for i++; i < rawArgsLen && rawArgs[i] != '\''; i++ {
|
||||
option.WriteByte(rawArgs[i])
|
||||
}
|
||||
|
||||
// add chars before comma
|
||||
} else if rawArgs[i] != ' ' {
|
||||
option.WriteByte(rawArgs[i])
|
||||
}
|
||||
}
|
||||
|
||||
options = append(options, parameter{name, option.String()})
|
||||
option.Reset()
|
||||
|
||||
// comma separator just read current option
|
||||
} else if rawArgs[i] == ',' {
|
||||
options = append(options, parameter{option.String(), "true"})
|
||||
option.Reset()
|
||||
|
||||
// what is not a separator fill option buffer
|
||||
} else {
|
||||
option.WriteByte(rawArgs[i])
|
||||
}
|
||||
}
|
||||
|
||||
// get residual option data
|
||||
if option.Len() > 0 {
|
||||
// add value to pending option
|
||||
options = append(options, parameter{option.String(), "true"})
|
||||
option.Reset()
|
||||
}
|
||||
|
||||
// scan each parameter
|
||||
for i := 0; i < len(options); i++ {
|
||||
parameter := options[i]
|
||||
|
||||
switch parameter.name {
|
||||
case "child":
|
||||
masterProcess = false
|
||||
if parsed, err := strconv.ParseInt(parameter.value, 10, 64); err == nil {
|
||||
if parsed > math.MaxInt || parsed <= 0 {
|
||||
panic(fmt.Errorf("parent PID %d is invalid", parsed))
|
||||
}
|
||||
mountOptions.fuseCommandPid = int(parsed)
|
||||
} else {
|
||||
panic(fmt.Errorf("parent PID %s is invalid: %w", parameter.value, err))
|
||||
}
|
||||
case "arg0":
|
||||
mountOptions.dir = ¶meter.value
|
||||
case "filer":
|
||||
mountOptions.filer = ¶meter.value
|
||||
case "filer.path":
|
||||
mountOptions.filerMountRootPath = ¶meter.value
|
||||
case "dirAutoCreate":
|
||||
if parsed, err := strconv.ParseBool(parameter.value); err == nil {
|
||||
mountOptions.dirAutoCreate = &parsed
|
||||
} else {
|
||||
panic(fmt.Errorf("dirAutoCreate: %s", err))
|
||||
}
|
||||
case "collection":
|
||||
mountOptions.collection = ¶meter.value
|
||||
case "replication":
|
||||
mountOptions.replication = ¶meter.value
|
||||
case "disk":
|
||||
mountOptions.diskType = ¶meter.value
|
||||
case "ttl":
|
||||
if parsed, err := strconv.ParseInt(parameter.value, 0, 32); err == nil {
|
||||
intValue := int(parsed)
|
||||
mountOptions.ttlSec = &intValue
|
||||
} else {
|
||||
panic(fmt.Errorf("ttl: %s", err))
|
||||
}
|
||||
case "chunkSizeLimitMB":
|
||||
if parsed, err := strconv.ParseInt(parameter.value, 0, 32); err == nil {
|
||||
intValue := int(parsed)
|
||||
mountOptions.chunkSizeLimitMB = &intValue
|
||||
} else {
|
||||
panic(fmt.Errorf("chunkSizeLimitMB: %s", err))
|
||||
}
|
||||
case "concurrentWriters":
|
||||
i++
|
||||
if parsed, err := strconv.ParseInt(parameter.value, 0, 32); err == nil {
|
||||
intValue := int(parsed)
|
||||
mountOptions.concurrentWriters = &intValue
|
||||
} else {
|
||||
panic(fmt.Errorf("concurrentWriters: %s", err))
|
||||
}
|
||||
case "cacheDir":
|
||||
mountOptions.cacheDirForRead = ¶meter.value
|
||||
case "cacheCapacityMB":
|
||||
if parsed, err := strconv.ParseInt(parameter.value, 0, 64); err == nil {
|
||||
mountOptions.cacheSizeMBForRead = &parsed
|
||||
} else {
|
||||
panic(fmt.Errorf("cacheCapacityMB: %s", err))
|
||||
}
|
||||
case "cacheDirWrite":
|
||||
mountOptions.cacheDirForWrite = ¶meter.value
|
||||
case "dataCenter":
|
||||
mountOptions.dataCenter = ¶meter.value
|
||||
case "allowOthers":
|
||||
if parsed, err := strconv.ParseBool(parameter.value); err == nil {
|
||||
mountOptions.allowOthers = &parsed
|
||||
} else {
|
||||
panic(fmt.Errorf("allowOthers: %s", err))
|
||||
}
|
||||
case "umask":
|
||||
mountOptions.umaskString = ¶meter.value
|
||||
case "nonempty":
|
||||
if parsed, err := strconv.ParseBool(parameter.value); err == nil {
|
||||
mountOptions.nonempty = &parsed
|
||||
} else {
|
||||
panic(fmt.Errorf("nonempty: %s", err))
|
||||
}
|
||||
case "volumeServerAccess":
|
||||
mountOptions.volumeServerAccess = ¶meter.value
|
||||
case "map.uid":
|
||||
mountOptions.uidMap = ¶meter.value
|
||||
case "map.gid":
|
||||
mountOptions.gidMap = ¶meter.value
|
||||
case "readOnly":
|
||||
if parsed, err := strconv.ParseBool(parameter.value); err == nil {
|
||||
mountOptions.readOnly = &parsed
|
||||
} else {
|
||||
panic(fmt.Errorf("readOnly: %s", err))
|
||||
}
|
||||
case "cpuprofile":
|
||||
mountCpuProfile = ¶meter.value
|
||||
case "memprofile":
|
||||
mountMemProfile = ¶meter.value
|
||||
case "readRetryTime":
|
||||
if parsed, err := time.ParseDuration(parameter.value); err == nil {
|
||||
mountReadRetryTime = &parsed
|
||||
} else {
|
||||
panic(fmt.Errorf("readRetryTime: %s", err))
|
||||
}
|
||||
case "fusermount.path":
|
||||
fusermountPath = parameter.value
|
||||
default:
|
||||
t := parameter.name
|
||||
if parameter.value != "true" {
|
||||
t = fmt.Sprintf("%s=%s", parameter.name, parameter.value)
|
||||
}
|
||||
mountOptions.extraOptions = append(mountOptions.extraOptions, t)
|
||||
}
|
||||
}
|
||||
|
||||
// the master start the child, release it then finish himself
|
||||
if masterProcess {
|
||||
arg0, err := os.Executable()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// pass our PID to the child process
|
||||
pid := os.Getpid()
|
||||
argv := append(os.Args, "-o", "child="+strconv.Itoa(pid))
|
||||
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, syscall.SIGTERM)
|
||||
|
||||
attr := os.ProcAttr{}
|
||||
attr.Env = os.Environ()
|
||||
|
||||
child, err := os.StartProcess(arg0, argv, &attr)
|
||||
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("master process can not start child process: %s", err))
|
||||
}
|
||||
|
||||
err = child.Release()
|
||||
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("master process can not release child process: %s", err))
|
||||
}
|
||||
|
||||
select {
|
||||
case <-c:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if fusermountPath != "" {
|
||||
if err := os.Setenv("PATH", fusermountPath); err != nil {
|
||||
panic(fmt.Errorf("setenv: %s", err))
|
||||
}
|
||||
} else if os.Getenv("PATH") == "" {
|
||||
if err := os.Setenv("PATH", "/bin:/sbin:/usr/bin:/usr/sbin"); err != nil {
|
||||
panic(fmt.Errorf("setenv: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
// just call "weed mount" command
|
||||
return runMount(cmdMount, []string{})
|
||||
}
|
||||
+2
-1
@@ -3,6 +3,7 @@ package command
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/util/version"
|
||||
"net/http"
|
||||
|
||||
"time"
|
||||
@@ -89,7 +90,7 @@ func (iamopt *IamOptions) startIamServer() bool {
|
||||
glog.Fatalf("IAM API Server listener on %s error: %v", listenAddress, err)
|
||||
}
|
||||
|
||||
glog.V(0).Infof("Start Seaweed IAM API Server %s at http port %d", util.Version(), *iamopt.port)
|
||||
glog.V(0).Infof("Start Seaweed IAM API Server %s at http port %d", version.Version(), *iamopt.port)
|
||||
if iamApiLocalListener != nil {
|
||||
go func() {
|
||||
if err = httpS.Serve(iamApiLocalListener); err != nil {
|
||||
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
_ "github.com/seaweedfs/seaweedfs/weed/filer/redis2"
|
||||
_ "github.com/seaweedfs/seaweedfs/weed/filer/redis3"
|
||||
_ "github.com/seaweedfs/seaweedfs/weed/filer/sqlite"
|
||||
_ "github.com/seaweedfs/seaweedfs/weed/filer/tarantool"
|
||||
_ "github.com/seaweedfs/seaweedfs/weed/filer/tikv"
|
||||
_ "github.com/seaweedfs/seaweedfs/weed/filer/ydb"
|
||||
)
|
||||
|
||||
@@ -3,6 +3,7 @@ package command
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/util/version"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
@@ -160,7 +161,7 @@ func startMaster(masterOption MasterOptions, masterWhiteList []string) {
|
||||
r := mux.NewRouter()
|
||||
ms := weed_server.NewMasterServer(r, masterOption.toMasterOption(masterWhiteList), masterPeers)
|
||||
listeningAddress := util.JoinHostPort(*masterOption.ipBind, *masterOption.port)
|
||||
glog.V(0).Infof("Start Seaweed Master %s at %s", util.Version(), listeningAddress)
|
||||
glog.V(0).Infof("Start Seaweed Master %s at %s", version.Version(), listeningAddress)
|
||||
masterListener, masterLocalListener, e := util.NewIpAndLocalListeners(*masterOption.ipBind, *masterOption.port, 0)
|
||||
if e != nil {
|
||||
glog.Fatalf("Master startup error: %v", e)
|
||||
@@ -192,7 +193,7 @@ func startMaster(masterOption MasterOptions, masterWhiteList []string) {
|
||||
}
|
||||
}
|
||||
ms.SetRaftServer(raftServer)
|
||||
r.HandleFunc("/cluster/status", raftServer.StatusHandler).Methods(http.MethodGet)
|
||||
r.HandleFunc("/cluster/status", raftServer.StatusHandler).Methods(http.MethodGet, http.MethodHead)
|
||||
r.HandleFunc("/cluster/healthz", raftServer.HealthzHandler).Methods(http.MethodGet, http.MethodHead)
|
||||
if *masterOption.raftHashicorp {
|
||||
r.HandleFunc("/raft/stats", raftServer.StatsRaftHandler).Methods(http.MethodGet)
|
||||
@@ -211,7 +212,7 @@ func startMaster(masterOption MasterOptions, masterWhiteList []string) {
|
||||
protobuf.RegisterRaftServer(grpcS, raftServer)
|
||||
}
|
||||
reflection.Register(grpcS)
|
||||
glog.V(0).Infof("Start Seaweed Master %s grpc server at %s:%d", util.Version(), *masterOption.ipBind, grpcPort)
|
||||
glog.V(0).Infof("Start Seaweed Master %s grpc server at %s:%d", version.Version(), *masterOption.ipBind, grpcPort)
|
||||
if grpcLocalL != nil {
|
||||
go grpcS.Serve(grpcLocalL)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package command
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/util/version"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
@@ -119,7 +120,7 @@ func startMasterFollower(masterOptions MasterOptions) {
|
||||
r := mux.NewRouter()
|
||||
ms := weed_server.NewMasterServer(r, option, masters)
|
||||
listeningAddress := util.JoinHostPort(*masterOptions.ipBind, *masterOptions.port)
|
||||
glog.V(0).Infof("Start Seaweed Master %s at %s", util.Version(), listeningAddress)
|
||||
glog.V(0).Infof("Start Seaweed Master %s at %s", version.Version(), listeningAddress)
|
||||
masterListener, masterLocalListener, e := util.NewIpAndLocalListeners(*masterOptions.ipBind, *masterOptions.port, 0)
|
||||
if e != nil {
|
||||
glog.Fatalf("Master startup error: %v", e)
|
||||
@@ -134,7 +135,7 @@ func startMasterFollower(masterOptions MasterOptions) {
|
||||
grpcS := pb.NewGrpcServer(security.LoadServerTLS(util.GetViper(), "grpc.master"))
|
||||
master_pb.RegisterSeaweedServer(grpcS, ms)
|
||||
reflection.Register(grpcS)
|
||||
glog.V(0).Infof("Start Seaweed Master %s grpc server at %s:%d", util.Version(), *masterOptions.ip, grpcPort)
|
||||
glog.V(0).Infof("Start Seaweed Master %s grpc server at %s:%d", version.Version(), *masterOptions.ip, grpcPort)
|
||||
if grpcLocalL != nil {
|
||||
go grpcS.Serve(grpcLocalL)
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ type MountOptions struct {
|
||||
localSocket *string
|
||||
disableXAttr *bool
|
||||
extraOptions []string
|
||||
fuseCommandPid int
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -72,6 +73,7 @@ func init() {
|
||||
mountOptions.debugPort = cmdMount.Flag.Int("debug.port", 6061, "http port for debugging")
|
||||
mountOptions.localSocket = cmdMount.Flag.String("localSocket", "", "default to /tmp/seaweedfs-mount-<mount_dir_hash>.sock")
|
||||
mountOptions.disableXAttr = cmdMount.Flag.Bool("disableXAttr", false, "disable xattr")
|
||||
mountOptions.fuseCommandPid = 0
|
||||
|
||||
mountCpuProfile = cmdMount.Flag.String("cpuprofile", "", "cpu profile output file")
|
||||
mountMemProfile = cmdMount.Flag.String("memprofile", "", "memory profile output file")
|
||||
|
||||
@@ -6,6 +6,7 @@ package command
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/util/version"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -13,6 +14,7 @@ import (
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/hanwen/go-fuse/v2/fuse"
|
||||
@@ -61,7 +63,7 @@ func RunMount(option *MountOptions, umask os.FileMode) bool {
|
||||
// basic checks
|
||||
chunkSizeLimitMB := *mountOptions.chunkSizeLimitMB
|
||||
if chunkSizeLimitMB <= 0 {
|
||||
fmt.Printf("Please specify a reasonable buffer size.")
|
||||
fmt.Printf("Please specify a reasonable buffer size.\n")
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -255,7 +257,7 @@ func RunMount(option *MountOptions, umask os.FileMode) bool {
|
||||
// create mount root
|
||||
mountRootPath := util.FullPath(mountRoot)
|
||||
mountRootParent, mountDir := mountRootPath.DirAndName()
|
||||
if err = filer_pb.Mkdir(seaweedFileSystem, mountRootParent, mountDir, nil); err != nil {
|
||||
if err = filer_pb.Mkdir(context.Background(), seaweedFileSystem, mountRootParent, mountDir, nil); err != nil {
|
||||
fmt.Printf("failed to create dir %s on filer %s: %v\n", mountRoot, filerAddresses, err)
|
||||
return false
|
||||
}
|
||||
@@ -268,6 +270,15 @@ func RunMount(option *MountOptions, umask os.FileMode) bool {
|
||||
unmount.Unmount(dir)
|
||||
})
|
||||
|
||||
if mountOptions.fuseCommandPid != 0 {
|
||||
// send a signal to the parent process to notify that the mount is ready
|
||||
err = syscall.Kill(mountOptions.fuseCommandPid, syscall.SIGTERM)
|
||||
if err != nil {
|
||||
fmt.Printf("failed to notify parent process: %v\n", err)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
grpcS := pb.NewGrpcServer()
|
||||
mount_pb.RegisterSeaweedMountServer(grpcS, seaweedFileSystem)
|
||||
reflection.Register(grpcS)
|
||||
@@ -280,9 +291,11 @@ func RunMount(option *MountOptions, umask os.FileMode) bool {
|
||||
}
|
||||
|
||||
glog.V(0).Infof("mounted %s%s to %v", *option.filer, mountRoot, dir)
|
||||
glog.V(0).Infof("This is SeaweedFS version %s %s %s", util.Version(), runtime.GOOS, runtime.GOARCH)
|
||||
glog.V(0).Infof("This is SeaweedFS version %s %s %s", version.Version(), runtime.GOOS, runtime.GOARCH)
|
||||
|
||||
server.Serve()
|
||||
|
||||
seaweedFileSystem.ClearCacheDir()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -26,12 +26,12 @@ type MessageQueueAgentOptions struct {
|
||||
func init() {
|
||||
cmdMqAgent.Run = runMqAgent // break init cycle
|
||||
mqAgentOptions.brokersString = cmdMqAgent.Flag.String("broker", "localhost:17777", "comma-separated message queue brokers")
|
||||
mqAgentOptions.ip = cmdMqAgent.Flag.String("ip", "localhost", "message queue agent host address")
|
||||
mqAgentOptions.ip = cmdMqAgent.Flag.String("ip", "", "message queue agent host address")
|
||||
mqAgentOptions.port = cmdMqAgent.Flag.Int("port", 16777, "message queue agent gRPC server port")
|
||||
}
|
||||
|
||||
var cmdMqAgent = &Command{
|
||||
UsageLine: "mq.agent [-port=6377] [-master=<ip:port>]",
|
||||
UsageLine: "mq.agent [-port=16777] [-broker=<ip:port>]",
|
||||
Short: "<WIP> start a message queue agent",
|
||||
Long: `start a message queue agent
|
||||
|
||||
@@ -64,6 +64,7 @@ func (mqAgentOpt *MessageQueueAgentOptions) startQueueAgent() bool {
|
||||
if err != nil {
|
||||
glog.Fatalf("failed to listen on grpc port %d: %v", *mqAgentOpt.port, err)
|
||||
}
|
||||
glog.Infof("Start Seaweed Message Queue Agent on %s:%d", *mqAgentOpt.ip, *mqAgentOpt.port)
|
||||
grpcS := pb.NewGrpcServer()
|
||||
mq_agent_pb.RegisterSeaweedMessagingAgentServer(grpcS, agentServer)
|
||||
reflection.Register(grpcS)
|
||||
|
||||
+11
-7
@@ -5,6 +5,7 @@ import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/util/version"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -57,6 +58,7 @@ type S3Options struct {
|
||||
dataCenter *string
|
||||
localSocket *string
|
||||
certProvider certprovider.Provider
|
||||
idleTimeout *int
|
||||
}
|
||||
|
||||
func init() {
|
||||
@@ -81,6 +83,7 @@ func init() {
|
||||
s3StandaloneOptions.allowDeleteBucketNotEmpty = cmdS3.Flag.Bool("allowDeleteBucketNotEmpty", true, "allow recursive deleting all entries along with bucket")
|
||||
s3StandaloneOptions.localFilerSocket = cmdS3.Flag.String("localFilerSocket", "", "local filer socket path")
|
||||
s3StandaloneOptions.localSocket = cmdS3.Flag.String("localSocket", "", "default to /tmp/seaweedfs-s3-<port>.sock")
|
||||
s3StandaloneOptions.idleTimeout = cmdS3.Flag.Int("idleTimeout", 10, "connection idle seconds")
|
||||
}
|
||||
|
||||
var cmdS3 = &Command{
|
||||
@@ -275,7 +278,8 @@ func (s3opt *S3Options) startS3Server() bool {
|
||||
}
|
||||
|
||||
listenAddress := fmt.Sprintf("%s:%d", *s3opt.bindIp, *s3opt.port)
|
||||
s3ApiListener, s3ApiLocalListener, err := util.NewIpAndLocalListeners(*s3opt.bindIp, *s3opt.port, time.Duration(10)*time.Second)
|
||||
s3ApiListener, s3ApiLocalListener, err := util.NewIpAndLocalListeners(
|
||||
*s3opt.bindIp, *s3opt.port, time.Duration(*s3opt.idleTimeout)*time.Second)
|
||||
if err != nil {
|
||||
glog.Fatalf("S3 API Server listener on %s error: %v", listenAddress, err)
|
||||
}
|
||||
@@ -312,7 +316,7 @@ func (s3opt *S3Options) startS3Server() bool {
|
||||
}
|
||||
|
||||
caCertPool := x509.NewCertPool()
|
||||
if *s3Options.tlsCACertificate != "" {
|
||||
if *s3opt.tlsCACertificate != "" {
|
||||
// load CA certificate file and add it to list of client CAs
|
||||
caCertFile, err := ioutil.ReadFile(*s3opt.tlsCACertificate)
|
||||
if err != nil {
|
||||
@@ -322,7 +326,7 @@ func (s3opt *S3Options) startS3Server() bool {
|
||||
}
|
||||
|
||||
clientAuth := tls.NoClientCert
|
||||
if *s3Options.tlsVerifyClientCert {
|
||||
if *s3opt.tlsVerifyClientCert {
|
||||
clientAuth = tls.RequireAndVerifyClientCert
|
||||
}
|
||||
|
||||
@@ -336,7 +340,7 @@ func (s3opt *S3Options) startS3Server() bool {
|
||||
glog.Fatalf("error with tls config: %v", err)
|
||||
}
|
||||
if *s3opt.portHttps == 0 {
|
||||
glog.V(0).Infof("Start Seaweed S3 API Server %s at https port %d", util.Version(), *s3opt.port)
|
||||
glog.V(0).Infof("Start Seaweed S3 API Server %s at https port %d", version.Version(), *s3opt.port)
|
||||
if s3ApiLocalListener != nil {
|
||||
go func() {
|
||||
if err = httpS.ServeTLS(s3ApiLocalListener, "", ""); err != nil {
|
||||
@@ -348,9 +352,9 @@ func (s3opt *S3Options) startS3Server() bool {
|
||||
glog.Fatalf("S3 API Server Fail to serve: %v", err)
|
||||
}
|
||||
} else {
|
||||
glog.V(0).Infof("Start Seaweed S3 API Server %s at https port %d", util.Version(), *s3opt.portHttps)
|
||||
glog.V(0).Infof("Start Seaweed S3 API Server %s at https port %d", version.Version(), *s3opt.portHttps)
|
||||
s3ApiListenerHttps, s3ApiLocalListenerHttps, _ := util.NewIpAndLocalListeners(
|
||||
*s3opt.bindIp, *s3opt.portHttps, time.Duration(10)*time.Second)
|
||||
*s3opt.bindIp, *s3opt.portHttps, time.Duration(*s3opt.idleTimeout)*time.Second)
|
||||
if s3ApiLocalListenerHttps != nil {
|
||||
go func() {
|
||||
if err = httpS.ServeTLS(s3ApiLocalListenerHttps, "", ""); err != nil {
|
||||
@@ -366,7 +370,7 @@ func (s3opt *S3Options) startS3Server() bool {
|
||||
}
|
||||
}
|
||||
if *s3opt.tlsPrivateKey == "" || *s3opt.portHttps > 0 {
|
||||
glog.V(0).Infof("Start Seaweed S3 API Server %s at http port %d", util.Version(), *s3opt.port)
|
||||
glog.V(0).Infof("Start Seaweed S3 API Server %s at http port %d", version.Version(), *s3opt.port)
|
||||
if s3ApiLocalListener != nil {
|
||||
go func() {
|
||||
if err = httpS.Serve(s3ApiLocalListener); err != nil {
|
||||
|
||||
@@ -54,6 +54,10 @@ enabled = false
|
||||
# dsn will take priority over "hostname, port, username, password, database".
|
||||
# [username[:password]@][protocol[(address)]]/dbname[?param1=value1&...¶mN=valueN]
|
||||
dsn = "root@tcp(localhost:3306)/seaweedfs?collation=utf8mb4_bin"
|
||||
enable_tls = false
|
||||
ca_crt = "" # ca.crt dir when enable_tls set true
|
||||
client_crt = "" # mysql client.crt dir when enable_tls set true
|
||||
client_key = "" # mysql client.key dir when enable_tls set true
|
||||
hostname = "localhost"
|
||||
port = 3306
|
||||
username = "root"
|
||||
@@ -112,7 +116,13 @@ connection_max_open = 100
|
||||
connection_max_lifetime_seconds = 0
|
||||
# if insert/upsert failing, you can disable upsert or update query syntax to match your RDBMS syntax:
|
||||
enableUpsert = true
|
||||
upsertQuery = """UPSERT INTO "%[1]s" (dirhash,name,directory,meta) VALUES($1,$2,$3,$4)"""
|
||||
upsertQuery = """
|
||||
INSERT INTO "%[1]s" (dirhash, name, directory, meta)
|
||||
VALUES($1, $2, $3, $4)
|
||||
ON CONFLICT (dirhash, name) DO UPDATE SET
|
||||
directory=EXCLUDED.directory,
|
||||
meta=EXCLUDED.meta
|
||||
"""
|
||||
|
||||
[postgres2]
|
||||
enabled = false
|
||||
@@ -137,14 +147,21 @@ connection_max_open = 100
|
||||
connection_max_lifetime_seconds = 0
|
||||
# if insert/upsert failing, you can disable upsert or update query syntax to match your RDBMS syntax:
|
||||
enableUpsert = true
|
||||
upsertQuery = """UPSERT INTO "%[1]s" (dirhash,name,directory,meta) VALUES($1,$2,$3,$4)"""
|
||||
upsertQuery = """
|
||||
INSERT INTO "%[1]s" (dirhash, name, directory, meta)
|
||||
VALUES($1, $2, $3, $4)
|
||||
ON CONFLICT (dirhash, name) DO UPDATE SET
|
||||
directory=EXCLUDED.directory,
|
||||
meta=EXCLUDED.meta
|
||||
"""
|
||||
|
||||
[cassandra]
|
||||
[cassandra2]
|
||||
# CREATE TABLE filemeta (
|
||||
# dirhash bigint,
|
||||
# directory varchar,
|
||||
# name varchar,
|
||||
# meta blob,
|
||||
# PRIMARY KEY (directory, name)
|
||||
# PRIMARY KEY ((dirhash, directory), name)
|
||||
# ) WITH CLUSTERING ORDER BY (name ASC);
|
||||
enabled = false
|
||||
keyspace = "seaweedfs"
|
||||
@@ -170,6 +187,10 @@ enabled = false
|
||||
address = "localhost:6379"
|
||||
password = ""
|
||||
database = 0
|
||||
enable_tls = false
|
||||
ca_cert_path = ""
|
||||
client_cert_path = ""
|
||||
client_key_path = ""
|
||||
# This changes the data layout. Only add new directories. Removing/Updating will cause data loss.
|
||||
superLargeDirectories = []
|
||||
|
||||
@@ -180,6 +201,10 @@ masterName = "master"
|
||||
username = ""
|
||||
password = ""
|
||||
database = 0
|
||||
enable_tls = false
|
||||
ca_cert_path = ""
|
||||
client_cert_path = ""
|
||||
client_key_path = ""
|
||||
|
||||
[redis_cluster2]
|
||||
enabled = false
|
||||
@@ -192,6 +217,10 @@ addresses = [
|
||||
"localhost:30006",
|
||||
]
|
||||
password = ""
|
||||
enable_tls = false
|
||||
ca_cert_path = ""
|
||||
client_cert_path = ""
|
||||
client_key_path = ""
|
||||
# allows reads from slave servers or the master, but all writes still go to the master
|
||||
readOnly = false
|
||||
# automatically use the closest Redis server for reads
|
||||
@@ -199,11 +228,16 @@ routeByLatency = false
|
||||
# This changes the data layout. Only add new directories. Removing/Updating will cause data loss.
|
||||
superLargeDirectories = []
|
||||
|
||||
# The following lua redis stores uses lua to ensure atomicity
|
||||
[redis_lua]
|
||||
enabled = false
|
||||
address = "localhost:6379"
|
||||
password = ""
|
||||
database = 0
|
||||
enable_tls = false
|
||||
ca_cert_path = ""
|
||||
client_cert_path = ""
|
||||
client_key_path = ""
|
||||
# This changes the data layout. Only add new directories. Removing/Updating will cause data loss.
|
||||
superLargeDirectories = []
|
||||
|
||||
@@ -214,6 +248,10 @@ masterName = "master"
|
||||
username = ""
|
||||
password = ""
|
||||
database = 0
|
||||
enable_tls = false
|
||||
ca_cert_path = ""
|
||||
client_cert_path = ""
|
||||
client_key_path = ""
|
||||
|
||||
[redis_lua_cluster]
|
||||
enabled = false
|
||||
@@ -226,6 +264,10 @@ addresses = [
|
||||
"localhost:30006",
|
||||
]
|
||||
password = ""
|
||||
enable_tls = false
|
||||
ca_cert_path = ""
|
||||
client_cert_path = ""
|
||||
client_key_path = ""
|
||||
# allows reads from slave servers or the master, but all writes still go to the master
|
||||
readOnly = false
|
||||
# automatically use the closest Redis server for reads
|
||||
@@ -233,36 +275,6 @@ routeByLatency = false
|
||||
# This changes the data layout. Only add new directories. Removing/Updating will cause data loss.
|
||||
superLargeDirectories = []
|
||||
|
||||
[redis3] # beta
|
||||
enabled = false
|
||||
address = "localhost:6379"
|
||||
password = ""
|
||||
database = 0
|
||||
|
||||
[redis3_sentinel]
|
||||
enabled = false
|
||||
addresses = ["172.22.12.7:26379","172.22.12.8:26379","172.22.12.9:26379"]
|
||||
masterName = "master"
|
||||
username = ""
|
||||
password = ""
|
||||
database = 0
|
||||
|
||||
[redis_cluster3] # beta
|
||||
enabled = false
|
||||
addresses = [
|
||||
"localhost:30001",
|
||||
"localhost:30002",
|
||||
"localhost:30003",
|
||||
"localhost:30004",
|
||||
"localhost:30005",
|
||||
"localhost:30006",
|
||||
]
|
||||
password = ""
|
||||
# allows reads from slave servers or the master, but all writes still go to the master
|
||||
readOnly = false
|
||||
# automatically use the closest Redis server for reads
|
||||
routeByLatency = false
|
||||
|
||||
[etcd]
|
||||
enabled = false
|
||||
servers = "localhost:2379"
|
||||
@@ -333,7 +345,7 @@ dialTimeOut = 10
|
||||
##########################
|
||||
# To add path-specific filer store:
|
||||
#
|
||||
# 1. Add a name following the store type separated by a dot ".". E.g., cassandra.tmp
|
||||
# 1. Add a name following the store type separated by a dot ".". E.g., cassandra2.tmp
|
||||
# 2. Add a location configuration. E.g., location = "/tmp/"
|
||||
# 3. Copy and customize all other configurations.
|
||||
# Make sure they are not the same if using the same store type!
|
||||
@@ -365,3 +377,10 @@ cert_path=""
|
||||
key_path=""
|
||||
# The name list used to verify the cn name
|
||||
verify_cn=""
|
||||
|
||||
[tarantool]
|
||||
address = "localhost:3301"
|
||||
user = "guest"
|
||||
password = ""
|
||||
timeout = "5s"
|
||||
maxReconnects = 1000
|
||||
|
||||
+35
-1
@@ -28,6 +28,7 @@ var (
|
||||
masterOptions MasterOptions
|
||||
filerOptions FilerOptions
|
||||
s3Options S3Options
|
||||
sftpOptions SftpOptions
|
||||
iamOptions IamOptions
|
||||
webdavOptions WebDavOption
|
||||
mqBrokerOptions MessageQueueBrokerOptions
|
||||
@@ -73,6 +74,7 @@ var (
|
||||
isStartingVolumeServer = cmdServer.Flag.Bool("volume", true, "whether to start volume server")
|
||||
isStartingFiler = cmdServer.Flag.Bool("filer", false, "whether to start filer")
|
||||
isStartingS3 = cmdServer.Flag.Bool("s3", false, "whether to start S3 gateway")
|
||||
isStartingSftp = cmdServer.Flag.Bool("sftp", false, "whether to start Sftp server")
|
||||
isStartingIam = cmdServer.Flag.Bool("iam", false, "whether to start IAM service")
|
||||
isStartingWebDav = cmdServer.Flag.Bool("webdav", false, "whether to start WebDAV gateway")
|
||||
isStartingMqBroker = cmdServer.Flag.Bool("mq.broker", false, "whether to start message queue broker")
|
||||
@@ -156,7 +158,20 @@ func init() {
|
||||
s3Options.allowEmptyFolder = cmdServer.Flag.Bool("s3.allowEmptyFolder", true, "allow empty folders")
|
||||
s3Options.allowDeleteBucketNotEmpty = cmdServer.Flag.Bool("s3.allowDeleteBucketNotEmpty", true, "allow recursive deleting all entries along with bucket")
|
||||
s3Options.localSocket = cmdServer.Flag.String("s3.localSocket", "", "default to /tmp/seaweedfs-s3-<port>.sock")
|
||||
s3Options.bindIp = cmdServer.Flag.String("s3.ip.bind", "", "ip address to bind to. If empty, default to same as -ip.bind option.")
|
||||
s3Options.idleTimeout = cmdServer.Flag.Int("s3.idleTimeout", 10, "connection idle seconds")
|
||||
|
||||
sftpOptions.port = cmdServer.Flag.Int("sftp.port", 2022, "SFTP server listen port")
|
||||
sftpOptions.sshPrivateKey = cmdServer.Flag.String("sftp.sshPrivateKey", "", "path to the SSH private key file for host authentication")
|
||||
sftpOptions.hostKeysFolder = cmdServer.Flag.String("sftp.hostKeysFolder", "", "path to folder containing SSH private key files for host authentication")
|
||||
sftpOptions.authMethods = cmdServer.Flag.String("sftp.authMethods", "password,publickey", "comma-separated list of allowed auth methods: password, publickey, keyboard-interactive")
|
||||
sftpOptions.maxAuthTries = cmdServer.Flag.Int("sftp.maxAuthTries", 6, "maximum number of authentication attempts per connection")
|
||||
sftpOptions.bannerMessage = cmdServer.Flag.String("sftp.bannerMessage", "SeaweedFS SFTP Server - Unauthorized access is prohibited", "message displayed before authentication")
|
||||
sftpOptions.loginGraceTime = cmdServer.Flag.Duration("sftp.loginGraceTime", 2*time.Minute, "timeout for authentication")
|
||||
sftpOptions.clientAliveInterval = cmdServer.Flag.Duration("sftp.clientAliveInterval", 5*time.Second, "interval for sending keep-alive messages")
|
||||
sftpOptions.clientAliveCountMax = cmdServer.Flag.Int("sftp.clientAliveCountMax", 3, "maximum number of missed keep-alive messages before disconnecting")
|
||||
sftpOptions.userStoreFile = cmdServer.Flag.String("sftp.userStoreFile", "", "path to JSON file containing user credentials and permissions")
|
||||
sftpOptions.localSocket = cmdServer.Flag.String("sftp.localSocket", "", "default to /tmp/seaweedfs-sftp-<port>.sock")
|
||||
iamOptions.port = cmdServer.Flag.Int("iam.port", 8111, "iam server http listen port")
|
||||
|
||||
webdavOptions.port = cmdServer.Flag.Int("webdav.port", 7333, "webdav server http listen port")
|
||||
@@ -188,6 +203,9 @@ func runServer(cmd *Command, args []string) bool {
|
||||
if *isStartingS3 {
|
||||
*isStartingFiler = true
|
||||
}
|
||||
if *isStartingSftp {
|
||||
*isStartingFiler = true
|
||||
}
|
||||
if *isStartingIam {
|
||||
*isStartingFiler = true
|
||||
}
|
||||
@@ -218,9 +236,15 @@ func runServer(cmd *Command, args []string) bool {
|
||||
filerOptions.masters = pb.ServerAddresses(*masterOptions.peers).ToServiceDiscovery()
|
||||
filerOptions.ip = serverIp
|
||||
filerOptions.bindIp = serverBindIp
|
||||
s3Options.bindIp = serverBindIp
|
||||
if *s3Options.bindIp == "" {
|
||||
s3Options.bindIp = serverBindIp
|
||||
}
|
||||
if sftpOptions.bindIp == nil || *sftpOptions.bindIp == "" {
|
||||
sftpOptions.bindIp = serverBindIp
|
||||
}
|
||||
iamOptions.ip = serverBindIp
|
||||
iamOptions.masters = masterOptions.peers
|
||||
webdavOptions.ipBind = serverBindIp
|
||||
serverOptions.v.ip = serverIp
|
||||
serverOptions.v.bindIp = serverBindIp
|
||||
serverOptions.v.masters = pb.ServerAddresses(*masterOptions.peers).ToAddresses()
|
||||
@@ -241,11 +265,13 @@ func runServer(cmd *Command, args []string) bool {
|
||||
mqBrokerOptions.dataCenter = serverDataCenter
|
||||
mqBrokerOptions.rack = serverRack
|
||||
s3Options.dataCenter = serverDataCenter
|
||||
sftpOptions.dataCenter = serverDataCenter
|
||||
filerOptions.disableHttp = serverDisableHttp
|
||||
masterOptions.disableHttp = serverDisableHttp
|
||||
|
||||
filerAddress := string(pb.NewServerAddress(*serverIp, *filerOptions.port, *filerOptions.portGrpc))
|
||||
s3Options.filer = &filerAddress
|
||||
sftpOptions.filer = &filerAddress
|
||||
iamOptions.filer = &filerAddress
|
||||
webdavOptions.filer = &filerAddress
|
||||
mqBrokerOptions.filerGroup = filerOptions.filerGroup
|
||||
@@ -286,6 +312,14 @@ func runServer(cmd *Command, args []string) bool {
|
||||
}()
|
||||
}
|
||||
|
||||
if *isStartingSftp {
|
||||
go func() {
|
||||
time.Sleep(2 * time.Second)
|
||||
sftpOptions.localSocket = filerOptions.localSocket
|
||||
sftpOptions.startSftpServer()
|
||||
}()
|
||||
}
|
||||
|
||||
if *isStartingIam {
|
||||
go func() {
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/util/version"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/seaweedfs/seaweedfs/weed/glog"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb"
|
||||
filer_pb "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/security"
|
||||
"github.com/seaweedfs/seaweedfs/weed/sftpd"
|
||||
stats_collect "github.com/seaweedfs/seaweedfs/weed/stats"
|
||||
"github.com/seaweedfs/seaweedfs/weed/util"
|
||||
)
|
||||
|
||||
var (
|
||||
sftpOptionsStandalone SftpOptions
|
||||
)
|
||||
|
||||
// SftpOptions holds configuration options for the SFTP server.
|
||||
type SftpOptions struct {
|
||||
filer *string
|
||||
bindIp *string
|
||||
port *int
|
||||
sshPrivateKey *string
|
||||
hostKeysFolder *string
|
||||
authMethods *string
|
||||
maxAuthTries *int
|
||||
bannerMessage *string
|
||||
loginGraceTime *time.Duration
|
||||
clientAliveInterval *time.Duration
|
||||
clientAliveCountMax *int
|
||||
userStoreFile *string
|
||||
dataCenter *string
|
||||
metricsHttpPort *int
|
||||
metricsHttpIp *string
|
||||
localSocket *string
|
||||
}
|
||||
|
||||
// cmdSftp defines the SFTP command similar to the S3 command.
|
||||
var cmdSftp = &Command{
|
||||
UsageLine: "sftp [-port=2022] [-filer=<ip:port>] [-sshPrivateKey=</path/to/private_key>]",
|
||||
Short: "start an SFTP server that is backed by a SeaweedFS filer",
|
||||
Long: `Start an SFTP server that leverages the SeaweedFS filer service to handle file operations.
|
||||
|
||||
Instead of reading from or writing to a local filesystem, all file operations
|
||||
are routed through the filer (filer_pb) gRPC API. This allows you to centralize
|
||||
your file management in SeaweedFS.
|
||||
`,
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Register the command to avoid cyclic dependencies.
|
||||
cmdSftp.Run = runSftp
|
||||
|
||||
sftpOptionsStandalone.filer = cmdSftp.Flag.String("filer", "localhost:8888", "filer server address (ip:port)")
|
||||
sftpOptionsStandalone.bindIp = cmdSftp.Flag.String("ip.bind", "0.0.0.0", "ip address to bind SFTP server")
|
||||
sftpOptionsStandalone.port = cmdSftp.Flag.Int("port", 2022, "SFTP server listen port")
|
||||
sftpOptionsStandalone.sshPrivateKey = cmdSftp.Flag.String("sshPrivateKey", "", "path to the SSH private key file for host authentication")
|
||||
sftpOptionsStandalone.hostKeysFolder = cmdSftp.Flag.String("hostKeysFolder", "", "path to folder containing SSH private key files for host authentication")
|
||||
sftpOptionsStandalone.authMethods = cmdSftp.Flag.String("authMethods", "password,publickey", "comma-separated list of allowed auth methods: password, publickey, keyboard-interactive")
|
||||
sftpOptionsStandalone.maxAuthTries = cmdSftp.Flag.Int("maxAuthTries", 6, "maximum number of authentication attempts per connection")
|
||||
sftpOptionsStandalone.bannerMessage = cmdSftp.Flag.String("bannerMessage", "SeaweedFS SFTP Server - Unauthorized access is prohibited", "message displayed before authentication")
|
||||
sftpOptionsStandalone.loginGraceTime = cmdSftp.Flag.Duration("loginGraceTime", 2*time.Minute, "timeout for authentication")
|
||||
sftpOptionsStandalone.clientAliveInterval = cmdSftp.Flag.Duration("clientAliveInterval", 5*time.Second, "interval for sending keep-alive messages")
|
||||
sftpOptionsStandalone.clientAliveCountMax = cmdSftp.Flag.Int("clientAliveCountMax", 3, "maximum number of missed keep-alive messages before disconnecting")
|
||||
sftpOptionsStandalone.userStoreFile = cmdSftp.Flag.String("userStoreFile", "", "path to JSON file containing user credentials and permissions")
|
||||
sftpOptionsStandalone.dataCenter = cmdSftp.Flag.String("dataCenter", "", "prefer to read and write to volumes in this data center")
|
||||
sftpOptionsStandalone.metricsHttpPort = cmdSftp.Flag.Int("metricsPort", 0, "Prometheus metrics listen port")
|
||||
sftpOptionsStandalone.metricsHttpIp = cmdSftp.Flag.String("metricsIp", "", "metrics listen ip. If empty, default to same as -ip.bind option.")
|
||||
sftpOptionsStandalone.localSocket = cmdSftp.Flag.String("localSocket", "", "default to /tmp/seaweedfs-sftp-<port>.sock")
|
||||
}
|
||||
|
||||
// runSftp is the command entry point.
|
||||
func runSftp(cmd *Command, args []string) bool {
|
||||
// Load security configuration as done in other SeaweedFS services.
|
||||
util.LoadSecurityConfiguration()
|
||||
|
||||
// Configure metrics
|
||||
switch {
|
||||
case *sftpOptionsStandalone.metricsHttpIp != "":
|
||||
// nothing to do, use sftpOptionsStandalone.metricsHttpIp
|
||||
case *sftpOptionsStandalone.bindIp != "":
|
||||
*sftpOptionsStandalone.metricsHttpIp = *sftpOptionsStandalone.bindIp
|
||||
}
|
||||
go stats_collect.StartMetricsServer(*sftpOptionsStandalone.metricsHttpIp, *sftpOptionsStandalone.metricsHttpPort)
|
||||
|
||||
return sftpOptionsStandalone.startSftpServer()
|
||||
}
|
||||
|
||||
func (sftpOpt *SftpOptions) startSftpServer() bool {
|
||||
filerAddress := pb.ServerAddress(*sftpOpt.filer)
|
||||
grpcDialOption := security.LoadClientTLS(util.GetViper(), "grpc.client")
|
||||
|
||||
// metrics read from the filer
|
||||
var metricsAddress string
|
||||
var metricsIntervalSec int
|
||||
var filerGroup string
|
||||
|
||||
// Connect to the filer service and try to retrieve basic configuration.
|
||||
for {
|
||||
err := pb.WithGrpcFilerClient(false, 0, filerAddress, grpcDialOption, func(client filer_pb.SeaweedFilerClient) error {
|
||||
resp, err := client.GetFilerConfiguration(context.Background(), &filer_pb.GetFilerConfigurationRequest{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("get filer %s configuration: %v", filerAddress, err)
|
||||
}
|
||||
metricsAddress, metricsIntervalSec = resp.MetricsAddress, int(resp.MetricsIntervalSec)
|
||||
filerGroup = resp.FilerGroup
|
||||
glog.V(0).Infof("SFTP read filer configuration, using filer at: %s", filerAddress)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
glog.V(0).Infof("Waiting to connect to filer %s grpc address %s...", *sftpOpt.filer, filerAddress.ToGrpcAddress())
|
||||
time.Sleep(time.Second)
|
||||
} else {
|
||||
glog.V(0).Infof("Connected to filer %s grpc address %s", *sftpOpt.filer, filerAddress.ToGrpcAddress())
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
go stats_collect.LoopPushingMetric("sftp", stats_collect.SourceName(uint32(*sftpOpt.port)), metricsAddress, metricsIntervalSec)
|
||||
|
||||
// Parse auth methods
|
||||
var authMethods []string
|
||||
if *sftpOpt.authMethods != "" {
|
||||
authMethods = util.StringSplit(*sftpOpt.authMethods, ",")
|
||||
}
|
||||
|
||||
// Create a new SFTP service instance with all options
|
||||
service := sftpd.NewSFTPService(&sftpd.SFTPServiceOptions{
|
||||
GrpcDialOption: grpcDialOption,
|
||||
DataCenter: *sftpOpt.dataCenter,
|
||||
FilerGroup: filerGroup,
|
||||
Filer: filerAddress,
|
||||
SshPrivateKey: *sftpOpt.sshPrivateKey,
|
||||
HostKeysFolder: *sftpOpt.hostKeysFolder,
|
||||
AuthMethods: authMethods,
|
||||
MaxAuthTries: *sftpOpt.maxAuthTries,
|
||||
BannerMessage: *sftpOpt.bannerMessage,
|
||||
LoginGraceTime: *sftpOpt.loginGraceTime,
|
||||
ClientAliveInterval: *sftpOpt.clientAliveInterval,
|
||||
ClientAliveCountMax: *sftpOpt.clientAliveCountMax,
|
||||
UserStoreFile: *sftpOpt.userStoreFile,
|
||||
})
|
||||
|
||||
// Set up Unix socket if on non-Windows platforms
|
||||
if runtime.GOOS != "windows" {
|
||||
localSocket := *sftpOpt.localSocket
|
||||
if localSocket == "" {
|
||||
localSocket = fmt.Sprintf("/tmp/seaweedfs-sftp-%d.sock", *sftpOpt.port)
|
||||
}
|
||||
if err := os.Remove(localSocket); err != nil && !os.IsNotExist(err) {
|
||||
glog.Fatalf("Failed to remove %s, error: %s", localSocket, err.Error())
|
||||
}
|
||||
go func() {
|
||||
// start on local unix socket
|
||||
sftpSocketListener, err := net.Listen("unix", localSocket)
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed to listen on %s: %v", localSocket, err)
|
||||
}
|
||||
if err := service.Serve(sftpSocketListener); err != nil {
|
||||
glog.Fatalf("Failed to serve SFTP on socket %s: %v", localSocket, err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// Start the SFTP service on TCP
|
||||
listenAddress := fmt.Sprintf("%s:%d", *sftpOpt.bindIp, *sftpOpt.port)
|
||||
sftpListener, sftpLocalListener, err := util.NewIpAndLocalListeners(*sftpOpt.bindIp, *sftpOpt.port, time.Duration(10)*time.Second)
|
||||
if err != nil {
|
||||
glog.Fatalf("SFTP server listener on %s error: %v", listenAddress, err)
|
||||
}
|
||||
|
||||
glog.V(0).Infof("Start Seaweed SFTP Server %s at %s", version.Version(), listenAddress)
|
||||
|
||||
if sftpLocalListener != nil {
|
||||
go func() {
|
||||
if err := service.Serve(sftpLocalListener); err != nil {
|
||||
glog.Fatalf("SFTP Server failed to serve on local listener: %v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
if err := service.Serve(sftpListener); err != nil {
|
||||
glog.Fatalf("SFTP Server failed to serve: %v", err)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
swv "github.com/seaweedfs/seaweedfs/weed/util/version"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -117,7 +118,7 @@ func runUpdate(cmd *Command, args []string) bool {
|
||||
}
|
||||
|
||||
func downloadRelease(ctx context.Context, target string, ver string) (version string, err error) {
|
||||
currentVersion := util.VERSION_NUMBER
|
||||
currentVersion := swv.VERSION_NUMBER
|
||||
rel, err := GitHubLatestRelease(ctx, ver, "seaweedfs", "seaweedfs")
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build elastic && gocdk && rclone && sqlite && tikv && ydb
|
||||
// +build elastic,gocdk,rclone,sqlite,tikv,ydb
|
||||
//go:build elastic && gocdk && rclone && sqlite && tarantool && tikv && ydb
|
||||
// +build elastic,gocdk,rclone,sqlite,tarantool,tikv,ydb
|
||||
|
||||
package command
|
||||
|
||||
|
||||
@@ -2,9 +2,8 @@ package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/util/version"
|
||||
"runtime"
|
||||
|
||||
"github.com/seaweedfs/seaweedfs/weed/util"
|
||||
)
|
||||
|
||||
var cmdVersion = &Command{
|
||||
@@ -19,6 +18,6 @@ func runVersion(cmd *Command, args []string) bool {
|
||||
cmd.Usage()
|
||||
}
|
||||
|
||||
fmt.Printf("version %s %s %s\n", util.Version(), runtime.GOOS, runtime.GOARCH)
|
||||
fmt.Printf("version %s %s %s\n", version.Version(), runtime.GOOS, runtime.GOARCH)
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/util/version"
|
||||
"net/http"
|
||||
httppprof "net/http/pprof"
|
||||
"os"
|
||||
@@ -351,7 +352,7 @@ func (v VolumeServerOptions) startGrpcService(vs volume_server_pb.VolumeServerSe
|
||||
|
||||
func (v VolumeServerOptions) startPublicHttpService(handler http.Handler) httpdown.Server {
|
||||
publicListeningAddress := util.JoinHostPort(*v.bindIp, *v.publicPort)
|
||||
glog.V(0).Infoln("Start Seaweed volume server", util.Version(), "public at", publicListeningAddress)
|
||||
glog.V(0).Infoln("Start Seaweed volume server", version.Version(), "public at", publicListeningAddress)
|
||||
publicListener, e := util.NewListener(publicListeningAddress, time.Duration(*v.idleConnectionTimeout)*time.Second)
|
||||
if e != nil {
|
||||
glog.Fatalf("Volume server listener error:%v", e)
|
||||
@@ -378,7 +379,7 @@ func (v VolumeServerOptions) startClusterHttpService(handler http.Handler) httpd
|
||||
}
|
||||
|
||||
listeningAddress := util.JoinHostPort(*v.bindIp, *v.port)
|
||||
glog.V(0).Infof("Start Seaweed volume server %s at %s", util.Version(), listeningAddress)
|
||||
glog.V(0).Infof("Start Seaweed volume server %s at %s", version.Version(), listeningAddress)
|
||||
listener, e := util.NewListener(listeningAddress, time.Duration(*v.idleConnectionTimeout)*time.Second)
|
||||
if e != nil {
|
||||
glog.Fatalf("Volume server listener error:%v", e)
|
||||
|
||||
@@ -3,6 +3,7 @@ package command
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/seaweedfs/seaweedfs/weed/util/version"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/user"
|
||||
@@ -23,6 +24,7 @@ var (
|
||||
|
||||
type WebDavOption struct {
|
||||
filer *string
|
||||
ipBind *string
|
||||
filerRootPath *string
|
||||
port *int
|
||||
collection *string
|
||||
@@ -38,6 +40,7 @@ type WebDavOption struct {
|
||||
func init() {
|
||||
cmdWebDav.Run = runWebDav // break init cycle
|
||||
webDavStandaloneOptions.filer = cmdWebDav.Flag.String("filer", "localhost:8888", "filer server address")
|
||||
webDavStandaloneOptions.ipBind = cmdWebDav.Flag.String("ip.bind", "", "ip address to bind to. Default listen to all.")
|
||||
webDavStandaloneOptions.port = cmdWebDav.Flag.Int("port", 7333, "webdav server http listen port")
|
||||
webDavStandaloneOptions.collection = cmdWebDav.Flag.String("collection", "", "collection to create the files")
|
||||
webDavStandaloneOptions.replication = cmdWebDav.Flag.String("replication", "", "replication to create the files")
|
||||
@@ -62,7 +65,8 @@ func runWebDav(cmd *Command, args []string) bool {
|
||||
|
||||
util.LoadSecurityConfiguration()
|
||||
|
||||
glog.V(0).Infof("Starting Seaweed WebDav Server %s at https port %d", util.Version(), *webDavStandaloneOptions.port)
|
||||
listenAddress := fmt.Sprintf("%s:%d", *webDavStandaloneOptions.ipBind, *webDavStandaloneOptions.port)
|
||||
glog.V(0).Infof("Starting Seaweed WebDav Server %s at %s", version.Version(), listenAddress)
|
||||
|
||||
return webDavStandaloneOptions.startWebDav()
|
||||
|
||||
@@ -126,19 +130,19 @@ func (wo *WebDavOption) startWebDav() bool {
|
||||
|
||||
httpS := &http.Server{Handler: ws.Handler}
|
||||
|
||||
listenAddress := fmt.Sprintf(":%d", *wo.port)
|
||||
listenAddress := fmt.Sprintf("%s:%d", *wo.ipBind, *wo.port)
|
||||
webDavListener, err := util.NewListener(listenAddress, time.Duration(10)*time.Second)
|
||||
if err != nil {
|
||||
glog.Fatalf("WebDav Server listener on %s error: %v", listenAddress, err)
|
||||
}
|
||||
|
||||
if *wo.tlsPrivateKey != "" {
|
||||
glog.V(0).Infof("Start Seaweed WebDav Server %s at https port %d", util.Version(), *wo.port)
|
||||
glog.V(0).Infof("Start Seaweed WebDav Server %s at https %s", version.Version(), listenAddress)
|
||||
if err = httpS.ServeTLS(webDavListener, *wo.tlsCertificate, *wo.tlsPrivateKey); err != nil {
|
||||
glog.Fatalf("WebDav Server Fail to serve: %v", err)
|
||||
}
|
||||
} else {
|
||||
glog.V(0).Infof("Start Seaweed WebDav Server %s at http port %d", util.Version(), *wo.port)
|
||||
glog.V(0).Infof("Start Seaweed WebDav Server %s at http %s", version.Version(), listenAddress)
|
||||
if err = httpS.Serve(webDavListener); err != nil {
|
||||
glog.Fatalf("WebDav Server Fail to serve: %v", err)
|
||||
}
|
||||
|
||||
@@ -1,14 +1 @@
|
||||
1. create a keyspace
|
||||
|
||||
CREATE KEYSPACE seaweedfs WITH replication = {'class':'SimpleStrategy', 'replication_factor' : 1};
|
||||
|
||||
2. create filemeta table
|
||||
|
||||
USE seaweedfs;
|
||||
|
||||
CREATE TABLE filemeta (
|
||||
directory varchar,
|
||||
name varchar,
|
||||
meta blob,
|
||||
PRIMARY KEY (directory, name)
|
||||
) WITH CLUSTERING ORDER BY (name ASC);
|
||||
Deprecated by cassandra2
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user