mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-03 05:02:03 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e98d7326b | ||
|
|
97c6e0efb1 | ||
|
|
9438738693 | ||
|
|
a69f0b62c2 | ||
|
|
9ae66f55fc | ||
|
|
4524ceae6b | ||
|
|
39b1e1b630 | ||
|
|
61af76c3bb | ||
|
|
89eb87c1d1 | ||
|
|
846c56e005 | ||
|
|
3551ca2fcf | ||
|
|
b597baf488 | ||
|
|
460d56d283 | ||
|
|
fd1dc1ab25 | ||
|
|
b4be56bb3b | ||
|
|
96800ffed5 | ||
|
|
7034fafb81 | ||
|
|
47eb9485b8 | ||
|
|
40ed4215f0 | ||
|
|
1384529eb7 | ||
|
|
94ea10e504 | ||
|
|
cae53cb238 | ||
|
|
4d881cdb61 | ||
|
|
9464f3b18c | ||
|
|
7a02fab289 | ||
|
|
6bc01e2f31 | ||
|
|
8ebdb0cb45 | ||
|
|
349550f41d | ||
|
|
89f633f3a9 | ||
|
|
9a21698caa | ||
|
|
4aa1fb7331 | ||
|
|
0af5c88a6e | ||
|
|
1b1c8e4af5 | ||
|
|
2c0e2e11df | ||
|
|
42fea7e7d6 | ||
|
|
db24ea8ad8 | ||
|
|
93f257c3c1 | ||
|
|
9b40f7f3af | ||
|
|
1f03fcccb1 | ||
|
|
dd13764a5c | ||
|
|
76b1c5ce67 | ||
|
|
72db181d68 | ||
|
|
44d810d163 | ||
|
|
180aa88a92 | ||
|
|
a4a0d56fc4 | ||
|
|
e58d48ed38 | ||
|
|
2232cfb5b7 | ||
|
|
2dfbe210e0 | ||
|
|
a87f57e47c | ||
|
|
931cb9e581 | ||
|
|
d2fe0fae33 | ||
|
|
c6ec5269f4 | ||
|
|
a9b4f0df04 | ||
|
|
261ba0208e | ||
|
|
71e837d6f1 | ||
|
|
50e93c3629 | ||
|
|
bc74b57a0b | ||
|
|
dffb59f350 | ||
|
|
295b1fcccc | ||
|
|
1cfae9f5c9 | ||
|
|
7a5128e9ee | ||
|
|
5593b0579c | ||
|
|
fa070474d5 | ||
|
|
9f4ecd50ac | ||
|
|
ceb058ddd9 | ||
|
|
7f26676f57 | ||
|
|
b1493520ee | ||
|
|
dff63e9024 | ||
|
|
4dba102137 | ||
|
|
bbc95dac47 | ||
|
|
aa7703c6dd | ||
|
|
f34205e110 | ||
|
|
104ea7b029 | ||
|
|
d6ee4bf65e | ||
|
|
a2fdb3e277 | ||
|
|
35bc67f030 | ||
|
|
f5246b748d | ||
|
|
11a9f993a8 | ||
|
|
7ff248d5cd | ||
|
|
85d80fd36d | ||
|
|
abe3cc6df2 | ||
|
|
869d23b099 | ||
|
|
86ed27f602 | ||
|
|
2347c21cdd | ||
|
|
2454020a92 | ||
|
|
4f87ee7755 | ||
|
|
c20e1edd99 | ||
|
|
3ab2c0e5c0 | ||
|
|
9d44b89c21 | ||
|
|
368d8e1a81 | ||
|
|
0a6703c7f7 | ||
|
|
14a2cc83bf | ||
|
|
fa25d5c43a | ||
|
|
ff2ec58897 | ||
|
|
83ee4c5fe2 | ||
|
|
72cbda3481 | ||
|
|
d30eafd0f3 | ||
|
|
9f9e0deafb | ||
|
|
357aa818fe | ||
|
|
3d229fe45c | ||
|
|
79b8e6a8c3 | ||
|
|
c1aeded2dd | ||
|
|
49ecb8d11c | ||
|
|
d02f13c2d1 | ||
|
|
7c85cb332d | ||
|
|
f15a737a0a | ||
|
|
bc888226fc | ||
|
|
8b3d76b24d | ||
|
|
bb4beebce3 | ||
|
|
ae5aa2bf04 | ||
|
|
10dc72ca54 | ||
|
|
0e796a5582 | ||
|
|
68f11b9687 | ||
|
|
1ae7f509f5 | ||
|
|
89d32a0670 | ||
|
|
7dd93a88ac | ||
|
|
17c6e8e39f | ||
|
|
b7cdde14ae | ||
|
|
3176bf126a | ||
|
|
9b0d02ed39 | ||
|
|
e752efc624 | ||
|
|
5b352ec1d2 | ||
|
|
6e4c94e2e1 | ||
|
|
4aae87f405 | ||
|
|
64db9db3de | ||
|
|
bb02803fca | ||
|
|
4062daf416 | ||
|
|
e28a8f802f | ||
|
|
19e5179159 | ||
|
|
e965c92c93 | ||
|
|
b58187df18 | ||
|
|
ca1bdb4661 | ||
|
|
566ec62aec | ||
|
|
622297f1a7 | ||
|
|
1a1e5778c3 | ||
|
|
14dd971890 | ||
|
|
c514710b7b | ||
|
|
d310711de0 | ||
|
|
9eda9a6e82 | ||
|
|
77a7d7253f | ||
|
|
e8d7bb42e2 | ||
|
|
6a2bcd03aa | ||
|
|
958f880b70 | ||
|
|
a8eefda452 | ||
|
|
105578a2f2 | ||
|
|
049f8f2e2a | ||
|
|
b7e34016d4 | ||
|
|
4ecba915f3 | ||
|
|
daca2d22a5 | ||
|
|
4b5c0e3fa9 | ||
|
|
6d55716fc3 | ||
|
|
bbbbbd70a4 | ||
|
|
743ad690b6 | ||
|
|
2305508b65 | ||
|
|
800cbc004c | ||
|
|
7fdd29c234 | ||
|
|
b0a7fd67cf | ||
|
|
dfe5bfbe2b | ||
|
|
aa7eb31bea | ||
|
|
2fc524ed30 | ||
|
|
02935ff145 | ||
|
|
67d870dfc2 | ||
|
|
4f5b018a02 | ||
|
|
7f4e33ec15 | ||
|
|
691ed50957 | ||
|
|
f08d67eeb7 | ||
|
|
a180394f75 | ||
|
|
b6a2b43efe | ||
|
|
c29f79a593 | ||
|
|
5738049d5a | ||
|
|
7a002c03fd | ||
|
|
123ab2f9c9 | ||
|
|
c0ac0dd5f2 | ||
|
|
a8b15c676c | ||
|
|
8be731a56d | ||
|
|
6f5f39dcbb | ||
|
|
531907acab | ||
|
|
fcf7f6c022 | ||
|
|
ce8ef60c59 | ||
|
|
6317f6a8a9 | ||
|
|
8732cc24c8 | ||
|
|
683581c412 | ||
|
|
7701a3008c | ||
|
|
6a286a5ea9 | ||
|
|
4db7754cd6 | ||
|
|
996231c01d | ||
|
|
50eaf59912 | ||
|
|
e0e8cbc501 | ||
|
|
47871f8389 | ||
|
|
5d59f2b191 | ||
|
|
1ff39c0cf9 | ||
|
|
a3c18ec82c | ||
|
|
993283bb1d | ||
|
|
5b90a39954 | ||
|
|
9231971c88 | ||
|
|
ed07e76f0e | ||
|
|
51bd015179 | ||
|
|
66583e7827 | ||
|
|
b208996153 | ||
|
|
80ddd4c7c8 | ||
|
|
9b118c6f76 | ||
|
|
fed9a96501 | ||
|
|
2fdf766fe5 | ||
|
|
f65c055c44 | ||
|
|
cfb5440b04 | ||
|
|
d525a57bf3 | ||
|
|
3af8ac8f1e | ||
|
|
84b7b83517 | ||
|
|
93615b2a49 | ||
|
|
dd2b9d93cc | ||
|
|
21636c98a5 | ||
|
|
02076f01a6 | ||
|
|
0edbc87857 | ||
|
|
d51a724101 | ||
|
|
0490ee87ef | ||
|
|
86d4c52d6e | ||
|
|
21e0898631 | ||
|
|
4ba7127ab1 | ||
|
|
3153c836a7 | ||
|
|
cae998eda1 | ||
|
|
34b743c481 | ||
|
|
fba1cfc2d6 | ||
|
|
a3411dd9da | ||
|
|
db027ed9c0 | ||
|
|
1b27f96669 | ||
|
|
aa24af77aa | ||
|
|
33c07e8fb0 | ||
|
|
4cc0440009 | ||
|
|
868ebbd9b0 | ||
|
|
763f354cdf | ||
|
|
423fbf3b08 | ||
|
|
44a0ebdf37 | ||
|
|
1d93ce4aa9 | ||
|
|
843790d8a0 | ||
|
|
30d985c4f7 | ||
|
|
ddd3945c26 | ||
|
|
c1450bf9fe | ||
|
|
89d84e275b | ||
|
|
b0a6f6ab39 | ||
|
|
3de184e37f | ||
|
|
04a3fd0460 | ||
|
|
b0d7e7c9a4 | ||
|
|
2fdfff667a | ||
|
|
44c840f498 | ||
|
|
0bf8ba0047 | ||
|
|
111149f956 | ||
|
|
b4fc1ff223 | ||
|
|
de06d63b80 | ||
|
|
ae40a9cb28 | ||
|
|
0b790d2bbf | ||
|
|
9b04f17555 | ||
|
|
0b5faef612 | ||
|
|
0562fceb99 | ||
|
|
8b983729ca | ||
|
|
23cc039c9b | ||
|
|
d4f20af739 | ||
|
|
46f2849890 | ||
|
|
f697dec43d | ||
|
|
db62759ca5 | ||
|
|
d540cec1dd | ||
|
|
94cfb86016 | ||
|
|
1d1ac14ac0 | ||
|
|
b807b64e58 | ||
|
|
3e47d282fc | ||
|
|
b8837cb5fa | ||
|
|
849a2c1f68 | ||
|
|
105bcfdbd4 | ||
|
|
e48764be75 | ||
|
|
18ae8943ef | ||
|
|
98c001f54a | ||
|
|
0448c05596 | ||
|
|
830e69c85d | ||
|
|
7fce84532b | ||
|
|
b29f16a626 | ||
|
|
560835e944 | ||
|
|
5230d6d9a9 | ||
|
|
a92296d263 | ||
|
|
cbddc10845 | ||
|
|
9a2bd95e20 | ||
|
|
e2cdba292b | ||
|
|
a0bad1c997 | ||
|
|
6c7f7d6887 | ||
|
|
afb93cd19f | ||
|
|
2e23162188 | ||
|
|
c8787d3e9a | ||
|
|
8cfcb9fe9f | ||
|
|
af4f345b0c | ||
|
|
8573798a8c | ||
|
|
5999099ed4 | ||
|
|
087def339f | ||
|
|
c3fe1654b9 | ||
|
|
468361aa78 | ||
|
|
22aca43b26 | ||
|
|
ac9f12c826 | ||
|
|
d1a6bd1cc6 | ||
|
|
a644b7236a | ||
|
|
0d692a6254 | ||
|
|
d12540c9f2 | ||
|
|
8373f9b2e7 | ||
|
|
349257f822 | ||
|
|
f8a089cbca | ||
|
|
4e2388e1b5 | ||
|
|
8f0410af2c | ||
|
|
24541fc7ec | ||
|
|
ae558fa073 | ||
|
|
57c6eddd22 | ||
|
|
80c14877d3 | ||
|
|
581c93d970 | ||
|
|
b75c6dcff5 | ||
|
|
3da2b83b38 | ||
|
|
4615560182 | ||
|
|
9f16df736e | ||
|
|
b1a819ebd8 | ||
|
|
b69ccc92b3 | ||
|
|
db578b0ea4 | ||
|
|
3a18e905d0 | ||
|
|
e13959996a | ||
|
|
ecf198b752 | ||
|
|
39fa4c75df | ||
|
|
c93976dda4 | ||
|
|
822a6fe3c8 | ||
|
|
c51f65df9e | ||
|
|
4bb17c6e36 | ||
|
|
48a2d3327d | ||
|
|
ce58bda4a0 | ||
|
|
c0475cc267 | ||
|
|
04c3be6829 | ||
|
|
d75d409800 | ||
|
|
3f514ef1a7 | ||
|
|
5b2814ec64 | ||
|
|
cf95091d40 | ||
|
|
dd737bd755 | ||
|
|
2824940ecf | ||
|
|
f247cab5cd | ||
|
|
01c48da6ce | ||
|
|
7ee38fa3a4 | ||
|
|
6886167d5f | ||
|
|
7542fd7f4d | ||
|
|
4042fdf3bb | ||
|
|
d2acde2a61 | ||
|
|
40b0033fa7 | ||
|
|
ee5417a5b3 | ||
|
|
81cce4b4c3 | ||
|
|
a6a8892255 | ||
|
|
a93c4947ba | ||
|
|
2aa9d9f84a | ||
|
|
9b14f0c81a | ||
|
|
b5b97a4799 | ||
|
|
ed818c90a9 | ||
|
|
3639cad69c | ||
|
|
fa6fe327bf | ||
|
|
f43c6daeda | ||
|
|
c2e7d663bc | ||
|
|
fbc9f0eb64 | ||
|
|
2eda3a686f | ||
|
|
bd5c5586b5 | ||
|
|
5cba8e51c5 | ||
|
|
f2f68f675e | ||
|
|
2f4cd20f90 | ||
|
|
53513475bf | ||
|
|
f70c1e449b | ||
|
|
b20ddc57a7 | ||
|
|
b40d252761 | ||
|
|
3a6eb8ca5f | ||
|
|
728bf50a73 | ||
|
|
f53cff045f | ||
|
|
834210a9dc | ||
|
|
197ade6aeb | ||
|
|
011a41b561 | ||
|
|
9b9ab6da86 | ||
|
|
2ea18fca48 | ||
|
|
fc0a583a4d | ||
|
|
f28dbbe5c5 | ||
|
|
e2b07737da | ||
|
|
dc204dd137 | ||
|
|
23d024708d | ||
|
|
f7f2a597dd | ||
|
|
d61bea9038 | ||
|
|
3aeee3d748 | ||
|
|
8136384473 | ||
|
|
d1b2231bc8 | ||
|
|
b9ff7723dd | ||
|
|
da3d330616 | ||
|
|
0cb17b45b1 | ||
|
|
6d3db4445b | ||
|
|
f3bcbeb60a | ||
|
|
db7766323e | ||
|
|
302738ee74 |
@@ -0,0 +1,10 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
- package-ecosystem: gomod
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
@@ -4,15 +4,20 @@ on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
|
||||
cleanup:
|
||||
permissions:
|
||||
contents: write # for mknejp/delete-release-assets to delete release assets
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
|
||||
- name: Delete old release assets
|
||||
uses: mknejp/delete-release-assets@v1
|
||||
uses: mknejp/delete-release-assets@a8aaab13272b1eaac16cc46dddd3f725b97ee05a # v1
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
tag: dev
|
||||
@@ -21,6 +26,8 @@ jobs:
|
||||
weed-*
|
||||
|
||||
build_dev_linux_windows:
|
||||
permissions:
|
||||
contents: write # for wangyoucao577/go-release-action to upload release assets
|
||||
needs: cleanup
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
@@ -31,13 +38,13 @@ jobs:
|
||||
steps:
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 # v2
|
||||
|
||||
- name: Set BUILD_TIME env
|
||||
run: echo BUILD_TIME=$(date -u +%Y%m%d-%H%M) >> ${GITHUB_ENV}
|
||||
|
||||
- name: Go Release Binaries Large Disk
|
||||
uses: wangyoucao577/go-release-action@v1.22
|
||||
uses: wangyoucao577/go-release-action@16624612d4e2b73de613857a362d294700207fff # v1.22
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
goos: ${{ matrix.goos }}
|
||||
@@ -53,7 +60,7 @@ jobs:
|
||||
asset_name: "weed-large-disk-${{ env.BUILD_TIME }}-${{ matrix.goos }}-${{ matrix.goarch }}"
|
||||
|
||||
- name: Go Release Binaries Normal Volume Size
|
||||
uses: wangyoucao577/go-release-action@v1.22
|
||||
uses: wangyoucao577/go-release-action@16624612d4e2b73de613857a362d294700207fff # v1.22
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
goos: ${{ matrix.goos }}
|
||||
@@ -68,6 +75,8 @@ jobs:
|
||||
asset_name: "weed-${{ env.BUILD_TIME }}-${{ matrix.goos }}-${{ matrix.goarch }}"
|
||||
|
||||
build_dev_darwin:
|
||||
permissions:
|
||||
contents: write # for wangyoucao577/go-release-action to upload release assets
|
||||
needs: build_dev_linux_windows
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
@@ -78,13 +87,13 @@ jobs:
|
||||
steps:
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 # v2
|
||||
|
||||
- name: Set BUILD_TIME env
|
||||
run: echo BUILD_TIME=$(date -u +%Y%m%d-%H%M) >> ${GITHUB_ENV}
|
||||
|
||||
- name: Go Release Binaries Large Disk
|
||||
uses: wangyoucao577/go-release-action@v1.22
|
||||
uses: wangyoucao577/go-release-action@16624612d4e2b73de613857a362d294700207fff # v1.22
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
goos: ${{ matrix.goos }}
|
||||
@@ -100,7 +109,7 @@ jobs:
|
||||
asset_name: "weed-large-disk-${{ env.BUILD_TIME }}-${{ matrix.goos }}-${{ matrix.goarch }}"
|
||||
|
||||
- name: Go Release Binaries Normal Volume Size
|
||||
uses: wangyoucao577/go-release-action@v1.22
|
||||
uses: wangyoucao577/go-release-action@16624612d4e2b73de613857a362d294700207fff # v1.22
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
goos: ${{ matrix.goos }}
|
||||
|
||||
@@ -11,9 +11,14 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
|
||||
build-release-binaries_windows:
|
||||
permissions:
|
||||
contents: write # for wangyoucao577/go-release-action to upload release assets
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
@@ -23,9 +28,9 @@ jobs:
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||
steps:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 # v2
|
||||
- name: Go Release Binaries Normal Volume Size
|
||||
uses: wangyoucao577/go-release-action@v1.22
|
||||
uses: wangyoucao577/go-release-action@16624612d4e2b73de613857a362d294700207fff # v1.22
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
goos: ${{ matrix.goos }}
|
||||
@@ -39,7 +44,7 @@ jobs:
|
||||
binary_name: weed
|
||||
asset_name: "${{ matrix.goos }}_${{ matrix.goarch }}"
|
||||
- name: Go Release Large Disk Binaries
|
||||
uses: wangyoucao577/go-release-action@v1.22
|
||||
uses: wangyoucao577/go-release-action@16624612d4e2b73de613857a362d294700207fff # v1.22
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
goos: ${{ matrix.goos }}
|
||||
|
||||
@@ -11,9 +11,14 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
|
||||
build-release-binaries_linux:
|
||||
permissions:
|
||||
contents: write # for wangyoucao577/go-release-action to upload release assets
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
@@ -23,9 +28,9 @@ jobs:
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||
steps:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 # v2
|
||||
- name: Go Release Binaries Normal Volume Size
|
||||
uses: wangyoucao577/go-release-action@v1.22
|
||||
uses: wangyoucao577/go-release-action@16624612d4e2b73de613857a362d294700207fff # v1.22
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
goos: ${{ matrix.goos }}
|
||||
@@ -39,7 +44,7 @@ jobs:
|
||||
binary_name: weed
|
||||
asset_name: "${{ matrix.goos }}_${{ matrix.goarch }}"
|
||||
- name: Go Release Large Disk Binaries
|
||||
uses: wangyoucao577/go-release-action@v1.22
|
||||
uses: wangyoucao577/go-release-action@16624612d4e2b73de613857a362d294700207fff # v1.22
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
goos: ${{ matrix.goos }}
|
||||
|
||||
@@ -11,9 +11,14 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
|
||||
build-release-binaries_darwin:
|
||||
permissions:
|
||||
contents: write # for wangyoucao577/go-release-action to upload release assets
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
@@ -23,9 +28,9 @@ jobs:
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||
steps:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 # v2
|
||||
- name: Go Release Binaries Normal Volume Size
|
||||
uses: wangyoucao577/go-release-action@v1.22
|
||||
uses: wangyoucao577/go-release-action@16624612d4e2b73de613857a362d294700207fff # v1.22
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
goos: ${{ matrix.goos }}
|
||||
@@ -39,7 +44,7 @@ jobs:
|
||||
binary_name: weed
|
||||
asset_name: "${{ matrix.goos }}_${{ matrix.goarch }}"
|
||||
- name: Go Release Large Disk Binaries
|
||||
uses: wangyoucao577/go-release-action@v1.22
|
||||
uses: wangyoucao577/go-release-action@16624612d4e2b73de613857a362d294700207fff # v1.22
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
goos: ${{ matrix.goos }}
|
||||
|
||||
@@ -11,9 +11,14 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
|
||||
build-release-binaries_freebsd:
|
||||
permissions:
|
||||
contents: write # for wangyoucao577/go-release-action to upload release assets
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
@@ -23,9 +28,9 @@ jobs:
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||
steps:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 # v2
|
||||
- name: Go Release Binaries Normal Volume Size
|
||||
uses: wangyoucao577/go-release-action@v1.22
|
||||
uses: wangyoucao577/go-release-action@16624612d4e2b73de613857a362d294700207fff # v1.22
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
goos: ${{ matrix.goos }}
|
||||
@@ -39,7 +44,7 @@ jobs:
|
||||
binary_name: weed
|
||||
asset_name: "${{ matrix.goos }}_${{ matrix.goarch }}"
|
||||
- name: Go Release Large Disk Binaries
|
||||
uses: wangyoucao577/go-release-action@v1.22
|
||||
uses: wangyoucao577/go-release-action@16624612d4e2b73de613857a362d294700207fff # v1.22
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
goos: ${{ matrix.goos }}
|
||||
|
||||
@@ -5,6 +5,9 @@ on:
|
||||
branches: [ master ]
|
||||
workflow_dispatch: []
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
|
||||
build-dev-containers:
|
||||
@@ -13,11 +16,11 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 # v2
|
||||
-
|
||||
name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@v3
|
||||
uses: docker/metadata-action@f2a13332ac1ce8c0a71aeac48a150dbb1838ab67 # v3
|
||||
with:
|
||||
images: |
|
||||
chrislusf/seaweedfs
|
||||
@@ -30,30 +33,30 @@ jobs:
|
||||
org.opencontainers.image.vendor=Chris Lu
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
uses: docker/setup-qemu-action@27d0a4f181a40b142cce983c5393082c365d1480 # v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
uses: docker/setup-buildx-action@94ab11c41e45d028884a99163086648e898eed25 # v1
|
||||
with:
|
||||
buildkitd-flags: "--debug"
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@dd4fa0671be5250ee6f50aedf4cb05514abda2c7 # v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Login to GHCR
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@dd4fa0671be5250ee6f50aedf4cb05514abda2c7 # v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.GHCR_USERNAME }}
|
||||
password: ${{ secrets.GHCR_TOKEN }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@v2
|
||||
uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a # v2
|
||||
with:
|
||||
context: ./docker
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
@@ -6,6 +6,9 @@ on:
|
||||
- '*'
|
||||
workflow_dispatch: []
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
|
||||
build-latest-container:
|
||||
@@ -14,11 +17,11 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 # v2
|
||||
-
|
||||
name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@v3
|
||||
uses: docker/metadata-action@f2a13332ac1ce8c0a71aeac48a150dbb1838ab67 # v3
|
||||
with:
|
||||
images: |
|
||||
chrislusf/seaweedfs
|
||||
@@ -31,30 +34,30 @@ jobs:
|
||||
org.opencontainers.image.vendor=Chris Lu
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
uses: docker/setup-qemu-action@27d0a4f181a40b142cce983c5393082c365d1480 # v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
uses: docker/setup-buildx-action@94ab11c41e45d028884a99163086648e898eed25 # v1
|
||||
with:
|
||||
buildkitd-flags: "--debug"
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@dd4fa0671be5250ee6f50aedf4cb05514abda2c7 # v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Login to GHCR
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@dd4fa0671be5250ee6f50aedf4cb05514abda2c7 # v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.GHCR_USERNAME }}
|
||||
password: ${{ secrets.GHCR_TOKEN }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@v2
|
||||
uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a # v2
|
||||
with:
|
||||
context: ./docker
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
@@ -6,6 +6,9 @@ on:
|
||||
- '*'
|
||||
workflow_dispatch: []
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build-default-release-container:
|
||||
runs-on: [ubuntu-latest]
|
||||
@@ -13,11 +16,11 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 # v2
|
||||
-
|
||||
name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@v3
|
||||
uses: docker/metadata-action@f2a13332ac1ce8c0a71aeac48a150dbb1838ab67 # v3
|
||||
with:
|
||||
images: |
|
||||
chrislusf/seaweedfs
|
||||
@@ -31,20 +34,20 @@ jobs:
|
||||
org.opencontainers.image.vendor=Chris Lu
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
uses: docker/setup-qemu-action@27d0a4f181a40b142cce983c5393082c365d1480 # v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
uses: docker/setup-buildx-action@94ab11c41e45d028884a99163086648e898eed25 # v1
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@dd4fa0671be5250ee6f50aedf4cb05514abda2c7 # v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@v2
|
||||
uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a # v2
|
||||
with:
|
||||
context: ./docker
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
@@ -6,6 +6,9 @@ on:
|
||||
- '*'
|
||||
workflow_dispatch: []
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
|
||||
build-large-release-container:
|
||||
@@ -14,11 +17,11 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 # v2
|
||||
-
|
||||
name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@v3
|
||||
uses: docker/metadata-action@f2a13332ac1ce8c0a71aeac48a150dbb1838ab67 # v3
|
||||
with:
|
||||
images: |
|
||||
chrislusf/seaweedfs
|
||||
@@ -32,20 +35,20 @@ jobs:
|
||||
org.opencontainers.image.vendor=Chris Lu
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
uses: docker/setup-qemu-action@27d0a4f181a40b142cce983c5393082c365d1480 # v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
uses: docker/setup-buildx-action@94ab11c41e45d028884a99163086648e898eed25 # v1
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@dd4fa0671be5250ee6f50aedf4cb05514abda2c7 # v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@v2
|
||||
uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a # v2
|
||||
with:
|
||||
context: ./docker
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
@@ -6,6 +6,9 @@ on:
|
||||
- '*'
|
||||
workflow_dispatch: []
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
|
||||
build-large-release-container_rocksdb:
|
||||
@@ -14,11 +17,11 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 # v2
|
||||
-
|
||||
name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@v3
|
||||
uses: docker/metadata-action@f2a13332ac1ce8c0a71aeac48a150dbb1838ab67 # v3
|
||||
with:
|
||||
images: |
|
||||
chrislusf/seaweedfs
|
||||
@@ -32,20 +35,20 @@ jobs:
|
||||
org.opencontainers.image.vendor=Chris Lu
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
uses: docker/setup-qemu-action@27d0a4f181a40b142cce983c5393082c365d1480 # v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
uses: docker/setup-buildx-action@94ab11c41e45d028884a99163086648e898eed25 # v1
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@dd4fa0671be5250ee6f50aedf4cb05514abda2c7 # v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@v2
|
||||
uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a # v2
|
||||
with:
|
||||
context: ./docker
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
@@ -10,6 +10,9 @@ concurrency:
|
||||
group: ${{ github.head_ref }}/go
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
@@ -18,13 +21,13 @@ jobs:
|
||||
steps:
|
||||
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v2
|
||||
uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab # v2
|
||||
with:
|
||||
go-version: ^1.13
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 # v2
|
||||
|
||||
- name: Get dependencies
|
||||
run: |
|
||||
|
||||
@@ -33,7 +33,7 @@ Your support will be really appreciated by me and other supporters!
|
||||
|
||||
|
||||
### Gold Sponsors
|
||||

|
||||
- [](https://www.nodion.com)
|
||||
|
||||
---
|
||||
|
||||
@@ -54,6 +54,7 @@ Table of Contents
|
||||
* [Quick Start](#quick-start)
|
||||
* [Quick Start for S3 API on Docker](#quick-start-for-s3-api-on-docker)
|
||||
* [Quick Start with Single Binary](#quick-start-with-single-binary)
|
||||
* [Quick Start SeaweedFS S3 on AWS](#quick-start-seaweedfs-s3-on-aws)
|
||||
* [Introduction](#introduction)
|
||||
* [Features](#features)
|
||||
* [Additional Features](#additional-features)
|
||||
@@ -82,6 +83,9 @@ Table of Contents
|
||||
|
||||
Also, to increase capacity, just add more volume servers by running `weed volume -dir="/some/data/dir2" -mserver="<master_host>:9333" -port=8081` locally, or on a different machine, or on thousands of machines. That is it!
|
||||
|
||||
## Quick Start SeaweedFS S3 on AWS ##
|
||||
* Setup fast production-ready [SeaweedFS S3 on AWS with cloudformation](https://aws.amazon.com/marketplace/pp/prodview-nzelz5gprlrjc)
|
||||
|
||||
## Introduction ##
|
||||
|
||||
SeaweedFS is a simple and highly scalable distributed file system. There are two objectives:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.17-alpine as builder
|
||||
FROM golang:1.18-alpine as builder
|
||||
RUN apk add git g++ fuse
|
||||
RUN mkdir -p /go/src/github.com/chrislusf/
|
||||
RUN git clone https://github.com/chrislusf/seaweedfs /go/src/github.com/chrislusf/seaweedfs
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.17-alpine as builder
|
||||
FROM golang:1.18-alpine as builder
|
||||
RUN apk add git g++ fuse
|
||||
RUN mkdir -p /go/src/github.com/chrislusf/
|
||||
RUN git clone https://github.com/chrislusf/seaweedfs /go/src/github.com/chrislusf/seaweedfs
|
||||
|
||||
@@ -3,7 +3,7 @@ FROM golang:1.17-buster 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 v6.22.1
|
||||
ENV ROCKSDB_VERSION v7.0.4
|
||||
|
||||
# build RocksDB
|
||||
RUN cd /tmp && \
|
||||
|
||||
@@ -55,6 +55,9 @@ cluster: build
|
||||
2clusters: build
|
||||
docker-compose -f compose/local-clusters-compose.yml -p seaweedfs up
|
||||
|
||||
hashicorp_raft: build
|
||||
docker-compose -f compose/local-hashicorp-raft-compose.yml -p seaweedfs up
|
||||
|
||||
s3tests: build s3tests_build
|
||||
docker-compose -f compose/local-s3tests-compose.yml -p seaweedfs up
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ services:
|
||||
ports:
|
||||
- 8080:8080
|
||||
- 18080:18080
|
||||
command: 'volume -dataCenter dc1 -rack v1 -mserver="master0:9333,master1:9334,master2:9335" -port=8080 -ip=volume1 -publicUrl=localhost:8080 -preStopSeconds=1'
|
||||
command: 'volume -dataCenter=dc1 -rack=v1 -mserver="master0:9333,master1:9334,master2:9335" -port=8080 -ip=volume1 -publicUrl=localhost:8080 -preStopSeconds=1'
|
||||
depends_on:
|
||||
- master0
|
||||
- master1
|
||||
@@ -46,7 +46,7 @@ services:
|
||||
ports:
|
||||
- 8082:8082
|
||||
- 18082:18082
|
||||
command: 'volume -dataCenter dc2 -rack v2 -mserver="master0:9333,master1:9334,master2:9335" -port=8082 -ip=volume2 -publicUrl=localhost:8082 -preStopSeconds=1'
|
||||
command: 'volume -dataCenter=dc2 -rack=v2 -mserver="master0:9333,master1:9334,master2:9335" -port=8082 -ip=volume2 -publicUrl=localhost:8082 -preStopSeconds=1'
|
||||
depends_on:
|
||||
- master0
|
||||
- master1
|
||||
@@ -56,7 +56,7 @@ services:
|
||||
ports:
|
||||
- 8083:8083
|
||||
- 18083:18083
|
||||
command: 'volume -dataCenter dc3 -rack v3 -mserver="master0:9333,master1:9334,master2:9335" -port=8083 -ip=volume3 -publicUrl=localhost:8083 -preStopSeconds=1'
|
||||
command: 'volume -dataCenter=dc3 -rack=v3 -mserver="master0:9333,master1:9334,master2:9335" -port=8083 -ip=volume3 -publicUrl=localhost:8083 -preStopSeconds=1'
|
||||
depends_on:
|
||||
- master0
|
||||
- master1
|
||||
@@ -67,7 +67,7 @@ services:
|
||||
- 8888:8888
|
||||
- 18888:18888
|
||||
- 8111:8111
|
||||
command: 'filer -defaultReplicaPlacement 100 -iam -master="master0:9333,master1:9334,master2:9335"'
|
||||
command: 'filer -defaultReplicaPlacement=100 -iam -master="master0:9333,master1:9334,master2:9335"'
|
||||
depends_on:
|
||||
- master0
|
||||
- master1
|
||||
@@ -85,4 +85,4 @@ services:
|
||||
- master2
|
||||
- volume1
|
||||
- volume2
|
||||
- filer
|
||||
- filer
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
master0:
|
||||
image: chrislusf/seaweedfs:local
|
||||
ports:
|
||||
- 9333:9333
|
||||
- 19333:19333
|
||||
command: "-v=4 master -volumeSizeLimitMB 100 -raftHashicorp -ip=master0 -port=9333 -peers=master1:9334,master2:9335 -mdir=/data"
|
||||
volumes:
|
||||
- ./master/0:/data
|
||||
environment:
|
||||
WEED_MASTER_VOLUME_GROWTH_COPY_1: 1
|
||||
WEED_MASTER_VOLUME_GROWTH_COPY_2: 2
|
||||
WEED_MASTER_VOLUME_GROWTH_COPY_OTHER: 1
|
||||
master1:
|
||||
image: chrislusf/seaweedfs:local
|
||||
ports:
|
||||
- 9334:9334
|
||||
- 19334:19334
|
||||
command: "-v=4 master -volumeSizeLimitMB 100 -raftHashicorp -ip=master1 -port=9334 -peers=master0:9333,master2:9335 -mdir=/data"
|
||||
volumes:
|
||||
- ./master/1:/data
|
||||
environment:
|
||||
WEED_MASTER_VOLUME_GROWTH_COPY_1: 1
|
||||
WEED_MASTER_VOLUME_GROWTH_COPY_2: 2
|
||||
WEED_MASTER_VOLUME_GROWTH_COPY_OTHER: 1
|
||||
master2:
|
||||
image: chrislusf/seaweedfs:local
|
||||
ports:
|
||||
- 9335:9335
|
||||
- 19335:19335
|
||||
command: "-v=4 master -volumeSizeLimitMB 100 -raftHashicorp -ip=master2 -port=9335 -peers=master0:9333,master1:9334 -mdir=/data"
|
||||
volumes:
|
||||
- ./master/2:/data
|
||||
environment:
|
||||
WEED_MASTER_VOLUME_GROWTH_COPY_1: 1
|
||||
WEED_MASTER_VOLUME_GROWTH_COPY_2: 2
|
||||
WEED_MASTER_VOLUME_GROWTH_COPY_OTHER: 1
|
||||
volume1:
|
||||
image: chrislusf/seaweedfs:local
|
||||
ports:
|
||||
- 8080:8080
|
||||
- 18080:18080
|
||||
command: 'volume -dataCenter=dc1 -rack=v1 -mserver="master0:9333,master1:9334,master2:9335" -port=8080 -ip=volume1 -publicUrl=localhost:8080 -preStopSeconds=1'
|
||||
depends_on:
|
||||
- master0
|
||||
- master1
|
||||
volume2:
|
||||
image: chrislusf/seaweedfs:local
|
||||
ports:
|
||||
- 8082:8082
|
||||
- 18082:18082
|
||||
command: 'volume -dataCenter=dc2 -rack=v2 -mserver="master0:9333,master1:9334,master2:9335" -port=8082 -ip=volume2 -publicUrl=localhost:8082 -preStopSeconds=1'
|
||||
depends_on:
|
||||
- master0
|
||||
- master1
|
||||
volume3:
|
||||
image: chrislusf/seaweedfs:local
|
||||
ports:
|
||||
- 8083:8083
|
||||
- 18083:18083
|
||||
command: 'volume -dataCenter=dc3 -rack=v3 -mserver="master0:9333,master1:9334,master2:9335" -port=8083 -ip=volume3 -publicUrl=localhost:8083 -preStopSeconds=1'
|
||||
depends_on:
|
||||
- master0
|
||||
- master1
|
||||
filer:
|
||||
image: chrislusf/seaweedfs:local
|
||||
ports:
|
||||
- 8888:8888
|
||||
- 18888:18888
|
||||
- 8111:8111
|
||||
command: 'filer -defaultReplicaPlacement=100 -iam -master="master0:9333,master1:9334,master2:9335"'
|
||||
depends_on:
|
||||
- master0
|
||||
- master1
|
||||
- volume1
|
||||
- volume2
|
||||
s3:
|
||||
image: chrislusf/seaweedfs:local
|
||||
ports:
|
||||
- 8333:8333
|
||||
command: '-v=9 s3 -ip.bind="s3" -filer="filer:8888"'
|
||||
depends_on:
|
||||
- master0
|
||||
- master1
|
||||
- volume1
|
||||
- volume2
|
||||
- filer
|
||||
@@ -24,7 +24,7 @@ services:
|
||||
- 8888:8888
|
||||
- 18888:18888
|
||||
- 8000:8000
|
||||
command: 'filer -master="master:9333" -s3 -s3.config=/etc/seaweedfs/s3.json -s3.port=8000'
|
||||
command: 'filer -master="master:9333" -s3 -s3.config=/etc/seaweedfs/s3.json -s3.port=8000 -s3.allowEmptyFolder=false -s3.allowDeleteBucketNotEmpty=false'
|
||||
volumes:
|
||||
- ./s3.json:/etc/seaweedfs/s3.json
|
||||
depends_on:
|
||||
@@ -38,7 +38,7 @@ services:
|
||||
S3TEST_CONF: "s3tests.conf"
|
||||
NOSETESTS_OPTIONS: "--verbose --logging-level=ERROR --with-xunit --failure-detail s3tests_boto3.functional.test_s3"
|
||||
NOSETESTS_ATTR: "!tagging,!fails_on_aws,!encryption,!bucket-policy,!versioning,!fails_on_rgw,!bucket-policy,!fails_with_subdomain,!policy_status,!object-lock,!lifecycle,!cors,!user-policy"
|
||||
NOSETESTS_EXCLUDE: "(get_bucket_encryption|put_bucket_encryption|bucket_list_delimiter_basic|bucket_listv2_delimiter_basic|bucket_listv2_encoding_basic|bucket_list_encoding_basic|bucket_list_delimiter_prefix|bucket_listv2_delimiter_prefix_ends_with_delimiter|bucket_list_delimiter_prefix_ends_with_delimiter|bucket_list_delimiter_alt|bucket_listv2_delimiter_alt|bucket_list_delimiter_prefix_underscore|bucket_list_delimiter_percentage|bucket_listv2_delimiter_percentage|bucket_list_delimiter_whitespace|bucket_listv2_delimiter_whitespace|bucket_list_delimiter_dot|bucket_listv2_delimiter_dot|bucket_list_delimiter_unreadable|bucket_listv2_delimiter_unreadable|bucket_listv2_fetchowner_defaultempty|bucket_listv2_fetchowner_empty|bucket_list_prefix_delimiter_alt|bucket_listv2_prefix_delimiter_alt|bucket_list_prefix_delimiter_prefix_not_exist|bucket_listv2_prefix_delimiter_prefix_not_exist|bucket_list_prefix_delimiter_delimiter_not_exist|bucket_listv2_prefix_delimiter_delimiter_not_exist|bucket_list_prefix_delimiter_prefix_delimiter_not_exist|bucket_listv2_prefix_delimiter_prefix_delimiter_not_exist|bucket_list_maxkeys_none|bucket_listv2_maxkeys_none|bucket_list_maxkeys_invalid|bucket_listv2_continuationtoken_empty|bucket_list_return_data|bucket_list_objects_anonymous|bucket_listv2_objects_anonymous|bucket_notexist|bucketv2_notexist|bucket_delete_nonempty|bucket_concurrent_set_canned_acl|object_write_to_nonexist_bucket|object_requestid_matches_header_on_error|object_set_get_metadata_none_to_good|object_set_get_metadata_none_to_empty|object_set_get_metadata_overwrite_to_empty|post_object_anonymous_request|post_object_authenticated_request|post_object_authenticated_no_content_type|post_object_authenticated_request_bad_access_key|post_object_set_success_code|post_object_set_invalid_success_code|post_object_upload_larger_than_chunk|post_object_set_key_from_filename|post_object_ignored_header|post_object_case_insensitive_condition_fields|post_object_escaped_field_values|post_object_success_redirect_action|post_object_invalid_signature|post_object_invalid_access_key|post_object_missing_policy_condition|post_object_user_specified_header|post_object_request_missing_policy_specified_field|post_object_expired_policy|post_object_invalid_request_field_value|get_object_ifunmodifiedsince_good|put_object_ifmatch_failed|object_raw_get_bucket_gone|object_delete_key_bucket_gone|object_raw_get_bucket_acl|object_raw_get_object_acl|object_raw_response_headers|object_raw_authenticated_bucket_gone|object_raw_get_x_amz_expires_out_max_range|object_raw_get_x_amz_expires_out_positive_range|object_anon_put_write_access|object_raw_put_authenticated_expired|bucket_create_exists|bucket_create_naming_bad_short_one|bucket_create_naming_bad_short_two|bucket_get_location|bucket_acl_default|bucket_acl_canned|bucket_acl_canned_publicreadwrite|bucket_acl_canned_authenticatedread|object_acl_default|object_acl_canned_during_create|object_acl_canned|object_acl_canned_publicreadwrite|object_acl_canned_authenticatedread|object_acl_canned_bucketownerread|object_acl_canned_bucketownerfullcontrol|object_acl_full_control_verify_attributes|bucket_acl_canned_private_to_private|bucket_acl_grant_nonexist_user|bucket_acl_no_grants|bucket_acl_grant_email_not_exist|bucket_acl_revoke_all|bucket_recreate_not_overriding|object_copy_verify_contenttype|object_copy_to_itself_with_metadata|object_copy_not_owned_bucket|object_copy_not_owned_object_bucket|object_copy_retaining_metadata|object_copy_replacing_metadata|multipart_upload_empty|multipart_copy_invalid_range|multipart_copy_special_names|multipart_upload_resend_part|multipart_upload_size_too_small|abort_multipart_upload_not_found|multipart_upload_missing_part|multipart_upload_incorrect_etag|100_continue|ranged_request_invalid_range|ranged_request_empty_object|access_bucket)"
|
||||
NOSETESTS_EXCLUDE: "(get_bucket_encryption|put_bucket_encryption|bucket_list_delimiter_basic|bucket_listv2_delimiter_basic|bucket_listv2_encoding_basic|bucket_list_encoding_basic|bucket_list_delimiter_prefix|bucket_listv2_delimiter_prefix_ends_with_delimiter|bucket_list_delimiter_prefix_ends_with_delimiter|bucket_list_delimiter_alt|bucket_listv2_delimiter_alt|bucket_list_delimiter_prefix_underscore|bucket_list_delimiter_percentage|bucket_listv2_delimiter_percentage|bucket_list_delimiter_whitespace|bucket_listv2_delimiter_whitespace|bucket_list_delimiter_dot|bucket_listv2_delimiter_dot|bucket_list_delimiter_unreadable|bucket_listv2_delimiter_unreadable|bucket_listv2_fetchowner_defaultempty|bucket_listv2_fetchowner_empty|bucket_list_prefix_delimiter_alt|bucket_listv2_prefix_delimiter_alt|bucket_list_prefix_delimiter_prefix_not_exist|bucket_listv2_prefix_delimiter_prefix_not_exist|bucket_list_prefix_delimiter_delimiter_not_exist|bucket_listv2_prefix_delimiter_delimiter_not_exist|bucket_list_prefix_delimiter_prefix_delimiter_not_exist|bucket_listv2_prefix_delimiter_prefix_delimiter_not_exist|bucket_list_maxkeys_none|bucket_listv2_maxkeys_none|bucket_list_maxkeys_invalid|bucket_listv2_continuationtoken_empty|bucket_list_return_data|bucket_list_objects_anonymous|bucket_listv2_objects_anonymous|bucket_concurrent_set_canned_acl|object_write_to_nonexist_bucket|object_requestid_matches_header_on_error|object_set_get_metadata_none_to_good|object_set_get_metadata_none_to_empty|object_set_get_metadata_overwrite_to_empty|post_object_anonymous_request|post_object_authenticated_request|post_object_authenticated_no_content_type|post_object_authenticated_request_bad_access_key|post_object_set_success_code|post_object_set_invalid_success_code|post_object_upload_larger_than_chunk|post_object_set_key_from_filename|post_object_ignored_header|post_object_case_insensitive_condition_fields|post_object_escaped_field_values|post_object_success_redirect_action|post_object_invalid_signature|post_object_invalid_access_key|post_object_missing_policy_condition|post_object_user_specified_header|post_object_request_missing_policy_specified_field|post_object_expired_policy|post_object_invalid_request_field_value|get_object_ifunmodifiedsince_good|put_object_ifmatch_failed|object_raw_get_bucket_gone|object_delete_key_bucket_gone|object_raw_get_bucket_acl|object_raw_get_object_acl|object_raw_response_headers|object_raw_authenticated_bucket_gone|object_raw_get_x_amz_expires_out_max_range|object_raw_get_x_amz_expires_out_positive_range|object_anon_put_write_access|object_raw_put_authenticated_expired|bucket_create_exists|bucket_create_naming_bad_short_one|bucket_create_naming_bad_short_two|bucket_get_location|bucket_acl_default|bucket_acl_canned|bucket_acl_canned_publicreadwrite|bucket_acl_canned_authenticatedread|object_acl_default|object_acl_canned_during_create|object_acl_canned|object_acl_canned_publicreadwrite|object_acl_canned_authenticatedread|object_acl_canned_bucketownerread|object_acl_canned_bucketownerfullcontrol|object_acl_full_control_verify_attributes|bucket_acl_canned_private_to_private|bucket_acl_grant_nonexist_user|bucket_acl_no_grants|bucket_acl_grant_email_not_exist|bucket_acl_revoke_all|bucket_recreate_not_overriding|object_copy_verify_contenttype|object_copy_to_itself_with_metadata|object_copy_not_owned_bucket|object_copy_not_owned_object_bucket|object_copy_retaining_metadata|object_copy_replacing_metadata|multipart_upload_empty|multipart_copy_invalid_range|multipart_copy_special_names|multipart_upload_resend_part|multipart_upload_size_too_small|abort_multipart_upload_not_found|multipart_upload_missing_part|100_continue|ranged_request_invalid_range|ranged_request_empty_object|access_bucket|list_multipart_upload_owner|multipart_upload_small)"
|
||||
depends_on:
|
||||
- master
|
||||
- volume
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
module github.com/chrislusf/seaweedfs
|
||||
|
||||
go 1.17
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.94.1 // indirect
|
||||
cloud.google.com/go/pubsub v1.3.1
|
||||
cloud.google.com/go/storage v1.16.1
|
||||
cloud.google.com/go v0.100.2 // indirect
|
||||
cloud.google.com/go/pubsub v1.20.0
|
||||
cloud.google.com/go/storage v1.22.0
|
||||
github.com/Azure/azure-pipeline-go v0.2.3
|
||||
github.com/Azure/azure-storage-blob-go v0.14.0
|
||||
github.com/OneOfOne/xxhash v1.2.2
|
||||
github.com/Shopify/sarama v1.23.1
|
||||
github.com/aws/aws-sdk-go v1.35.3
|
||||
github.com/OneOfOne/xxhash v1.2.8
|
||||
github.com/Shopify/sarama v1.32.0
|
||||
github.com/aws/aws-sdk-go v1.43.40
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/buraksezer/consistent v0.0.0-20191006190839-693edf70fd72
|
||||
github.com/bwmarrin/snowflake v0.3.0
|
||||
github.com/cespare/xxhash v1.1.0
|
||||
github.com/cespare/xxhash/v2 v2.1.1 // indirect
|
||||
github.com/chrislusf/raft v1.0.7
|
||||
github.com/colinmarc/hdfs/v2 v2.2.0
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/chrislusf/raft v1.0.8
|
||||
github.com/colinmarc/hdfs/v2 v2.3.0
|
||||
github.com/coreos/go-semver v0.3.0 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
@@ -32,85 +32,77 @@ 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.8.0
|
||||
github.com/frankban/quicktest v1.7.2 // indirect
|
||||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||
github.com/fclairamb/ftpserverlib v0.17.0
|
||||
github.com/fsnotify/fsnotify v1.5.1 // indirect
|
||||
github.com/go-errors/errors v1.1.1 // indirect
|
||||
github.com/go-redis/redis/v8 v8.4.4
|
||||
github.com/go-redsync/redsync/v4 v4.4.1
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/go-redis/redis/v8 v8.11.5
|
||||
github.com/go-redsync/redsync/v4 v4.5.0
|
||||
github.com/go-sql-driver/mysql v1.6.0
|
||||
github.com/go-stack/stack v1.8.0 // indirect
|
||||
github.com/go-zookeeper/zk v1.0.2 // indirect
|
||||
github.com/gocql/gocql v0.0.0-20210707082121-9a3953d1826d
|
||||
github.com/golang-jwt/jwt v3.2.1+incompatible
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/btree v1.0.0
|
||||
github.com/google/go-cmp v0.5.6 // indirect
|
||||
github.com/google/btree v1.0.1
|
||||
github.com/google/go-cmp v0.5.7 // indirect
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/google/wire v0.4.0 // indirect
|
||||
github.com/googleapis/gax-go v2.0.2+incompatible // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.1.0 // indirect
|
||||
github.com/gorilla/mux v1.7.4
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.1.0
|
||||
github.com/google/wire v0.5.0 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.3.0 // indirect
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
|
||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.0 // indirect
|
||||
github.com/hashicorp/go-uuid v1.0.2 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/jcmturner/gofork v1.0.0 // indirect
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.1
|
||||
github.com/jinzhu/copier v0.2.8
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.2
|
||||
github.com/jinzhu/copier v0.3.5
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/json-iterator/go v1.1.11
|
||||
github.com/karlseguin/ccache/v2 v2.0.7
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/karlseguin/ccache/v2 v2.0.8
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/klauspost/compress v1.13.6 // indirect
|
||||
github.com/klauspost/cpuid v1.2.1 // indirect
|
||||
github.com/klauspost/reedsolomon v1.9.2
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect
|
||||
github.com/klauspost/compress v1.15.1 // indirect
|
||||
github.com/klauspost/reedsolomon v1.9.16
|
||||
github.com/kurin/blazer v0.5.3
|
||||
github.com/lib/pq v1.10.0
|
||||
github.com/linxGnu/grocksdb v1.6.38
|
||||
github.com/magiconair/properties v1.8.1 // indirect
|
||||
github.com/mailru/easyjson v0.7.1 // indirect
|
||||
github.com/mattn/go-ieproxy v0.0.1 // indirect
|
||||
github.com/mattn/go-isatty v0.0.12 // indirect
|
||||
github.com/lib/pq v1.10.5
|
||||
github.com/linxGnu/grocksdb v1.7.0
|
||||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-ieproxy v0.0.3 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.1.2 // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.3 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/nats-io/jwt v1.0.1 // indirect
|
||||
github.com/nats-io/nats.go v1.10.0 // indirect
|
||||
github.com/nats-io/nkeys v0.2.0 // indirect
|
||||
github.com/nats-io/nuid v1.0.1 // indirect
|
||||
github.com/olivere/elastic/v7 v7.0.19
|
||||
github.com/pelletier/go-toml v1.7.0 // indirect
|
||||
github.com/peterh/liner v1.1.0
|
||||
github.com/pierrec/lz4 v2.2.7+incompatible // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/olivere/elastic/v7 v7.0.32
|
||||
github.com/pelletier/go-toml v1.9.4 // indirect
|
||||
github.com/peterh/liner v1.2.2
|
||||
github.com/pierrec/lz4 v2.6.1+incompatible // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/posener/complete v1.2.3
|
||||
github.com/pquerna/cachecontrol v0.1.0
|
||||
github.com/prometheus/client_golang v1.11.0
|
||||
github.com/prometheus/client_golang v1.12.1
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.26.0 // indirect
|
||||
github.com/prometheus/procfs v0.6.0 // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563 // indirect
|
||||
github.com/prometheus/common v0.32.1 // indirect
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
||||
github.com/seaweedfs/goexif v1.0.2
|
||||
github.com/sirupsen/logrus v1.6.0 // indirect
|
||||
github.com/seaweedfs/goexif v2.0.0+incompatible
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/spf13/afero v1.6.0 // indirect
|
||||
github.com/spf13/cast v1.3.0 // indirect
|
||||
github.com/spf13/afero v1.8.2 // indirect
|
||||
github.com/spf13/cast v1.4.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/viper v1.4.0
|
||||
github.com/streadway/amqp v0.0.0-20200108173154-1c71cc93ed71
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/spf13/viper v1.11.0
|
||||
github.com/streadway/amqp v1.0.0
|
||||
github.com/stretchr/testify v1.7.1
|
||||
github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965
|
||||
github.com/tidwall/gjson v1.10.2
|
||||
github.com/tidwall/gjson v1.14.0
|
||||
github.com/tidwall/match v1.1.1
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
github.com/tsuna/gohbase v0.0.0-20201125011725-348991136365
|
||||
@@ -120,75 +112,106 @@ require (
|
||||
github.com/viant/ptrie v0.3.0
|
||||
github.com/viant/toolbox v0.33.2 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.0.2 // indirect
|
||||
github.com/xdg-go/scram v1.1.0 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.2 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.0
|
||||
go.mongodb.org/mongo-driver v1.8.0
|
||||
go.etcd.io/etcd/client/v3 v3.5.3
|
||||
go.mongodb.org/mongo-driver v1.9.0
|
||||
go.opencensus.io v0.23.0 // indirect
|
||||
go.opentelemetry.io/otel v0.15.0 // indirect
|
||||
gocloud.dev v0.20.0
|
||||
gocloud.dev/pubsub/natspubsub v0.20.0
|
||||
gocloud.dev/pubsub/rabbitpubsub v0.20.0
|
||||
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f // indirect
|
||||
gocloud.dev v0.25.0
|
||||
gocloud.dev/pubsub/natspubsub v0.25.0
|
||||
gocloud.dev/pubsub/rabbitpubsub v0.25.0
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
|
||||
golang.org/x/exp v0.0.0-20220414153411-bcd21879b8fd
|
||||
golang.org/x/image v0.0.0-20200119044424-58c23975cae1
|
||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d
|
||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect
|
||||
golang.org/x/sys v0.0.0-20220111092808-5a964db01320
|
||||
golang.org/x/net v0.0.0-20220412020605-290c469a71a5
|
||||
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
google.golang.org/api v0.57.0
|
||||
golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023
|
||||
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect
|
||||
google.golang.org/api v0.74.0
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20210921142501-181ce0d877f6 // indirect
|
||||
google.golang.org/grpc v1.40.0
|
||||
google.golang.org/protobuf v1.27.1
|
||||
google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac // indirect
|
||||
google.golang.org/grpc v1.45.0
|
||||
google.golang.org/protobuf v1.28.0
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/jcmturner/aescts.v1 v1.0.1 // indirect
|
||||
gopkg.in/jcmturner/dnsutils.v1 v1.0.1 // indirect
|
||||
gopkg.in/jcmturner/goidentity.v3 v3.0.0 // indirect
|
||||
gopkg.in/jcmturner/gokrb5.v7 v7.3.0 // indirect
|
||||
gopkg.in/jcmturner/rpc.v1 v1.1.0 // indirect
|
||||
modernc.org/b v1.0.0 // indirect
|
||||
modernc.org/cc/v3 v3.33.5 // indirect
|
||||
modernc.org/ccgo/v3 v3.9.4 // indirect
|
||||
modernc.org/libc v1.9.5 // indirect
|
||||
modernc.org/mathutil v1.2.2 // indirect
|
||||
modernc.org/memory v1.0.4 // indirect
|
||||
modernc.org/cc/v3 v3.35.24 // indirect
|
||||
modernc.org/ccgo/v3 v3.15.18 // indirect
|
||||
modernc.org/libc v1.14.12 // indirect
|
||||
modernc.org/mathutil v1.4.1 // indirect
|
||||
modernc.org/memory v1.0.7 // indirect
|
||||
modernc.org/opt v0.1.1 // indirect
|
||||
modernc.org/sqlite v1.10.7
|
||||
modernc.org/strutil v1.1.0 // indirect
|
||||
modernc.org/sqlite v1.16.0
|
||||
modernc.org/strutil v1.1.1 // indirect
|
||||
modernc.org/token v1.0.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/fluent/fluent-logger-golang v1.8.0
|
||||
github.com/Jille/raft-grpc-transport v1.2.0
|
||||
github.com/fluent/fluent-logger-golang v1.9.0
|
||||
github.com/hanwen/go-fuse/v2 v2.1.0
|
||||
github.com/hashicorp/raft v1.3.7
|
||||
github.com/hashicorp/raft-boltdb v0.0.0-20220329195025-15018e9b97e0
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go/kms v1.0.0 // indirect
|
||||
github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798 // indirect
|
||||
cloud.google.com/go/compute v1.5.0 // indirect
|
||||
cloud.google.com/go/iam v0.3.0 // indirect
|
||||
github.com/armon/go-metrics v0.3.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.16.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.15.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.11.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sns v1.17.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sqs v1.18.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.16.3 // indirect
|
||||
github.com/aws/smithy-go v1.11.2 // indirect
|
||||
github.com/boltdb/bolt v1.3.1 // indirect
|
||||
github.com/d4l3k/messagediff v1.2.1 // indirect
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/fclairamb/go-log v0.1.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/googleapis/go-type-adapters v1.0.0 // indirect
|
||||
github.com/hashicorp/go-hclog v1.2.0 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
github.com/hashicorp/go-msgpack v1.1.5 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
|
||||
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.2 // indirect
|
||||
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.0.6 // indirect
|
||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.7 // indirect
|
||||
github.com/mattn/go-sqlite3 v2.0.1+incompatible // indirect
|
||||
github.com/nats-io/nats.go v1.13.1-0.20220121202836-972a071d373d // indirect
|
||||
github.com/nats-io/nkeys v0.3.0 // indirect
|
||||
github.com/nats-io/nuid v1.0.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.0-beta.8 // indirect
|
||||
github.com/philhofer/fwd v1.1.1 // indirect
|
||||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/subosito/gotenv v1.2.0 // indirect
|
||||
github.com/tinylib/msgp v1.1.6 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.0 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0 // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.7.0 // indirect
|
||||
go.uber.org/zap v1.17.0 // indirect
|
||||
golang.org/x/mod v0.4.2 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.3 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.3 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
go.uber.org/zap v1.21.0 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57 // indirect
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||
gopkg.in/ini.v1 v1.66.4 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
lukechampine.com/uint128 v1.1.1 // indirect
|
||||
)
|
||||
|
||||
// replace github.com/chrislusf/raft => /Users/chrislu/go/src/github.com/chrislusf/raft
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
apiVersion: v1
|
||||
description: SeaweedFS
|
||||
name: seaweedfs
|
||||
appVersion: "2.93"
|
||||
version: "2.93"
|
||||
appVersion: "2.99"
|
||||
version: "2.99"
|
||||
|
||||
@@ -41,8 +41,7 @@ master:
|
||||
grpcPort: 19333
|
||||
ipBind: "0.0.0.0"
|
||||
volumePreallocate: false
|
||||
#Master stops directing writes to oversized volumes
|
||||
volumeSizeLimitMB: 30000
|
||||
volumeSizeLimitMB: 1000
|
||||
loggingOverrideLevel: null
|
||||
#number of seconds between heartbeats, default 5
|
||||
pulseSeconds: null
|
||||
|
||||
@@ -48,6 +48,9 @@ service SeaweedFiler {
|
||||
rpc Statistics (StatisticsRequest) returns (StatisticsResponse) {
|
||||
}
|
||||
|
||||
rpc Ping (PingRequest) returns (PingResponse) {
|
||||
}
|
||||
|
||||
rpc GetFilerConfiguration (GetFilerConfigurationRequest) returns (GetFilerConfigurationResponse) {
|
||||
}
|
||||
|
||||
@@ -181,6 +184,7 @@ message CreateEntryRequest {
|
||||
bool o_excl = 3;
|
||||
bool is_from_other_cluster = 4;
|
||||
repeated int32 signatures = 5;
|
||||
bool skip_check_parent_directory = 6;
|
||||
}
|
||||
|
||||
message CreateEntryResponse {
|
||||
@@ -310,6 +314,16 @@ message StatisticsResponse {
|
||||
uint64 file_count = 6;
|
||||
}
|
||||
|
||||
message PingRequest {
|
||||
string target = 1; // default to ping itself
|
||||
string target_type = 2;
|
||||
}
|
||||
message PingResponse {
|
||||
int64 start_time_ns = 1;
|
||||
int64 remote_time_ns = 2;
|
||||
int64 stop_time_ns = 3;
|
||||
}
|
||||
|
||||
message GetFilerConfigurationRequest {
|
||||
}
|
||||
message GetFilerConfigurationResponse {
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.hadoop</groupId>
|
||||
<artifactId>hadoop-common</artifactId>
|
||||
<version>3.2.2</version>
|
||||
<version>3.2.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.hadoop</groupId>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<properties>
|
||||
<seaweedfs.client.version>2.85</seaweedfs.client.version>
|
||||
<hadoop.version>3.1.4</hadoop.version>
|
||||
<hadoop.version>3.2.3</hadoop.version>
|
||||
</properties>
|
||||
|
||||
<groupId>com.github.chrislusf</groupId>
|
||||
|
||||
+22
-3
@@ -9,9 +9,10 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
MasterType = "master"
|
||||
FilerType = "filer"
|
||||
BrokerType = "broker"
|
||||
MasterType = "master"
|
||||
VolumeServerType = "volumeServer"
|
||||
FilerType = "filer"
|
||||
BrokerType = "broker"
|
||||
)
|
||||
|
||||
type ClusterNode struct {
|
||||
@@ -80,6 +81,15 @@ func (cluster *Cluster) AddClusterNode(nodeType string, address pb.ServerAddress
|
||||
},
|
||||
}
|
||||
case MasterType:
|
||||
return []*master_pb.KeepConnectedResponse{
|
||||
{
|
||||
ClusterNodeUpdate: &master_pb.ClusterNodeUpdate{
|
||||
NodeType: nodeType,
|
||||
Address: string(address),
|
||||
IsAdd: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -119,6 +129,15 @@ func (cluster *Cluster) RemoveClusterNode(nodeType string, address pb.ServerAddr
|
||||
}
|
||||
}
|
||||
case MasterType:
|
||||
return []*master_pb.KeepConnectedResponse{
|
||||
{
|
||||
ClusterNodeUpdate: &master_pb.ClusterNodeUpdate{
|
||||
NodeType: nodeType,
|
||||
Address: string(address),
|
||||
IsAdd: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ func runBenchmark(cmd *Command, args []string) bool {
|
||||
defer pprof.StopCPUProfile()
|
||||
}
|
||||
|
||||
b.masterClient = wdclient.NewMasterClient(b.grpcDialOption, "client", "", "", pb.ServerAddresses(*b.masters).ToAddresses())
|
||||
b.masterClient = wdclient.NewMasterClient(b.grpcDialOption, "client", "", "", pb.ServerAddresses(*b.masters).ToAddressMap())
|
||||
go b.masterClient.KeepConnectedToMaster()
|
||||
b.masterClient.WaitUntilConnected()
|
||||
|
||||
|
||||
+53
-8
@@ -2,8 +2,10 @@ package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc/reflection"
|
||||
@@ -12,7 +14,7 @@ import (
|
||||
"github.com/chrislusf/seaweedfs/weed/pb"
|
||||
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
|
||||
"github.com/chrislusf/seaweedfs/weed/security"
|
||||
"github.com/chrislusf/seaweedfs/weed/server"
|
||||
weed_server "github.com/chrislusf/seaweedfs/weed/server"
|
||||
stats_collect "github.com/chrislusf/seaweedfs/weed/stats"
|
||||
"github.com/chrislusf/seaweedfs/weed/util"
|
||||
)
|
||||
@@ -28,7 +30,7 @@ var (
|
||||
)
|
||||
|
||||
type FilerOptions struct {
|
||||
masters []pb.ServerAddress
|
||||
masters map[string]pb.ServerAddress
|
||||
mastersString *string
|
||||
ip *string
|
||||
bindIp *string
|
||||
@@ -51,6 +53,7 @@ type FilerOptions struct {
|
||||
concurrentUploadLimitMB *int
|
||||
debug *bool
|
||||
debugPort *int
|
||||
localSocket *string
|
||||
}
|
||||
|
||||
func init() {
|
||||
@@ -58,7 +61,7 @@ func init() {
|
||||
f.mastersString = cmdFiler.Flag.String("master", "localhost:9333", "comma-separated master servers")
|
||||
f.collection = cmdFiler.Flag.String("collection", "", "all data will be stored in this default collection")
|
||||
f.ip = cmdFiler.Flag.String("ip", util.DetectedHostAddress(), "filer server http listen ip address")
|
||||
f.bindIp = cmdFiler.Flag.String("ip.bind", "", "ip address to bind to")
|
||||
f.bindIp = cmdFiler.Flag.String("ip.bind", "", "ip address to bind to. If empty, default to same as -ip option.")
|
||||
f.port = cmdFiler.Flag.Int("port", 8888, "filer server http listen port")
|
||||
f.portGrpc = cmdFiler.Flag.Int("port.grpc", 0, "filer server grpc listen port")
|
||||
f.publicPort = cmdFiler.Flag.Int("port.readonly", 0, "readonly port opened to public")
|
||||
@@ -76,6 +79,7 @@ func init() {
|
||||
f.concurrentUploadLimitMB = cmdFiler.Flag.Int("concurrentUploadLimitMB", 128, "limit total concurrent upload size")
|
||||
f.debug = cmdFiler.Flag.Bool("debug", false, "serves runtime profiling data, e.g., http://localhost:<debug.port>/debug/pprof/goroutine?debug=2")
|
||||
f.debugPort = cmdFiler.Flag.Int("debug.port", 6060, "http port for debugging")
|
||||
f.localSocket = cmdFiler.Flag.String("localSocket", "", "default to /tmp/seaweedfs-filer-<port>.sock")
|
||||
|
||||
// start s3 on filer
|
||||
filerStartS3 = cmdFiler.Flag.Bool("s3", false, "whether to start S3 gateway")
|
||||
@@ -86,6 +90,7 @@ func init() {
|
||||
filerS3Options.config = cmdFiler.Flag.String("s3.config", "", "path to the config file")
|
||||
filerS3Options.auditLogConfig = cmdFiler.Flag.String("s3.auditLogConfig", "", "path to the audit log config file")
|
||||
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")
|
||||
|
||||
// start webdav on filer
|
||||
filerStartWebDav = cmdFiler.Flag.Bool("webdav", false, "whether to start webdav gateway")
|
||||
@@ -100,6 +105,7 @@ func init() {
|
||||
|
||||
// start iam on filer
|
||||
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")
|
||||
}
|
||||
|
||||
@@ -139,11 +145,14 @@ func runFiler(cmd *Command, args []string) bool {
|
||||
if *filerStartS3 {
|
||||
filerS3Options.filer = &filerAddress
|
||||
filerS3Options.bindIp = f.bindIp
|
||||
filerS3Options.localFilerSocket = f.localSocket
|
||||
go func() {
|
||||
time.Sleep(startDelay * time.Second)
|
||||
filerS3Options.startS3Server()
|
||||
}()
|
||||
startDelay++
|
||||
} else {
|
||||
*f.localSocket = ""
|
||||
}
|
||||
|
||||
if *filerStartWebDav {
|
||||
@@ -164,7 +173,7 @@ func runFiler(cmd *Command, args []string) bool {
|
||||
}()
|
||||
}
|
||||
|
||||
f.masters = pb.ServerAddresses(*f.mastersString).ToAddresses()
|
||||
f.masters = pb.ServerAddresses(*f.mastersString).ToAddressMap()
|
||||
|
||||
f.startFiler()
|
||||
|
||||
@@ -182,6 +191,9 @@ func (fo *FilerOptions) startFiler() {
|
||||
if *fo.portGrpc == 0 {
|
||||
*fo.portGrpc = 10000 + *fo.port
|
||||
}
|
||||
if *fo.bindIp == "" {
|
||||
*fo.bindIp = *fo.ip
|
||||
}
|
||||
|
||||
defaultLevelDbDirectory := util.ResolvePath(*fo.defaultLevelDbDirectory + "/filerldb2")
|
||||
|
||||
@@ -210,7 +222,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)
|
||||
publicListener, e := util.NewListener(publicListeningAddress, 0)
|
||||
publicListener, localPublicListner, 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)
|
||||
}
|
||||
@@ -219,11 +231,18 @@ func (fo *FilerOptions) startFiler() {
|
||||
glog.Fatalf("Volume server fail to serve public: %v", e)
|
||||
}
|
||||
}()
|
||||
if localPublicListner != nil {
|
||||
go func() {
|
||||
if e := http.Serve(localPublicListner, publicVolumeMux); e != nil {
|
||||
glog.Errorf("Volume server fail to serve public: %v", e)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
glog.V(0).Infof("Start Seaweed Filer %s at %s:%d", util.Version(), *fo.ip, *fo.port)
|
||||
filerListener, e := util.NewListener(
|
||||
util.JoinHostPort(*fo.bindIp, *fo.port),
|
||||
filerListener, filerLocalListener, e := util.NewIpAndLocalListeners(
|
||||
*fo.bindIp, *fo.port,
|
||||
time.Duration(10)*time.Second,
|
||||
)
|
||||
if e != nil {
|
||||
@@ -232,16 +251,42 @@ func (fo *FilerOptions) startFiler() {
|
||||
|
||||
// starting grpc server
|
||||
grpcPort := *fo.portGrpc
|
||||
grpcL, err := util.NewListener(util.JoinHostPort(*fo.bindIp, grpcPort), 0)
|
||||
grpcL, grpcLocalL, err := util.NewIpAndLocalListeners(*fo.bindIp, grpcPort, 0)
|
||||
if err != nil {
|
||||
glog.Fatalf("failed to listen on grpc port %d: %v", grpcPort, err)
|
||||
}
|
||||
grpcS := pb.NewGrpcServer(security.LoadServerTLS(util.GetViper(), "grpc.filer"))
|
||||
filer_pb.RegisterSeaweedFilerServer(grpcS, fs)
|
||||
reflection.Register(grpcS)
|
||||
if grpcLocalL != nil {
|
||||
go grpcS.Serve(grpcLocalL)
|
||||
}
|
||||
go grpcS.Serve(grpcL)
|
||||
|
||||
httpS := &http.Server{Handler: defaultMux}
|
||||
if runtime.GOOS != "windows" {
|
||||
if *fo.localSocket == "" {
|
||||
*fo.localSocket = fmt.Sprintf("/tmp/seaweefs-filer-%d.sock", *fo.port)
|
||||
if err := os.Remove(*fo.localSocket); err != nil && !os.IsNotExist(err) {
|
||||
glog.Fatalf("Failed to remove %s, error: %s", *fo.localSocket, err.Error())
|
||||
}
|
||||
}
|
||||
go func() {
|
||||
// start on local unix socket
|
||||
filerSocketListener, err := net.Listen("unix", *fo.localSocket)
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed to listen on %s: %v", *fo.localSocket, err)
|
||||
}
|
||||
httpS.Serve(filerSocketListener)
|
||||
}()
|
||||
}
|
||||
if filerLocalListener != nil {
|
||||
go func() {
|
||||
if err := httpS.Serve(filerLocalListener); err != nil {
|
||||
glog.Errorf("Filer Fail to serve: %v", e)
|
||||
}
|
||||
}()
|
||||
}
|
||||
if err := httpS.Serve(filerListener); err != nil {
|
||||
glog.Fatalf("Filer Fail to serve: %v", e)
|
||||
}
|
||||
|
||||
@@ -267,7 +267,10 @@ func genProcessFunction(sourcePath string, targetPath string, dataSink sink.Repl
|
||||
return nil
|
||||
}
|
||||
key := buildKey(dataSink, message, targetPath, sourceOldKey, sourcePath)
|
||||
return dataSink.DeleteEntry(key, message.OldEntry.IsDirectory, message.DeleteChunks, message.Signatures)
|
||||
if !dataSink.IsIncremental() {
|
||||
return dataSink.DeleteEntry(key, message.OldEntry.IsDirectory, message.DeleteChunks, message.Signatures)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// handle new entries
|
||||
|
||||
+11
-2
@@ -22,6 +22,7 @@ var (
|
||||
type IamOptions struct {
|
||||
filer *string
|
||||
masters *string
|
||||
ip *string
|
||||
port *int
|
||||
}
|
||||
|
||||
@@ -29,6 +30,7 @@ func init() {
|
||||
cmdIam.Run = runIam // break init cycle
|
||||
iamStandaloneOptions.filer = cmdIam.Flag.String("filer", "localhost:8888", "filer server address")
|
||||
iamStandaloneOptions.masters = cmdIam.Flag.String("master", "localhost:9333", "comma-separated master servers")
|
||||
iamStandaloneOptions.ip = cmdIam.Flag.String("ip", util.DetectedHostAddress(), "iam server http listen ip address")
|
||||
iamStandaloneOptions.port = cmdIam.Flag.Int("port", 8111, "iam server http listen port")
|
||||
}
|
||||
|
||||
@@ -65,7 +67,7 @@ func (iamopt *IamOptions) startIamServer() bool {
|
||||
}
|
||||
}
|
||||
|
||||
masters := pb.ServerAddresses(*iamopt.masters).ToAddresses()
|
||||
masters := pb.ServerAddresses(*iamopt.masters).ToAddressMap()
|
||||
router := mux.NewRouter().SkipClean(true)
|
||||
_, iamApiServer_err := iamapi.NewIamApiServer(router, &iamapi.IamServerOption{
|
||||
Masters: masters,
|
||||
@@ -81,12 +83,19 @@ func (iamopt *IamOptions) startIamServer() bool {
|
||||
httpS := &http.Server{Handler: router}
|
||||
|
||||
listenAddress := fmt.Sprintf(":%d", *iamopt.port)
|
||||
iamApiListener, err := util.NewListener(listenAddress, time.Duration(10)*time.Second)
|
||||
iamApiListener, iamApiLocalListener, err := util.NewIpAndLocalListeners(*iamopt.ip, *iamopt.port, time.Duration(10)*time.Second)
|
||||
if err != nil {
|
||||
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)
|
||||
if iamApiLocalListener != nil {
|
||||
go func() {
|
||||
if err = httpS.Serve(iamApiLocalListener); err != nil {
|
||||
glog.Errorf("IAM API Server Fail to serve: %v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
if err = httpS.Serve(iamApiListener); err != nil {
|
||||
glog.Fatalf("IAM API Server Fail to serve: %v", err)
|
||||
}
|
||||
|
||||
+93
-25
@@ -1,15 +1,17 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"golang.org/x/exp/slices"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/chrislusf/raft/protobuf"
|
||||
stats_collect "github.com/chrislusf/seaweedfs/weed/stats"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/viper"
|
||||
"google.golang.org/grpc/reflection"
|
||||
"net/http"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/chrislusf/seaweedfs/weed/util/grace"
|
||||
|
||||
@@ -17,7 +19,7 @@ import (
|
||||
"github.com/chrislusf/seaweedfs/weed/pb"
|
||||
"github.com/chrislusf/seaweedfs/weed/pb/master_pb"
|
||||
"github.com/chrislusf/seaweedfs/weed/security"
|
||||
"github.com/chrislusf/seaweedfs/weed/server"
|
||||
weed_server "github.com/chrislusf/seaweedfs/weed/server"
|
||||
"github.com/chrislusf/seaweedfs/weed/storage/backend"
|
||||
"github.com/chrislusf/seaweedfs/weed/util"
|
||||
)
|
||||
@@ -46,6 +48,8 @@ type MasterOptions struct {
|
||||
metricsHttpPort *int
|
||||
heartbeatInterval *time.Duration
|
||||
electionTimeout *time.Duration
|
||||
raftHashicorp *bool
|
||||
raftBootstrap *bool
|
||||
}
|
||||
|
||||
func init() {
|
||||
@@ -53,7 +57,7 @@ func init() {
|
||||
m.port = cmdMaster.Flag.Int("port", 9333, "http listen port")
|
||||
m.portGrpc = cmdMaster.Flag.Int("port.grpc", 0, "grpc listen port")
|
||||
m.ip = cmdMaster.Flag.String("ip", util.DetectedHostAddress(), "master <ip>|<server> address, also used as identifier")
|
||||
m.ipBind = cmdMaster.Flag.String("ip.bind", "", "ip address to bind to")
|
||||
m.ipBind = cmdMaster.Flag.String("ip.bind", "", "ip address to bind to. If empty, default to same as -ip option.")
|
||||
m.metaFolder = cmdMaster.Flag.String("mdir", os.TempDir(), "data directory to store meta data")
|
||||
m.peers = cmdMaster.Flag.String("peers", "", "all master nodes in comma separated ip:port list, example: 127.0.0.1:9093,127.0.0.1:9094,127.0.0.1:9095")
|
||||
m.volumeSizeLimitMB = cmdMaster.Flag.Uint("volumeSizeLimitMB", 30*1000, "Master stops directing writes to oversized volumes.")
|
||||
@@ -69,6 +73,8 @@ func init() {
|
||||
m.raftResumeState = cmdMaster.Flag.Bool("resumeState", false, "resume previous state on start master server")
|
||||
m.heartbeatInterval = cmdMaster.Flag.Duration("heartbeatInterval", 300*time.Millisecond, "heartbeat interval of master servers, and will be randomly multiplied by [1, 1.25)")
|
||||
m.electionTimeout = cmdMaster.Flag.Duration("electionTimeout", 10*time.Second, "election timeout of master servers")
|
||||
m.raftHashicorp = cmdMaster.Flag.Bool("raftHashicorp", false, "use hashicorp raft")
|
||||
m.raftBootstrap = cmdMaster.Flag.Bool("raftBootstrap", false, "Whether to bootstrap the Raft cluster")
|
||||
}
|
||||
|
||||
var cmdMaster = &Command{
|
||||
@@ -124,61 +130,123 @@ func startMaster(masterOption MasterOptions, masterWhiteList []string) {
|
||||
if *masterOption.portGrpc == 0 {
|
||||
*masterOption.portGrpc = 10000 + *masterOption.port
|
||||
}
|
||||
if *masterOption.ipBind == "" {
|
||||
*masterOption.ipBind = *masterOption.ip
|
||||
}
|
||||
|
||||
myMasterAddress, peers := checkPeers(*masterOption.ip, *masterOption.port, *masterOption.portGrpc, *masterOption.peers)
|
||||
|
||||
masterPeers := make(map[string]pb.ServerAddress)
|
||||
for _, peer := range peers {
|
||||
masterPeers[string(peer)] = peer
|
||||
}
|
||||
|
||||
r := mux.NewRouter()
|
||||
ms := weed_server.NewMasterServer(r, masterOption.toMasterOption(masterWhiteList), peers)
|
||||
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)
|
||||
masterListener, e := util.NewListener(listeningAddress, 0)
|
||||
masterListener, masterLocalListner, e := util.NewIpAndLocalListeners(*masterOption.ipBind, *masterOption.port, 0)
|
||||
if e != nil {
|
||||
glog.Fatalf("Master startup error: %v", e)
|
||||
}
|
||||
|
||||
// start raftServer
|
||||
raftServerOption := &weed_server.RaftServerOption{
|
||||
GrpcDialOption: security.LoadClientTLS(util.GetViper(), "grpc.master"),
|
||||
Peers: peers,
|
||||
Peers: masterPeers,
|
||||
ServerAddr: myMasterAddress,
|
||||
DataDir: util.ResolvePath(*masterOption.metaFolder),
|
||||
Topo: ms.Topo,
|
||||
RaftResumeState: *masterOption.raftResumeState,
|
||||
HeartbeatInterval: *masterOption.heartbeatInterval,
|
||||
ElectionTimeout: *masterOption.electionTimeout,
|
||||
RaftBootstrap: *m.raftBootstrap,
|
||||
}
|
||||
raftServer, err := weed_server.NewRaftServer(raftServerOption)
|
||||
if raftServer == nil {
|
||||
glog.Fatalf("please verify %s is writable, see https://github.com/chrislusf/seaweedfs/issues/717: %s", *masterOption.metaFolder, err)
|
||||
var raftServer *weed_server.RaftServer
|
||||
var err error
|
||||
if *m.raftHashicorp {
|
||||
if raftServer, err = weed_server.NewHashicorpRaftServer(raftServerOption); err != nil {
|
||||
glog.Fatalf("NewHashicorpRaftServer: %s", err)
|
||||
}
|
||||
} else {
|
||||
raftServer, err = weed_server.NewRaftServer(raftServerOption)
|
||||
if raftServer == nil {
|
||||
glog.Fatalf("please verify %s is writable, see https://github.com/chrislusf/seaweedfs/issues/717: %s", *masterOption.metaFolder, err)
|
||||
}
|
||||
}
|
||||
ms.SetRaftServer(raftServer)
|
||||
r.HandleFunc("/cluster/status", raftServer.StatusHandler).Methods("GET")
|
||||
if *m.raftHashicorp {
|
||||
r.HandleFunc("/raft/stats", raftServer.StatsRaftHandler).Methods("GET")
|
||||
}
|
||||
// starting grpc server
|
||||
grpcPort := *masterOption.portGrpc
|
||||
grpcL, err := util.NewListener(util.JoinHostPort(*masterOption.ipBind, grpcPort), 0)
|
||||
grpcL, grpcLocalL, err := util.NewIpAndLocalListeners(*masterOption.ipBind, grpcPort, 0)
|
||||
if err != nil {
|
||||
glog.Fatalf("master failed to listen on grpc port %d: %v", grpcPort, err)
|
||||
}
|
||||
grpcS := pb.NewGrpcServer(security.LoadServerTLS(util.GetViper(), "grpc.master"))
|
||||
master_pb.RegisterSeaweedServer(grpcS, ms)
|
||||
protobuf.RegisterRaftServer(grpcS, raftServer)
|
||||
if *m.raftHashicorp {
|
||||
raftServer.TransportManager.Register(grpcS)
|
||||
} else {
|
||||
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)
|
||||
if grpcLocalL != nil {
|
||||
go grpcS.Serve(grpcLocalL)
|
||||
}
|
||||
go grpcS.Serve(grpcL)
|
||||
|
||||
go func() {
|
||||
time.Sleep(1500 * time.Millisecond)
|
||||
if ms.Topo.RaftServer.Leader() == "" && ms.Topo.RaftServer.IsLogEmpty() && isTheFirstOne(myMasterAddress, peers) {
|
||||
if ms.MasterClient.FindLeaderFromOtherPeers(myMasterAddress) == "" {
|
||||
raftServer.DoJoinCommand()
|
||||
timeSleep := 1500 * time.Millisecond
|
||||
if !*m.raftHashicorp {
|
||||
go func() {
|
||||
time.Sleep(timeSleep)
|
||||
if ms.Topo.RaftServer.Leader() == "" && ms.Topo.RaftServer.IsLogEmpty() && isTheFirstOne(myMasterAddress, peers) {
|
||||
if ms.MasterClient.FindLeaderFromOtherPeers(myMasterAddress) == "" {
|
||||
raftServer.DoJoinCommand()
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}()
|
||||
}
|
||||
|
||||
go ms.MasterClient.KeepConnectedToMaster()
|
||||
|
||||
// start http server
|
||||
var (
|
||||
clientCertFile,
|
||||
certFile,
|
||||
keyFile string
|
||||
)
|
||||
useTLS := false
|
||||
useMTLS := false
|
||||
|
||||
if viper.GetString("https.master.key") != "" {
|
||||
useTLS = true
|
||||
certFile = viper.GetString("https.master.cert")
|
||||
keyFile = viper.GetString("https.master.key")
|
||||
}
|
||||
|
||||
if viper.GetString("https.master.ca") != "" {
|
||||
useMTLS = true
|
||||
clientCertFile = viper.GetString("https.master.ca")
|
||||
}
|
||||
|
||||
httpS := &http.Server{Handler: r}
|
||||
go httpS.Serve(masterListener)
|
||||
if masterLocalListner != nil {
|
||||
go httpS.Serve(masterLocalListner)
|
||||
}
|
||||
|
||||
if useMTLS {
|
||||
httpS.TLSConfig = security.LoadClientTLSHTTP(clientCertFile)
|
||||
}
|
||||
|
||||
if useTLS {
|
||||
go httpS.ServeTLS(masterListener, certFile, keyFile)
|
||||
} else {
|
||||
go httpS.Serve(masterListener)
|
||||
}
|
||||
|
||||
select {}
|
||||
}
|
||||
@@ -206,8 +274,8 @@ func checkPeers(masterIp string, masterPort int, masterGrpcPort int, peers strin
|
||||
}
|
||||
|
||||
func isTheFirstOne(self pb.ServerAddress, peers []pb.ServerAddress) bool {
|
||||
sort.Slice(peers, func(i, j int) bool {
|
||||
return strings.Compare(string(peers[i]), string(peers[j])) < 0
|
||||
slices.SortFunc(peers, func(a, b pb.ServerAddress) bool {
|
||||
return strings.Compare(string(a), string(b)) < 0
|
||||
})
|
||||
if len(peers) <= 0 {
|
||||
return true
|
||||
|
||||
@@ -3,17 +3,18 @@ package command
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/chrislusf/seaweedfs/weed/glog"
|
||||
"github.com/chrislusf/seaweedfs/weed/pb"
|
||||
"github.com/chrislusf/seaweedfs/weed/pb/master_pb"
|
||||
"github.com/chrislusf/seaweedfs/weed/security"
|
||||
"github.com/chrislusf/seaweedfs/weed/server"
|
||||
weed_server "github.com/chrislusf/seaweedfs/weed/server"
|
||||
"github.com/chrislusf/seaweedfs/weed/util"
|
||||
"github.com/gorilla/mux"
|
||||
"google.golang.org/grpc/reflection"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -24,7 +25,7 @@ func init() {
|
||||
cmdMasterFollower.Run = runMasterFollower // break init cycle
|
||||
mf.port = cmdMasterFollower.Flag.Int("port", 9334, "http listen port")
|
||||
mf.portGrpc = cmdMasterFollower.Flag.Int("port.grpc", 0, "grpc listen port")
|
||||
mf.ipBind = cmdMasterFollower.Flag.String("ip.bind", "", "ip address to bind to")
|
||||
mf.ipBind = cmdMasterFollower.Flag.String("ip.bind", "", "ip address to bind to. Default to localhost.")
|
||||
mf.peers = cmdMasterFollower.Flag.String("masters", "localhost:9333", "all master nodes in comma separated ip:port list, example: 127.0.0.1:9093,127.0.0.1:9094,127.0.0.1:9095")
|
||||
|
||||
mf.ip = aws.String(util.DetectedHostAddress())
|
||||
@@ -45,13 +46,13 @@ var cmdMasterFollower = &Command{
|
||||
Short: "start a master follower",
|
||||
Long: `start a master follower to provide volume=>location mapping service
|
||||
|
||||
The master follower does not participate in master election.
|
||||
The master follower does not participate in master election.
|
||||
It just follow the existing masters, and listen for any volume location changes.
|
||||
|
||||
In most cases, the master follower is not needed. In big data centers with thousands of volume
|
||||
servers. In theory, the master may have trouble to keep up with the write requests and read requests.
|
||||
|
||||
The master follower can relieve the master from from read requests, which only needs to
|
||||
The master follower can relieve the master from from read requests, which only needs to
|
||||
lookup a fileId or volumeId.
|
||||
|
||||
The master follower currently can handle fileId lookup requests:
|
||||
@@ -82,7 +83,7 @@ func runMasterFollower(cmd *Command, args []string) bool {
|
||||
func startMasterFollower(masterOptions MasterOptions) {
|
||||
|
||||
// collect settings from main masters
|
||||
masters := pb.ServerAddresses(*mf.peers).ToAddresses()
|
||||
masters := pb.ServerAddresses(*mf.peers).ToAddressMap()
|
||||
|
||||
var err error
|
||||
grpcDialOption := security.LoadClientTLS(util.GetViper(), "grpc.master")
|
||||
@@ -111,18 +112,22 @@ func startMasterFollower(masterOptions MasterOptions) {
|
||||
option := masterOptions.toMasterOption(nil)
|
||||
option.IsFollower = true
|
||||
|
||||
if *masterOptions.ipBind == "" {
|
||||
*masterOptions.ipBind = *masterOptions.ip
|
||||
}
|
||||
|
||||
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)
|
||||
masterListener, e := util.NewListener(listeningAddress, 0)
|
||||
masterListener, masterLocalListner, e := util.NewIpAndLocalListeners(*masterOptions.ipBind, *masterOptions.port, 0)
|
||||
if e != nil {
|
||||
glog.Fatalf("Master startup error: %v", e)
|
||||
}
|
||||
|
||||
// starting grpc server
|
||||
grpcPort := *masterOptions.portGrpc
|
||||
grpcL, err := util.NewListener(util.JoinHostPort(*masterOptions.ipBind, grpcPort), 0)
|
||||
grpcL, grpcLocalL, err := util.NewIpAndLocalListeners(*masterOptions.ipBind, grpcPort, 0)
|
||||
if err != nil {
|
||||
glog.Fatalf("master failed to listen on grpc port %d: %v", grpcPort, err)
|
||||
}
|
||||
@@ -130,12 +135,18 @@ func startMasterFollower(masterOptions MasterOptions) {
|
||||
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)
|
||||
if grpcLocalL != nil {
|
||||
go grpcS.Serve(grpcLocalL)
|
||||
}
|
||||
go grpcS.Serve(grpcL)
|
||||
|
||||
go ms.MasterClient.KeepConnectedToMaster()
|
||||
|
||||
// start http server
|
||||
httpS := &http.Server{Handler: r}
|
||||
if masterLocalListner != nil {
|
||||
go httpS.Serve(masterLocalListner)
|
||||
}
|
||||
go httpS.Serve(masterListener)
|
||||
|
||||
select {}
|
||||
|
||||
@@ -29,6 +29,7 @@ type MountOptions struct {
|
||||
readOnly *bool
|
||||
debug *bool
|
||||
debugPort *int
|
||||
localSocket *string
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -63,6 +64,7 @@ func init() {
|
||||
mountOptions.readOnly = cmdMount.Flag.Bool("readOnly", false, "read only")
|
||||
mountOptions.debug = cmdMount.Flag.Bool("debug", false, "serves runtime profiling data, e.g., http://localhost:<debug.port>/debug/pprof/goroutine?debug=2")
|
||||
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")
|
||||
|
||||
mountCpuProfile = cmdMount.Flag.String("cpuprofile", "", "cpu profile output file")
|
||||
mountMemProfile = cmdMount.Flag.String("memprofile", "", "memory profile output file")
|
||||
|
||||
@@ -12,9 +12,12 @@ import (
|
||||
"github.com/chrislusf/seaweedfs/weed/mount/unmount"
|
||||
"github.com/chrislusf/seaweedfs/weed/pb"
|
||||
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
|
||||
"github.com/chrislusf/seaweedfs/weed/pb/mount_pb"
|
||||
"github.com/chrislusf/seaweedfs/weed/security"
|
||||
"github.com/chrislusf/seaweedfs/weed/storage/types"
|
||||
"github.com/hanwen/go-fuse/v2/fuse"
|
||||
"google.golang.org/grpc/reflection"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/user"
|
||||
@@ -98,6 +101,22 @@ func RunMount(option *MountOptions, umask os.FileMode) bool {
|
||||
|
||||
unmount.Unmount(dir)
|
||||
|
||||
// start on local unix socket
|
||||
if *option.localSocket == "" {
|
||||
mountDirHash := util.HashToInt32([]byte(dir))
|
||||
if mountDirHash < 0 {
|
||||
mountDirHash = -mountDirHash
|
||||
}
|
||||
*option.localSocket = fmt.Sprintf("/tmp/seaweefs-mount-%d.sock", mountDirHash)
|
||||
}
|
||||
if err := os.Remove(*option.localSocket); err != nil && !os.IsNotExist(err) {
|
||||
glog.Fatalf("Failed to remove %s, error: %s", *option.localSocket, err.Error())
|
||||
}
|
||||
montSocketListener, err := net.Listen("unix", *option.localSocket)
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed to listen on %s: %v", *option.localSocket, err)
|
||||
}
|
||||
|
||||
// detect mount folder mode
|
||||
if *option.dirAutoCreate {
|
||||
os.MkdirAll(dir, os.FileMode(0777)&^umask)
|
||||
@@ -229,6 +248,11 @@ func RunMount(option *MountOptions, umask os.FileMode) bool {
|
||||
unmount.Unmount(dir)
|
||||
})
|
||||
|
||||
grpcS := pb.NewGrpcServer()
|
||||
mount_pb.RegisterSeaweedMountServer(grpcS, seaweedFileSystem)
|
||||
reflection.Register(grpcS)
|
||||
go grpcS.Serve(montSocketListener)
|
||||
|
||||
seaweedFileSystem.StartBackgroundTasks()
|
||||
|
||||
fmt.Printf("This is SeaweedFS version %s %s %s\n", util.Version(), runtime.GOOS, runtime.GOARCH)
|
||||
|
||||
@@ -95,7 +95,7 @@ func (msgBrokerOpt *MessageBrokerOptions) startQueueServer() bool {
|
||||
}, grpcDialOption)
|
||||
|
||||
// start grpc listener
|
||||
grpcL, err := util.NewListener(util.JoinHostPort("", *msgBrokerOpt.port), 0)
|
||||
grpcL, _, err := util.NewIpAndLocalListeners("", *msgBrokerOpt.port, 0)
|
||||
if err != nil {
|
||||
glog.Fatalf("failed to listen on grpc port %d: %v", *msgBrokerOpt.port, err)
|
||||
}
|
||||
|
||||
+42
-19
@@ -24,22 +24,24 @@ var (
|
||||
)
|
||||
|
||||
type S3Options struct {
|
||||
filer *string
|
||||
bindIp *string
|
||||
port *int
|
||||
config *string
|
||||
domainName *string
|
||||
tlsPrivateKey *string
|
||||
tlsCertificate *string
|
||||
metricsHttpPort *int
|
||||
allowEmptyFolder *bool
|
||||
auditLogConfig *string
|
||||
filer *string
|
||||
bindIp *string
|
||||
port *int
|
||||
config *string
|
||||
domainName *string
|
||||
tlsPrivateKey *string
|
||||
tlsCertificate *string
|
||||
metricsHttpPort *int
|
||||
allowEmptyFolder *bool
|
||||
allowDeleteBucketNotEmpty *bool
|
||||
auditLogConfig *string
|
||||
localFilerSocket *string
|
||||
}
|
||||
|
||||
func init() {
|
||||
cmdS3.Run = runS3 // break init cycle
|
||||
s3StandaloneOptions.filer = cmdS3.Flag.String("filer", "localhost:8888", "filer server address")
|
||||
s3StandaloneOptions.bindIp = cmdS3.Flag.String("ip.bind", "", "ip address to bind to")
|
||||
s3StandaloneOptions.bindIp = cmdS3.Flag.String("ip.bind", "", "ip address to bind to. Default to localhost.")
|
||||
s3StandaloneOptions.port = cmdS3.Flag.Int("port", 8333, "s3 server http listen port")
|
||||
s3StandaloneOptions.domainName = cmdS3.Flag.String("domainName", "", "suffix of the host name in comma separated list, {bucket}.{domainName}")
|
||||
s3StandaloneOptions.config = cmdS3.Flag.String("config", "", "path to the config file")
|
||||
@@ -48,6 +50,7 @@ func init() {
|
||||
s3StandaloneOptions.tlsCertificate = cmdS3.Flag.String("cert.file", "", "path to the TLS certificate file")
|
||||
s3StandaloneOptions.metricsHttpPort = cmdS3.Flag.Int("metricsPort", 0, "Prometheus metrics listen port")
|
||||
s3StandaloneOptions.allowEmptyFolder = cmdS3.Flag.Bool("allowEmptyFolder", true, "allow empty folders")
|
||||
s3StandaloneOptions.allowDeleteBucketNotEmpty = cmdS3.Flag.Bool("allowDeleteBucketNotEmpty", true, "allow recursive deleting all entries along with bucket")
|
||||
}
|
||||
|
||||
var cmdS3 = &Command{
|
||||
@@ -177,13 +180,15 @@ func (s3opt *S3Options) startS3Server() bool {
|
||||
router := mux.NewRouter().SkipClean(true)
|
||||
|
||||
_, s3ApiServer_err := s3api.NewS3ApiServer(router, &s3api.S3ApiServerOption{
|
||||
Filer: filerAddress,
|
||||
Port: *s3opt.port,
|
||||
Config: *s3opt.config,
|
||||
DomainName: *s3opt.domainName,
|
||||
BucketsPath: filerBucketsPath,
|
||||
GrpcDialOption: grpcDialOption,
|
||||
AllowEmptyFolder: *s3opt.allowEmptyFolder,
|
||||
Filer: filerAddress,
|
||||
Port: *s3opt.port,
|
||||
Config: *s3opt.config,
|
||||
DomainName: *s3opt.domainName,
|
||||
BucketsPath: filerBucketsPath,
|
||||
GrpcDialOption: grpcDialOption,
|
||||
AllowEmptyFolder: *s3opt.allowEmptyFolder,
|
||||
AllowDeleteBucketNotEmpty: *s3opt.allowDeleteBucketNotEmpty,
|
||||
LocalFilerSocket: s3opt.localFilerSocket,
|
||||
})
|
||||
if s3ApiServer_err != nil {
|
||||
glog.Fatalf("S3 API Server startup error: %v", s3ApiServer_err)
|
||||
@@ -191,8 +196,12 @@ func (s3opt *S3Options) startS3Server() bool {
|
||||
|
||||
httpS := &http.Server{Handler: router}
|
||||
|
||||
if *s3opt.bindIp == "" {
|
||||
*s3opt.bindIp = "localhost"
|
||||
}
|
||||
|
||||
listenAddress := fmt.Sprintf("%s:%d", *s3opt.bindIp, *s3opt.port)
|
||||
s3ApiListener, err := util.NewListener(listenAddress, time.Duration(10)*time.Second)
|
||||
s3ApiListener, s3ApiLocalListner, err := util.NewIpAndLocalListeners(*s3opt.bindIp, *s3opt.port, time.Duration(10)*time.Second)
|
||||
if err != nil {
|
||||
glog.Fatalf("S3 API Server listener on %s error: %v", listenAddress, err)
|
||||
}
|
||||
@@ -206,11 +215,25 @@ func (s3opt *S3Options) startS3Server() bool {
|
||||
|
||||
if *s3opt.tlsPrivateKey != "" {
|
||||
glog.V(0).Infof("Start Seaweed S3 API Server %s at https port %d", util.Version(), *s3opt.port)
|
||||
if s3ApiLocalListner != nil {
|
||||
go func() {
|
||||
if err = httpS.ServeTLS(s3ApiLocalListner, *s3opt.tlsCertificate, *s3opt.tlsPrivateKey); err != nil {
|
||||
glog.Fatalf("S3 API Server Fail to serve: %v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
if err = httpS.ServeTLS(s3ApiListener, *s3opt.tlsCertificate, *s3opt.tlsPrivateKey); err != nil {
|
||||
glog.Fatalf("S3 API Server Fail to serve: %v", err)
|
||||
}
|
||||
} else {
|
||||
glog.V(0).Infof("Start Seaweed S3 API Server %s at http port %d", util.Version(), *s3opt.port)
|
||||
if s3ApiLocalListner != nil {
|
||||
go func() {
|
||||
if err = httpS.Serve(s3ApiLocalListner); err != nil {
|
||||
glog.Fatalf("S3 API Server Fail to serve: %v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
if err = httpS.Serve(s3ApiListener); err != nil {
|
||||
glog.Fatalf("S3 API Server Fail to serve: %v", err)
|
||||
}
|
||||
|
||||
@@ -83,7 +83,13 @@ key = ""
|
||||
# this does not work with other clients, e.g., "weed filer|mount" etc, yet.
|
||||
[https.client]
|
||||
enabled = true
|
||||
|
||||
[https.volume]
|
||||
cert = ""
|
||||
key = ""
|
||||
ca = ""
|
||||
|
||||
[https.master]
|
||||
cert = ""
|
||||
key = ""
|
||||
ca = ""
|
||||
|
||||
+10
-2
@@ -55,7 +55,7 @@ var cmdServer = &Command{
|
||||
|
||||
var (
|
||||
serverIp = cmdServer.Flag.String("ip", util.DetectedHostAddress(), "ip or server name, also used as identifier")
|
||||
serverBindIp = cmdServer.Flag.String("ip.bind", "", "ip address to bind to")
|
||||
serverBindIp = cmdServer.Flag.String("ip.bind", "", "ip address to bind to. If empty, default to same as -ip option.")
|
||||
serverTimeout = cmdServer.Flag.Int("idleTimeout", 30, "connection idle seconds")
|
||||
serverDataCenter = cmdServer.Flag.String("dataCenter", "", "current volume server's data center name")
|
||||
serverRack = cmdServer.Flag.String("rack", "", "current volume server's rack name")
|
||||
@@ -112,6 +112,7 @@ func init() {
|
||||
filerOptions.cipher = cmdServer.Flag.Bool("filer.encryptVolumeData", false, "encrypt data on volume servers")
|
||||
filerOptions.saveToFilerLimit = cmdServer.Flag.Int("filer.saveToFilerLimit", 0, "Small files smaller than this limit can be cached in filer store.")
|
||||
filerOptions.concurrentUploadLimitMB = cmdServer.Flag.Int("filer.concurrentUploadLimitMB", 64, "limit total concurrent upload size")
|
||||
filerOptions.localSocket = cmdServer.Flag.String("filer.localSocket", "", "default to /tmp/seaweedfs-filer-<port>.sock")
|
||||
|
||||
serverOptions.v.port = cmdServer.Flag.Int("volume.port", 8080, "volume server http listen port")
|
||||
serverOptions.v.portGrpc = cmdServer.Flag.Int("volume.port.grpc", 0, "volume server grpc listen port")
|
||||
@@ -137,6 +138,7 @@ func init() {
|
||||
s3Options.config = cmdServer.Flag.String("s3.config", "", "path to the config file")
|
||||
s3Options.auditLogConfig = cmdServer.Flag.String("s3.auditLogConfig", "", "path to the audit log config file")
|
||||
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")
|
||||
|
||||
iamOptions.port = cmdServer.Flag.Int("iam.port", 8111, "iam server http listen port")
|
||||
|
||||
@@ -183,13 +185,18 @@ func runServer(cmd *Command, args []string) bool {
|
||||
masterOptions.peers = &peers
|
||||
}
|
||||
|
||||
if *serverBindIp == "" {
|
||||
serverBindIp = serverIp
|
||||
}
|
||||
|
||||
// ip address
|
||||
masterOptions.ip = serverIp
|
||||
masterOptions.ipBind = serverBindIp
|
||||
filerOptions.masters = pb.ServerAddresses(*masterOptions.peers).ToAddresses()
|
||||
filerOptions.masters = pb.ServerAddresses(*masterOptions.peers).ToAddressMap()
|
||||
filerOptions.ip = serverIp
|
||||
filerOptions.bindIp = serverBindIp
|
||||
s3Options.bindIp = serverBindIp
|
||||
iamOptions.ip = serverBindIp
|
||||
iamOptions.masters = masterOptions.peers
|
||||
serverOptions.v.ip = serverIp
|
||||
serverOptions.v.bindIp = serverBindIp
|
||||
@@ -245,6 +252,7 @@ func runServer(cmd *Command, args []string) bool {
|
||||
if *isStartingS3 {
|
||||
go func() {
|
||||
time.Sleep(2 * time.Second)
|
||||
s3Options.localFilerSocket = filerOptions.localSocket
|
||||
s3Options.startS3Server()
|
||||
}()
|
||||
}
|
||||
|
||||
+15
-4
@@ -2,7 +2,6 @@ package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/chrislusf/seaweedfs/weed/storage/types"
|
||||
"net/http"
|
||||
httppprof "net/http/pprof"
|
||||
"os"
|
||||
@@ -11,6 +10,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/chrislusf/seaweedfs/weed/storage/types"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
@@ -24,7 +25,7 @@ import (
|
||||
|
||||
"github.com/chrislusf/seaweedfs/weed/glog"
|
||||
"github.com/chrislusf/seaweedfs/weed/pb/volume_server_pb"
|
||||
"github.com/chrislusf/seaweedfs/weed/server"
|
||||
weed_server "github.com/chrislusf/seaweedfs/weed/server"
|
||||
stats_collect "github.com/chrislusf/seaweedfs/weed/stats"
|
||||
"github.com/chrislusf/seaweedfs/weed/storage"
|
||||
"github.com/chrislusf/seaweedfs/weed/util"
|
||||
@@ -74,7 +75,7 @@ func init() {
|
||||
v.publicPort = cmdVolume.Flag.Int("port.public", 0, "port opened to public")
|
||||
v.ip = cmdVolume.Flag.String("ip", util.DetectedHostAddress(), "ip or server name, also used as identifier")
|
||||
v.publicUrl = cmdVolume.Flag.String("publicUrl", "", "Publicly accessible address")
|
||||
v.bindIp = cmdVolume.Flag.String("ip.bind", "", "ip address to bind to")
|
||||
v.bindIp = cmdVolume.Flag.String("ip.bind", "", "ip address to bind to. If empty, default to same as -ip option.")
|
||||
v.mastersString = cmdVolume.Flag.String("mserver", "localhost:9333", "comma-separated master servers")
|
||||
v.preStopSeconds = cmdVolume.Flag.Int("preStopSeconds", 10, "number of seconds between stop send heartbeats and stop volume server")
|
||||
// v.pulseSeconds = cmdVolume.Flag.Int("pulseSeconds", 5, "number of seconds between heartbeats, must be smaller than or equal to the master's setting")
|
||||
@@ -193,6 +194,9 @@ func (v VolumeServerOptions) startVolumeServer(volumeFolders, maxVolumeCounts, v
|
||||
*v.ip = util.DetectedHostAddress()
|
||||
glog.V(0).Infof("detected volume server ip address: %v", *v.ip)
|
||||
}
|
||||
if *v.bindIp == "" {
|
||||
*v.bindIp = *v.ip
|
||||
}
|
||||
|
||||
if *v.publicPort == 0 {
|
||||
*v.publicPort = *v.port
|
||||
@@ -368,7 +372,14 @@ func (v VolumeServerOptions) startClusterHttpService(handler http.Handler) httpd
|
||||
StopTimeout: 30 * time.Second,
|
||||
CertFile: certFile,
|
||||
KeyFile: keyFile}
|
||||
clusterHttpServer := httpDown.Serve(&http.Server{Handler: handler}, listener)
|
||||
httpS := &http.Server{Handler: handler}
|
||||
|
||||
if viper.GetString("https.volume.ca") != "" {
|
||||
clientCertFile := viper.GetString("https.volume.ca")
|
||||
httpS.TLSConfig = security.LoadClientTLSHTTP(clientCertFile)
|
||||
}
|
||||
|
||||
clusterHttpServer := httpDown.Serve(httpS, listener)
|
||||
go func() {
|
||||
if e := clusterHttpServer.Wait(); e != nil {
|
||||
glog.Fatalf("Volume server fail to serve: %v", e)
|
||||
|
||||
@@ -68,12 +68,12 @@ func ResolveChunkManifest(lookupFileIdFn wdclient.LookupFileIdFunctionType, chun
|
||||
|
||||
manifestChunks = append(manifestChunks, chunk)
|
||||
// recursive
|
||||
dchunks, mchunks, subErr := ResolveChunkManifest(lookupFileIdFn, resolvedChunks, startOffset, stopOffset)
|
||||
dataChunks, manifestChunks, subErr := ResolveChunkManifest(lookupFileIdFn, resolvedChunks, startOffset, stopOffset)
|
||||
if subErr != nil {
|
||||
return chunks, nil, subErr
|
||||
}
|
||||
dataChunks = append(dataChunks, dchunks...)
|
||||
manifestChunks = append(manifestChunks, mchunks...)
|
||||
dataChunks = append(dataChunks, dataChunks...)
|
||||
manifestChunks = append(manifestChunks, manifestChunks...)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -115,6 +115,15 @@ func fetchWholeChunk(bytesBuffer *bytes.Buffer, lookupFileIdFn wdclient.LookupFi
|
||||
return nil
|
||||
}
|
||||
|
||||
func fetchChunkRange(buffer []byte, lookupFileIdFn wdclient.LookupFileIdFunctionType, fileId string, cipherKey []byte, isGzipped bool, offset int64) (int, error) {
|
||||
urlStrings, err := lookupFileIdFn(fileId)
|
||||
if err != nil {
|
||||
glog.Errorf("operation LookupFileId %s failed, err: %v", fileId, err)
|
||||
return 0, err
|
||||
}
|
||||
return retriedFetchChunkData(buffer, urlStrings, cipherKey, isGzipped, false, offset)
|
||||
}
|
||||
|
||||
func retriedFetchChunkData(buffer []byte, urlStrings []string, cipherKey []byte, isGzipped bool, isFullChunk bool, offset int64) (n int, err error) {
|
||||
|
||||
var shouldRetry bool
|
||||
|
||||
+18
-11
@@ -4,8 +4,8 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/chrislusf/seaweedfs/weed/wdclient"
|
||||
"golang.org/x/exp/slices"
|
||||
"math"
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
|
||||
@@ -23,7 +23,16 @@ func TotalSize(chunks []*filer_pb.FileChunk) (size uint64) {
|
||||
}
|
||||
|
||||
func FileSize(entry *filer_pb.Entry) (size uint64) {
|
||||
return maxUint64(TotalSize(entry.Chunks), entry.Attributes.FileSize)
|
||||
if entry == nil || entry.Attributes == nil {
|
||||
return 0
|
||||
}
|
||||
fileSize := entry.Attributes.FileSize
|
||||
if entry.RemoteEntry != nil {
|
||||
if entry.RemoteEntry.RemoteMtime > entry.Attributes.Mtime {
|
||||
fileSize = maxUint64(fileSize, uint64(entry.RemoteEntry.RemoteSize))
|
||||
}
|
||||
}
|
||||
return maxUint64(TotalSize(entry.Chunks), fileSize)
|
||||
}
|
||||
|
||||
func ETag(entry *filer_pb.Entry) (etag string) {
|
||||
@@ -245,19 +254,17 @@ func NonOverlappingVisibleIntervals(lookupFileIdFn wdclient.LookupFileIdFunction
|
||||
if true {
|
||||
return visibles2, err
|
||||
}
|
||||
|
||||
sort.Slice(chunks, func(i, j int) bool {
|
||||
if chunks[i].Mtime == chunks[j].Mtime {
|
||||
filer_pb.EnsureFid(chunks[i])
|
||||
filer_pb.EnsureFid(chunks[j])
|
||||
if chunks[i].Fid == nil || chunks[j].Fid == nil {
|
||||
slices.SortFunc(chunks, func(a, b *filer_pb.FileChunk) bool {
|
||||
if a.Mtime == b.Mtime {
|
||||
filer_pb.EnsureFid(a)
|
||||
filer_pb.EnsureFid(b)
|
||||
if a.Fid == nil || b.Fid == nil {
|
||||
return true
|
||||
}
|
||||
return chunks[i].Fid.FileKey < chunks[j].Fid.FileKey
|
||||
return a.Fid.FileKey < b.Fid.FileKey
|
||||
}
|
||||
return chunks[i].Mtime < chunks[j].Mtime // keep this to make tests run
|
||||
return a.Mtime < b.Mtime
|
||||
})
|
||||
|
||||
for _, chunk := range chunks {
|
||||
|
||||
// glog.V(0).Infof("merge [%d,%d)", chunk.Offset, chunk.Offset+int64(chunk.Size))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package filer
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"golang.org/x/exp/slices"
|
||||
"testing"
|
||||
|
||||
"github.com/chrislusf/seaweedfs/weed/glog"
|
||||
@@ -34,11 +34,11 @@ func TestCompactFileChunksRealCase(t *testing.T) {
|
||||
}
|
||||
|
||||
func printChunks(name string, chunks []*filer_pb.FileChunk) {
|
||||
sort.Slice(chunks, func(i, j int) bool {
|
||||
if chunks[i].Offset == chunks[j].Offset {
|
||||
return chunks[i].Mtime < chunks[j].Mtime
|
||||
slices.SortFunc(chunks, func(a, b *filer_pb.FileChunk) bool {
|
||||
if a.Offset == b.Offset {
|
||||
return a.Mtime < b.Mtime
|
||||
}
|
||||
return chunks[i].Offset < chunks[j].Offset
|
||||
return a.Offset < b.Offset
|
||||
})
|
||||
for _, chunk := range chunks {
|
||||
glog.V(0).Infof("%s chunk %s [%10d,%10d)", name, chunk.GetFileIdString(), chunk.Offset, chunk.Offset+int64(chunk.Size))
|
||||
|
||||
@@ -2,7 +2,7 @@ package filer
|
||||
|
||||
import (
|
||||
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
|
||||
"sort"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
func readResolvedChunks(chunks []*filer_pb.FileChunk) (visibles []VisibleInterval) {
|
||||
@@ -22,17 +22,14 @@ func readResolvedChunks(chunks []*filer_pb.FileChunk) (visibles []VisibleInterva
|
||||
isStart: false,
|
||||
})
|
||||
}
|
||||
sort.Slice(points, func(i, j int) bool {
|
||||
if points[i].x != points[j].x {
|
||||
return points[i].x < points[j].x
|
||||
slices.SortFunc(points, func(a, b *Point) bool {
|
||||
if a.x != b.x {
|
||||
return a.x < b.x
|
||||
}
|
||||
if points[i].ts != points[j].ts {
|
||||
return points[i].ts < points[j].ts
|
||||
if a.ts != b.ts {
|
||||
return a.ts < b.ts
|
||||
}
|
||||
if !points[i].isStart {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return !a.isStart
|
||||
})
|
||||
|
||||
var prevX int64
|
||||
|
||||
+7
-5
@@ -49,7 +49,7 @@ type Filer struct {
|
||||
UniqueFileId uint32
|
||||
}
|
||||
|
||||
func NewFiler(masters []pb.ServerAddress, grpcDialOption grpc.DialOption,
|
||||
func NewFiler(masters map[string]pb.ServerAddress, grpcDialOption grpc.DialOption,
|
||||
filerHost pb.ServerAddress, collection string, replication string, dataCenter string, notifyFn func()) *Filer {
|
||||
f := &Filer{
|
||||
MasterClient: wdclient.NewMasterClient(grpcDialOption, cluster.FilerType, filerHost, dataCenter, masters),
|
||||
@@ -151,7 +151,7 @@ func (f *Filer) RollbackTransaction(ctx context.Context) error {
|
||||
return f.Store.RollbackTransaction(ctx)
|
||||
}
|
||||
|
||||
func (f *Filer) CreateEntry(ctx context.Context, entry *Entry, o_excl bool, isFromOtherCluster bool, signatures []int32) error {
|
||||
func (f *Filer) CreateEntry(ctx context.Context, entry *Entry, o_excl bool, isFromOtherCluster bool, signatures []int32, skipCreateParentDir bool) error {
|
||||
|
||||
if string(entry.FullPath) == "/" {
|
||||
return nil
|
||||
@@ -169,9 +169,11 @@ func (f *Filer) CreateEntry(ctx context.Context, entry *Entry, o_excl bool, isFr
|
||||
|
||||
if oldEntry == nil {
|
||||
|
||||
dirParts := strings.Split(string(entry.FullPath), "/")
|
||||
if err := f.ensureParentDirecotryEntry(ctx, entry, dirParts, len(dirParts)-1, isFromOtherCluster); err != nil {
|
||||
return err
|
||||
if !skipCreateParentDir {
|
||||
dirParts := strings.Split(string(entry.FullPath), "/")
|
||||
if err := f.ensureParentDirecotryEntry(ctx, entry, dirParts, len(dirParts)-1, isFromOtherCluster); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
glog.V(4).Infof("InsertEntry %s: new entry: %v", entry.FullPath, entry.Name())
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package filer
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -129,6 +130,12 @@ func (f *Filer) DeleteChunks(chunks []*filer_pb.FileChunk) {
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Filer) DeleteChunksNotRecursive(chunks []*filer_pb.FileChunk) {
|
||||
for _, chunk := range chunks {
|
||||
f.fileIdDeletionQueue.EnQueue(chunk.GetFileIdString())
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Filer) deleteChunksIfNotNew(oldEntry, newEntry *Entry) {
|
||||
|
||||
if oldEntry == nil {
|
||||
@@ -141,14 +148,36 @@ func (f *Filer) deleteChunksIfNotNew(oldEntry, newEntry *Entry) {
|
||||
|
||||
var toDelete []*filer_pb.FileChunk
|
||||
newChunkIds := make(map[string]bool)
|
||||
for _, newChunk := range newEntry.Chunks {
|
||||
newDataChunks, newManifestChunks, err := ResolveChunkManifest(f.MasterClient.GetLookupFileIdFunction(),
|
||||
newEntry.Chunks, 0, math.MaxInt64)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to resolve new entry chunks when delete old entry chunks. new: %s, old: %s",
|
||||
newEntry.Chunks, oldEntry.Chunks)
|
||||
return
|
||||
}
|
||||
for _, newChunk := range newDataChunks {
|
||||
newChunkIds[newChunk.GetFileIdString()] = true
|
||||
}
|
||||
for _, newChunk := range newManifestChunks {
|
||||
newChunkIds[newChunk.GetFileIdString()] = true
|
||||
}
|
||||
|
||||
for _, oldChunk := range oldEntry.Chunks {
|
||||
oldDataChunks, oldManifestChunks, err := ResolveChunkManifest(f.MasterClient.GetLookupFileIdFunction(),
|
||||
oldEntry.Chunks, 0, math.MaxInt64)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to resolve old entry chunks when delete old entry chunks. new: %s, old: %s",
|
||||
newEntry.Chunks, oldEntry.Chunks)
|
||||
return
|
||||
}
|
||||
for _, oldChunk := range oldDataChunks {
|
||||
if _, found := newChunkIds[oldChunk.GetFileIdString()]; !found {
|
||||
toDelete = append(toDelete, oldChunk)
|
||||
}
|
||||
}
|
||||
f.DeleteChunks(toDelete)
|
||||
for _, oldChunk := range oldManifestChunks {
|
||||
if _, found := newChunkIds[oldChunk.GetFileIdString()]; !found {
|
||||
toDelete = append(toDelete, oldChunk)
|
||||
}
|
||||
}
|
||||
f.DeleteChunksNotRecursive(toDelete)
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ func (f *Filer) appendToFile(targetFile string, data []byte) error {
|
||||
entry.Chunks = append(entry.Chunks, uploadResult.ToPbFileChunk(assignResult.Fid, offset))
|
||||
|
||||
// update the entry
|
||||
err = f.CreateEntry(context.Background(), entry, false, false, nil)
|
||||
err = f.CreateEntry(context.Background(), entry, false, false, nil, false)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ func TestCreateAndFind(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
if err := testFiler.CreateEntry(ctx, entry1, false, false, nil); err != nil {
|
||||
if err := testFiler.CreateEntry(ctx, entry1, false, false, nil, false); err != nil {
|
||||
t.Errorf("create entry %v: %v", entry1.FullPath, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ func TestCreateAndFind(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
if err := testFiler.CreateEntry(ctx, entry1, false, false, nil); err != nil {
|
||||
if err := testFiler.CreateEntry(ctx, entry1, false, false, nil, false); err != nil {
|
||||
t.Errorf("create entry %v: %v", entry1.FullPath, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ func TestCreateAndFind(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
if err := testFiler.CreateEntry(ctx, entry1, false, false, nil); err != nil {
|
||||
if err := testFiler.CreateEntry(ctx, entry1, false, false, nil, false); err != nil {
|
||||
t.Errorf("create entry %v: %v", entry1.FullPath, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -76,9 +76,6 @@ func (ma *MetaAggregator) setActive(address pb.ServerAddress, isActive bool) (no
|
||||
}
|
||||
} else {
|
||||
if _, found := ma.peerStatues[address]; found {
|
||||
ma.peerStatues[address] -= 1
|
||||
}
|
||||
if ma.peerStatues[address] <= 0 {
|
||||
delete(ma.peerStatues, address)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/chrislusf/seaweedfs/weed/filer"
|
||||
@@ -82,7 +83,7 @@ func (store *MysqlStore2) initialize(createTable, upsertQuery string, enableUpse
|
||||
return fmt.Errorf("connect to %s error:%v", sqlUrl, err)
|
||||
}
|
||||
|
||||
if err = store.CreateTable(context.Background(), abstract_sql.DEFAULT_TABLE); err != nil {
|
||||
if err = store.CreateTable(context.Background(), abstract_sql.DEFAULT_TABLE); err != nil && !strings.Contains(err.Error(), "table already exist") {
|
||||
return fmt.Errorf("init table %s: %v", abstract_sql.DEFAULT_TABLE, err)
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ func SaveInsideFiler(client filer_pb.SeaweedFilerClient, dir, name string, conte
|
||||
},
|
||||
Content: content,
|
||||
},
|
||||
SkipCheckParentDirectory: true,
|
||||
})
|
||||
} else if err == nil {
|
||||
entry := resp.Entry
|
||||
|
||||
@@ -164,7 +164,7 @@ func (c *ChunkReadAt) doReadAt(p []byte, offset int64) (n int, err error) {
|
||||
func (c *ChunkReadAt) readChunkSliceAt(buffer []byte, chunkView *ChunkView, nextChunkViews []*ChunkView, offset uint64) (n int, err error) {
|
||||
|
||||
if c.readerPattern.IsRandomMode() {
|
||||
return c.readerCache.ReadChunkAt(buffer, chunkView.FileId, chunkView.CipherKey, chunkView.IsGzipped, int64(offset), int(chunkView.ChunkSize), chunkView.LogicOffset == 0)
|
||||
return fetchChunkRange(buffer, c.readerCache.lookupFileIdFn, chunkView.FileId, chunkView.CipherKey, chunkView.IsGzipped, int64(offset))
|
||||
}
|
||||
|
||||
n, err = c.readerCache.ReadChunkAt(buffer, chunkView.FileId, chunkView.CipherKey, chunkView.IsGzipped, int64(offset), int(chunkView.ChunkSize), chunkView.LogicOffset == 0)
|
||||
|
||||
@@ -84,7 +84,7 @@ func TestReaderAt(t *testing.T) {
|
||||
|
||||
func testReadAt(t *testing.T, readerAt *ChunkReadAt, offset int64, size int, expected int, expectedErr error) {
|
||||
data := make([]byte, size)
|
||||
n, err := readerAt.ReadAt(data, offset)
|
||||
n, err := readerAt.doReadAt(data, offset)
|
||||
|
||||
for _, d := range data {
|
||||
fmt.Printf("%x", d)
|
||||
|
||||
@@ -3,7 +3,7 @@ package redis
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"golang.org/x/exp/slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -157,8 +157,8 @@ func (store *UniversalRedisStore) ListDirectoryEntries(ctx context.Context, dirP
|
||||
}
|
||||
|
||||
// sort
|
||||
sort.Slice(members, func(i, j int) bool {
|
||||
return strings.Compare(members[i], members[j]) < 0
|
||||
slices.SortFunc(members, func(a, b string) bool {
|
||||
return strings.Compare(a, b) < 0
|
||||
})
|
||||
|
||||
// limit
|
||||
|
||||
@@ -34,7 +34,7 @@ func TestCreateAndFind(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
if err := testFiler.CreateEntry(ctx, entry1, false, false, nil); err != nil {
|
||||
if err := testFiler.CreateEntry(ctx, entry1, false, false, nil, false); err != nil {
|
||||
t.Errorf("create entry %v: %v", entry1.FullPath, err)
|
||||
return
|
||||
}
|
||||
|
||||
+14
-11
@@ -3,6 +3,7 @@ package filer
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"golang.org/x/exp/slices"
|
||||
"io"
|
||||
"math"
|
||||
"sort"
|
||||
@@ -39,11 +40,11 @@ func isSameChunks(a, b []*filer_pb.FileChunk) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
sort.Slice(a, func(i, j int) bool {
|
||||
return strings.Compare(a[i].ETag, a[j].ETag) < 0
|
||||
slices.SortFunc(a, func(i, j *filer_pb.FileChunk) bool {
|
||||
return strings.Compare(i.ETag, j.ETag) < 0
|
||||
})
|
||||
sort.Slice(b, func(i, j int) bool {
|
||||
return strings.Compare(b[i].ETag, b[j].ETag) < 0
|
||||
slices.SortFunc(b, func(i, j *filer_pb.FileChunk) bool {
|
||||
return strings.Compare(i.ETag, j.ETag) < 0
|
||||
})
|
||||
for i := 0; i < len(a); i++ {
|
||||
if a[i].ETag != b[i].ETag {
|
||||
@@ -62,7 +63,7 @@ func NewFileReader(filerClient filer_pb.FilerClient, entry *filer_pb.Entry) io.R
|
||||
|
||||
func StreamContent(masterClient wdclient.HasLookupFileIdFunction, writer io.Writer, chunks []*filer_pb.FileChunk, offset int64, size int64) error {
|
||||
|
||||
glog.V(9).Infof("start to stream content for chunks: %+v\n", chunks)
|
||||
glog.V(4).Infof("start to stream content for chunks: %+v", chunks)
|
||||
chunkViews := ViewFromChunks(masterClient.GetLookupFileIdFunction(), chunks, offset, size)
|
||||
|
||||
fileId2Url := make(map[string][]string)
|
||||
@@ -104,10 +105,12 @@ func StreamContent(masterClient wdclient.HasLookupFileIdFunction, writer io.Writ
|
||||
}
|
||||
stats.FilerRequestCounter.WithLabelValues("chunkDownload").Inc()
|
||||
}
|
||||
glog.V(4).Infof("zero [%d,%d)", offset, offset+remaining)
|
||||
err := writeZero(writer, remaining)
|
||||
if err != nil {
|
||||
return fmt.Errorf("write zero [%d,%d)", offset, offset+remaining)
|
||||
if remaining > 0 {
|
||||
glog.V(4).Infof("zero [%d,%d)", offset, offset+remaining)
|
||||
err := writeZero(writer, remaining)
|
||||
if err != nil {
|
||||
return fmt.Errorf("write zero [%d,%d)", offset, offset+remaining)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -177,8 +180,8 @@ var _ = io.ReaderAt(&ChunkStreamReader{})
|
||||
func doNewChunkStreamReader(lookupFileIdFn wdclient.LookupFileIdFunctionType, chunks []*filer_pb.FileChunk) *ChunkStreamReader {
|
||||
|
||||
chunkViews := ViewFromChunks(lookupFileIdFn, chunks, 0, math.MaxInt64)
|
||||
sort.Slice(chunkViews, func(i, j int) bool {
|
||||
return chunkViews[i].LogicOffset < chunkViews[j].LogicOffset
|
||||
slices.SortFunc(chunkViews, func(a, b *ChunkView) bool {
|
||||
return a.LogicOffset < b.LogicOffset
|
||||
})
|
||||
|
||||
var totalSize int64
|
||||
|
||||
@@ -4,10 +4,6 @@ import (
|
||||
"crypto/sha1"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/chrislusf/seaweedfs/weed/glog"
|
||||
"github.com/chrislusf/seaweedfs/weed/pb/iam_pb"
|
||||
"github.com/chrislusf/seaweedfs/weed/s3api/s3_constants"
|
||||
"github.com/chrislusf/seaweedfs/weed/s3api/s3err"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -16,6 +12,11 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/chrislusf/seaweedfs/weed/glog"
|
||||
"github.com/chrislusf/seaweedfs/weed/pb/iam_pb"
|
||||
"github.com/chrislusf/seaweedfs/weed/s3api/s3_constants"
|
||||
"github.com/chrislusf/seaweedfs/weed/s3api/s3err"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
)
|
||||
|
||||
@@ -155,6 +156,22 @@ func (iama *IamApiServer) GetUser(s3cfg *iam_pb.S3ApiConfiguration, userName str
|
||||
return resp, fmt.Errorf(iam.ErrCodeNoSuchEntityException)
|
||||
}
|
||||
|
||||
func (iama *IamApiServer) UpdateUser(s3cfg *iam_pb.S3ApiConfiguration, values url.Values) (resp UpdateUserResponse, err error) {
|
||||
userName := values.Get("UserName")
|
||||
newUserName := values.Get("NewUserName")
|
||||
if newUserName != "" {
|
||||
for _, ident := range s3cfg.Identities {
|
||||
if userName == ident.Name {
|
||||
ident.Name = newUserName
|
||||
return resp, nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return resp, nil
|
||||
}
|
||||
return resp, fmt.Errorf(iam.ErrCodeNoSuchEntityException)
|
||||
}
|
||||
|
||||
func GetPolicyDocument(policy *string) (policyDocument PolicyDocument, err error) {
|
||||
if err = json.Unmarshal([]byte(*policy), &policyDocument); err != nil {
|
||||
return PolicyDocument{}, err
|
||||
@@ -396,6 +413,13 @@ func (iama *IamApiServer) DoActions(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
changed = false
|
||||
case "UpdateUser":
|
||||
response, err = iama.UpdateUser(s3cfg, values)
|
||||
if err != nil {
|
||||
glog.Errorf("UpdateUser: %+v", err)
|
||||
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidRequest)
|
||||
return
|
||||
}
|
||||
case "DeleteUser":
|
||||
userName := values.Get("UserName")
|
||||
response, err = iama.DeleteUser(s3cfg, userName)
|
||||
|
||||
@@ -66,6 +66,11 @@ type GetUserResponse struct {
|
||||
} `xml:"GetUserResult"`
|
||||
}
|
||||
|
||||
type UpdateUserResponse struct {
|
||||
CommonResponse
|
||||
XMLName xml.Name `xml:"https://iam.amazonaws.com/doc/2010-05-08/ UpdateUserResponse"`
|
||||
}
|
||||
|
||||
type CreateAccessKeyResponse struct {
|
||||
CommonResponse
|
||||
XMLName xml.Name `xml:"https://iam.amazonaws.com/doc/2010-05-08/ CreateAccessKeyResponse"`
|
||||
|
||||
@@ -33,7 +33,7 @@ type IamS3ApiConfigure struct {
|
||||
}
|
||||
|
||||
type IamServerOption struct {
|
||||
Masters []pb.ServerAddress
|
||||
Masters map[string]pb.ServerAddress
|
||||
Filer pb.ServerAddress
|
||||
Port int
|
||||
GrpcDialOption grpc.DialOption
|
||||
|
||||
@@ -2,6 +2,10 @@ package iamapi
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
@@ -9,9 +13,6 @@ import (
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var GetS3ApiConfiguration func(s3cfg *iam_pb.S3ApiConfiguration) (err error)
|
||||
@@ -161,8 +162,20 @@ func TestGetUserPolicy(t *testing.T) {
|
||||
assert.Equal(t, http.StatusOK, response.Code)
|
||||
}
|
||||
|
||||
func TestDeleteUser(t *testing.T) {
|
||||
func TestUpdateUser(t *testing.T) {
|
||||
userName := aws.String("Test")
|
||||
newUserName := aws.String("Test-New")
|
||||
params := &iam.UpdateUserInput{NewUserName: newUserName, UserName: userName}
|
||||
req, _ := iam.New(session.New()).UpdateUserRequest(params)
|
||||
_ = req.Build()
|
||||
out := UpdateUserResponse{}
|
||||
response, err := executeRequest(req.HTTPRequest, out)
|
||||
assert.Equal(t, nil, err)
|
||||
assert.Equal(t, http.StatusOK, response.Code)
|
||||
}
|
||||
|
||||
func TestDeleteUser(t *testing.T) {
|
||||
userName := aws.String("Test-New")
|
||||
params := &iam.DeleteUserInput{UserName: userName}
|
||||
req, _ := iam.New(session.New()).DeleteUserRequest(params)
|
||||
_ = req.Build()
|
||||
|
||||
@@ -30,16 +30,19 @@ func newMemoryChunkPages(fh *FileHandle, chunkSize int64) *ChunkedDirtyPages {
|
||||
fh: fh,
|
||||
}
|
||||
|
||||
dirtyPages.uploadPipeline = page_writer.NewUploadPipeline(fh.wfs.concurrentWriters, chunkSize, dirtyPages.saveChunkedFileIntevalToStorage, fh.wfs.option.ConcurrentWriters)
|
||||
swapFileDir := fh.wfs.option.getTempFilePageDir()
|
||||
|
||||
dirtyPages.uploadPipeline = page_writer.NewUploadPipeline(fh.wfs.concurrentWriters, chunkSize,
|
||||
dirtyPages.saveChunkedFileIntevalToStorage, fh.wfs.option.ConcurrentWriters, swapFileDir)
|
||||
|
||||
return dirtyPages
|
||||
}
|
||||
|
||||
func (pages *ChunkedDirtyPages) AddPage(offset int64, data []byte) {
|
||||
func (pages *ChunkedDirtyPages) AddPage(offset int64, data []byte, isSequential bool) {
|
||||
pages.hasWrites = true
|
||||
|
||||
glog.V(4).Infof("%v memory AddPage [%d, %d)", pages.fh.fh, offset, offset+int64(len(data)))
|
||||
pages.uploadPipeline.SaveDataAt(data, offset)
|
||||
pages.uploadPipeline.SaveDataAt(data, offset, isSequential)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"github.com/chrislusf/seaweedfs/weed/glog"
|
||||
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
|
||||
"github.com/chrislusf/seaweedfs/weed/util"
|
||||
"golang.org/x/exp/slices"
|
||||
"io"
|
||||
"sort"
|
||||
"sync"
|
||||
)
|
||||
|
||||
@@ -76,8 +76,8 @@ func (fh *FileHandle) addChunks(chunks []*filer_pb.FileChunk) {
|
||||
}
|
||||
|
||||
// sort incoming chunks
|
||||
sort.Slice(chunks, func(i, j int) bool {
|
||||
return lessThan(chunks[i], chunks[j])
|
||||
slices.SortFunc(chunks, func(a, b *filer_pb.FileChunk) bool {
|
||||
return lessThan(a, b)
|
||||
})
|
||||
|
||||
glog.V(4).Infof("%s existing %d chunks adds %d more", fh.FullPath(), len(fh.entry.Chunks), len(chunks))
|
||||
@@ -88,6 +88,10 @@ func (fh *FileHandle) addChunks(chunks []*filer_pb.FileChunk) {
|
||||
fh.chunkAddLock.Unlock()
|
||||
}
|
||||
|
||||
func (fh *FileHandle) Release() {
|
||||
fh.dirtyPages.Destroy()
|
||||
}
|
||||
|
||||
func lessThan(a, b *filer_pb.FileChunk) bool {
|
||||
if a.Mtime == b.Mtime {
|
||||
return a.Fid.FileKey < b.Fid.FileKey
|
||||
|
||||
@@ -49,6 +49,7 @@ func (i *FileHandleToInode) AcquireFileHandle(wfs *WFS, inode uint64, entry *fil
|
||||
} else {
|
||||
fh.counter++
|
||||
}
|
||||
fh.entry = entry
|
||||
return fh
|
||||
}
|
||||
|
||||
@@ -61,6 +62,7 @@ func (i *FileHandleToInode) ReleaseByInode(inode uint64) {
|
||||
if fh.counter <= 0 {
|
||||
delete(i.inode2fh, inode)
|
||||
delete(i.fh2inode, fh.fh)
|
||||
fh.Release()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,6 +79,7 @@ func (i *FileHandleToInode) ReleaseByHandle(fh FileHandleId) {
|
||||
if fhHandle.counter <= 0 {
|
||||
delete(i.inode2fh, inode)
|
||||
delete(i.fh2inode, fhHandle.fh)
|
||||
fhHandle.Release()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"github.com/chrislusf/seaweedfs/weed/glog"
|
||||
"github.com/chrislusf/seaweedfs/weed/util"
|
||||
"github.com/hanwen/go-fuse/v2/fuse"
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
@@ -31,13 +30,13 @@ func NewInodeToPath(root util.FullPath) *InodeToPath {
|
||||
return t
|
||||
}
|
||||
|
||||
func (i *InodeToPath) Lookup(path util.FullPath, mode os.FileMode, isHardlink bool, possibleInode uint64, isLookup bool) uint64 {
|
||||
func (i *InodeToPath) Lookup(path util.FullPath, unixTime int64, isDirectory bool, isHardlink bool, possibleInode uint64, isLookup bool) uint64 {
|
||||
i.Lock()
|
||||
defer i.Unlock()
|
||||
inode, found := i.path2inode[path]
|
||||
if !found {
|
||||
if possibleInode == 0 {
|
||||
inode = path.AsInode(mode)
|
||||
inode = path.AsInode(unixTime)
|
||||
} else {
|
||||
inode = possibleInode
|
||||
}
|
||||
@@ -55,22 +54,22 @@ func (i *InodeToPath) Lookup(path util.FullPath, mode os.FileMode, isHardlink bo
|
||||
}
|
||||
} else {
|
||||
if !isLookup {
|
||||
i.inode2path[inode] = &InodeEntry{path, 0, mode&os.ModeDir > 0, false}
|
||||
i.inode2path[inode] = &InodeEntry{path, 0, isDirectory, false}
|
||||
} else {
|
||||
i.inode2path[inode] = &InodeEntry{path, 1, mode&os.ModeDir > 0, false}
|
||||
i.inode2path[inode] = &InodeEntry{path, 1, isDirectory, false}
|
||||
}
|
||||
}
|
||||
|
||||
return inode
|
||||
}
|
||||
|
||||
func (i *InodeToPath) AllocateInode(path util.FullPath, mode os.FileMode) uint64 {
|
||||
func (i *InodeToPath) AllocateInode(path util.FullPath, unixTime int64) uint64 {
|
||||
if path == "/" {
|
||||
return 1
|
||||
}
|
||||
i.Lock()
|
||||
defer i.Unlock()
|
||||
inode := path.AsInode(mode)
|
||||
inode := path.AsInode(unixTime)
|
||||
for _, found := i.inode2path[inode]; found; inode++ {
|
||||
_, found = i.inode2path[inode]
|
||||
}
|
||||
|
||||
+13
-12
@@ -6,10 +6,11 @@ import (
|
||||
)
|
||||
|
||||
type PageWriter struct {
|
||||
fh *FileHandle
|
||||
collection string
|
||||
replication string
|
||||
chunkSize int64
|
||||
fh *FileHandle
|
||||
collection string
|
||||
replication string
|
||||
chunkSize int64
|
||||
writerPattern *WriterPattern
|
||||
|
||||
randomWriter page_writer.DirtyPages
|
||||
}
|
||||
@@ -20,29 +21,29 @@ var (
|
||||
|
||||
func newPageWriter(fh *FileHandle, chunkSize int64) *PageWriter {
|
||||
pw := &PageWriter{
|
||||
fh: fh,
|
||||
chunkSize: chunkSize,
|
||||
randomWriter: newMemoryChunkPages(fh, chunkSize),
|
||||
// randomWriter: newTempFileDirtyPages(fh.f, chunkSize),
|
||||
fh: fh,
|
||||
chunkSize: chunkSize,
|
||||
writerPattern: NewWriterPattern(chunkSize),
|
||||
randomWriter: newMemoryChunkPages(fh, chunkSize),
|
||||
}
|
||||
return pw
|
||||
}
|
||||
|
||||
func (pw *PageWriter) AddPage(offset int64, data []byte) {
|
||||
func (pw *PageWriter) AddPage(offset int64, data []byte, isSequentail bool) {
|
||||
|
||||
glog.V(4).Infof("%v AddPage [%d, %d)", pw.fh.fh, offset, offset+int64(len(data)))
|
||||
|
||||
chunkIndex := offset / pw.chunkSize
|
||||
for i := chunkIndex; len(data) > 0; i++ {
|
||||
writeSize := min(int64(len(data)), (i+1)*pw.chunkSize-offset)
|
||||
pw.addToOneChunk(i, offset, data[:writeSize])
|
||||
pw.addToOneChunk(i, offset, data[:writeSize], isSequentail)
|
||||
offset += writeSize
|
||||
data = data[writeSize:]
|
||||
}
|
||||
}
|
||||
|
||||
func (pw *PageWriter) addToOneChunk(chunkIndex, offset int64, data []byte) {
|
||||
pw.randomWriter.AddPage(offset, data)
|
||||
func (pw *PageWriter) addToOneChunk(chunkIndex, offset int64, data []byte, isSequential bool) {
|
||||
pw.randomWriter.AddPage(offset, data, isSequential)
|
||||
}
|
||||
|
||||
func (pw *PageWriter) FlushData() error {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package page_writer
|
||||
|
||||
type DirtyPages interface {
|
||||
AddPage(offset int64, data []byte)
|
||||
AddPage(offset int64, data []byte, isSequential bool)
|
||||
FlushData() error
|
||||
ReadDirtyDataAt(data []byte, startOffset int64) (maxStop int64)
|
||||
GetStorageOptions() (collection, replication string)
|
||||
|
||||
@@ -3,10 +3,13 @@ package page_writer
|
||||
import (
|
||||
"github.com/chrislusf/seaweedfs/weed/util"
|
||||
"github.com/chrislusf/seaweedfs/weed/util/mem"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
var (
|
||||
_ = PageChunk(&MemChunk{})
|
||||
|
||||
memChunkCounter int64
|
||||
)
|
||||
|
||||
type MemChunk struct {
|
||||
@@ -17,6 +20,7 @@ type MemChunk struct {
|
||||
}
|
||||
|
||||
func NewMemChunk(logicChunkIndex LogicChunkIndex, chunkSize int64) *MemChunk {
|
||||
atomic.AddInt64(&memChunkCounter, 1)
|
||||
return &MemChunk{
|
||||
logicChunkIndex: logicChunkIndex,
|
||||
chunkSize: chunkSize,
|
||||
@@ -26,6 +30,7 @@ func NewMemChunk(logicChunkIndex LogicChunkIndex, chunkSize int64) *MemChunk {
|
||||
}
|
||||
|
||||
func (mc *MemChunk) FreeResource() {
|
||||
atomic.AddInt64(&memChunkCounter, -1)
|
||||
mem.Free(mc.buf)
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"github.com/chrislusf/seaweedfs/weed/util"
|
||||
"github.com/chrislusf/seaweedfs/weed/util/mem"
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -14,10 +15,12 @@ var (
|
||||
type ActualChunkIndex int
|
||||
|
||||
type SwapFile struct {
|
||||
dir string
|
||||
file *os.File
|
||||
logicToActualChunkIndex map[LogicChunkIndex]ActualChunkIndex
|
||||
chunkSize int64
|
||||
dir string
|
||||
file *os.File
|
||||
logicToActualChunkIndex map[LogicChunkIndex]ActualChunkIndex
|
||||
logicToActualChunkIndexLock sync.Mutex
|
||||
chunkSize int64
|
||||
freeActualChunkList []ActualChunkIndex
|
||||
}
|
||||
|
||||
type SwapFileChunk struct {
|
||||
@@ -51,9 +54,16 @@ func (sf *SwapFile) NewTempFileChunk(logicChunkIndex LogicChunkIndex) (tc *SwapF
|
||||
return nil
|
||||
}
|
||||
}
|
||||
sf.logicToActualChunkIndexLock.Lock()
|
||||
defer sf.logicToActualChunkIndexLock.Unlock()
|
||||
actualChunkIndex, found := sf.logicToActualChunkIndex[logicChunkIndex]
|
||||
if !found {
|
||||
actualChunkIndex = ActualChunkIndex(len(sf.logicToActualChunkIndex))
|
||||
if len(sf.freeActualChunkList) > 0 {
|
||||
actualChunkIndex = sf.freeActualChunkList[0]
|
||||
sf.freeActualChunkList = sf.freeActualChunkList[1:]
|
||||
} else {
|
||||
actualChunkIndex = ActualChunkIndex(len(sf.logicToActualChunkIndex))
|
||||
}
|
||||
sf.logicToActualChunkIndex[logicChunkIndex] = actualChunkIndex
|
||||
}
|
||||
|
||||
@@ -66,6 +76,11 @@ func (sf *SwapFile) NewTempFileChunk(logicChunkIndex LogicChunkIndex) (tc *SwapF
|
||||
}
|
||||
|
||||
func (sc *SwapFileChunk) FreeResource() {
|
||||
sc.swapfile.logicToActualChunkIndexLock.Lock()
|
||||
defer sc.swapfile.logicToActualChunkIndexLock.Unlock()
|
||||
|
||||
sc.swapfile.freeActualChunkList = append(sc.swapfile.freeActualChunkList, sc.actualChunkIndex)
|
||||
delete(sc.swapfile.logicToActualChunkIndex, sc.logicChunkIndex)
|
||||
}
|
||||
|
||||
func (sc *SwapFileChunk) WriteDataAt(src []byte, offset int64) (n int) {
|
||||
|
||||
@@ -24,7 +24,8 @@ type UploadPipeline struct {
|
||||
saveToStorageFn SaveToStorageFunc
|
||||
activeReadChunks map[LogicChunkIndex]int
|
||||
activeReadChunksLock sync.Mutex
|
||||
bufferChunkLimit int
|
||||
writableChunkLimit int
|
||||
swapFile *SwapFile
|
||||
}
|
||||
|
||||
type SealedChunk struct {
|
||||
@@ -40,30 +41,30 @@ func (sc *SealedChunk) FreeReference(messageOnFree string) {
|
||||
}
|
||||
}
|
||||
|
||||
func NewUploadPipeline(writers *util.LimitedConcurrentExecutor, chunkSize int64, saveToStorageFn SaveToStorageFunc, bufferChunkLimit int) *UploadPipeline {
|
||||
func NewUploadPipeline(writers *util.LimitedConcurrentExecutor, chunkSize int64, saveToStorageFn SaveToStorageFunc, bufferChunkLimit int, swapFileDir string) *UploadPipeline {
|
||||
return &UploadPipeline{
|
||||
ChunkSize: chunkSize,
|
||||
writableChunks: make(map[LogicChunkIndex]PageChunk),
|
||||
sealedChunks: make(map[LogicChunkIndex]*SealedChunk),
|
||||
uploaders: writers,
|
||||
uploaderCountCond: sync.NewCond(&sync.Mutex{}),
|
||||
saveToStorageFn: saveToStorageFn,
|
||||
activeReadChunks: make(map[LogicChunkIndex]int),
|
||||
bufferChunkLimit: bufferChunkLimit,
|
||||
ChunkSize: chunkSize,
|
||||
writableChunks: make(map[LogicChunkIndex]PageChunk),
|
||||
sealedChunks: make(map[LogicChunkIndex]*SealedChunk),
|
||||
uploaders: writers,
|
||||
uploaderCountCond: sync.NewCond(&sync.Mutex{}),
|
||||
saveToStorageFn: saveToStorageFn,
|
||||
activeReadChunks: make(map[LogicChunkIndex]int),
|
||||
writableChunkLimit: bufferChunkLimit,
|
||||
swapFile: NewSwapFile(swapFileDir, chunkSize),
|
||||
}
|
||||
}
|
||||
|
||||
func (up *UploadPipeline) SaveDataAt(p []byte, off int64) (n int) {
|
||||
func (up *UploadPipeline) SaveDataAt(p []byte, off int64, isSequential bool) (n int) {
|
||||
up.writableChunksLock.Lock()
|
||||
defer up.writableChunksLock.Unlock()
|
||||
|
||||
logicChunkIndex := LogicChunkIndex(off / up.ChunkSize)
|
||||
|
||||
memChunk, found := up.writableChunks[logicChunkIndex]
|
||||
pageChunk, found := up.writableChunks[logicChunkIndex]
|
||||
if !found {
|
||||
if len(up.writableChunks) < up.bufferChunkLimit {
|
||||
memChunk = NewMemChunk(logicChunkIndex, up.ChunkSize)
|
||||
} else {
|
||||
if len(up.writableChunks) > up.writableChunkLimit {
|
||||
// if current file chunks is over the per file buffer count limit
|
||||
fullestChunkIndex, fullness := LogicChunkIndex(-1), int64(0)
|
||||
for lci, mc := range up.writableChunks {
|
||||
chunkFullness := mc.WrittenSize()
|
||||
@@ -74,13 +75,19 @@ func (up *UploadPipeline) SaveDataAt(p []byte, off int64) (n int) {
|
||||
}
|
||||
up.moveToSealed(up.writableChunks[fullestChunkIndex], fullestChunkIndex)
|
||||
delete(up.writableChunks, fullestChunkIndex)
|
||||
fmt.Printf("flush chunk %d with %d bytes written", logicChunkIndex, fullness)
|
||||
memChunk = NewMemChunk(logicChunkIndex, up.ChunkSize)
|
||||
// fmt.Printf("flush chunk %d with %d bytes written\n", logicChunkIndex, fullness)
|
||||
}
|
||||
up.writableChunks[logicChunkIndex] = memChunk
|
||||
if isSequential &&
|
||||
len(up.writableChunks) < up.writableChunkLimit &&
|
||||
atomic.LoadInt64(&memChunkCounter) < 4*int64(up.writableChunkLimit) {
|
||||
pageChunk = NewMemChunk(logicChunkIndex, up.ChunkSize)
|
||||
} else {
|
||||
pageChunk = up.swapFile.NewTempFileChunk(logicChunkIndex)
|
||||
}
|
||||
up.writableChunks[logicChunkIndex] = pageChunk
|
||||
}
|
||||
n = memChunk.WriteDataAt(p, off)
|
||||
up.maybeMoveToSealed(memChunk, logicChunkIndex)
|
||||
n = pageChunk.WriteDataAt(p, off)
|
||||
up.maybeMoveToSealed(pageChunk, logicChunkIndex)
|
||||
|
||||
return
|
||||
}
|
||||
@@ -179,4 +186,11 @@ func (up *UploadPipeline) moveToSealed(memChunk PageChunk, logicChunkIndex Logic
|
||||
}
|
||||
|
||||
func (up *UploadPipeline) Shutdown() {
|
||||
up.swapFile.FreeResource()
|
||||
|
||||
up.sealedChunksLock.Lock()
|
||||
defer up.sealedChunksLock.Unlock()
|
||||
for logicChunkIndex, sealedChunk := range up.sealedChunks {
|
||||
sealedChunk.FreeReference(fmt.Sprintf("%s uploadpipeline shutdown chunk %d", up.filepath, logicChunkIndex))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
|
||||
func TestUploadPipeline(t *testing.T) {
|
||||
|
||||
uploadPipeline := NewUploadPipeline(nil, 2*1024*1024, nil, 16)
|
||||
uploadPipeline := NewUploadPipeline(nil, 2*1024*1024, nil, 16, "")
|
||||
|
||||
writeRange(uploadPipeline, 0, 131072)
|
||||
writeRange(uploadPipeline, 131072, 262144)
|
||||
@@ -31,7 +31,7 @@ func writeRange(uploadPipeline *UploadPipeline, startOff, stopOff int64) {
|
||||
p := make([]byte, 4)
|
||||
for i := startOff / 4; i < stopOff/4; i += 4 {
|
||||
util.Uint32toBytes(p, uint32(i))
|
||||
uploadPipeline.SaveDataAt(p, i)
|
||||
uploadPipeline.SaveDataAt(p, i, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package mount
|
||||
|
||||
type WriterPattern struct {
|
||||
isStreaming bool
|
||||
lastWriteOffset int64
|
||||
chunkSize int64
|
||||
}
|
||||
|
||||
// For streaming write: only cache the first chunk
|
||||
// For random write: fall back to temp file approach
|
||||
// writes can only change from streaming mode to non-streaming mode
|
||||
|
||||
func NewWriterPattern(chunkSize int64) *WriterPattern {
|
||||
return &WriterPattern{
|
||||
isStreaming: true,
|
||||
lastWriteOffset: -1,
|
||||
chunkSize: chunkSize,
|
||||
}
|
||||
}
|
||||
|
||||
func (rp *WriterPattern) MonitorWriteAt(offset int64, size int) {
|
||||
if rp.lastWriteOffset > offset {
|
||||
rp.isStreaming = false
|
||||
}
|
||||
if rp.lastWriteOffset == -1 {
|
||||
if offset != 0 {
|
||||
rp.isStreaming = false
|
||||
}
|
||||
}
|
||||
rp.lastWriteOffset = offset
|
||||
}
|
||||
|
||||
func (rp *WriterPattern) IsStreamingMode() bool {
|
||||
return rp.isStreaming
|
||||
}
|
||||
|
||||
func (rp *WriterPattern) IsRandomMode() bool {
|
||||
return !rp.isStreaming
|
||||
}
|
||||
|
||||
func (rp *WriterPattern) Reset() {
|
||||
rp.isStreaming = true
|
||||
rp.lastWriteOffset = -1
|
||||
}
|
||||
+15
-2
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/chrislusf/seaweedfs/weed/mount/meta_cache"
|
||||
"github.com/chrislusf/seaweedfs/weed/pb"
|
||||
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
|
||||
"github.com/chrislusf/seaweedfs/weed/pb/mount_pb"
|
||||
"github.com/chrislusf/seaweedfs/weed/storage/types"
|
||||
"github.com/chrislusf/seaweedfs/weed/util"
|
||||
"github.com/chrislusf/seaweedfs/weed/util/chunk_cache"
|
||||
@@ -16,6 +17,7 @@ import (
|
||||
"math/rand"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/hanwen/go-fuse/v2/fs"
|
||||
@@ -50,12 +52,15 @@ type Option struct {
|
||||
Cipher bool // whether encrypt data on volume server
|
||||
UidGidMapper *meta_cache.UidGidMapper
|
||||
|
||||
uniqueCacheDir string
|
||||
uniqueCacheDir string
|
||||
uniqueCacheTempPageDir string
|
||||
}
|
||||
|
||||
type WFS struct {
|
||||
// https://dl.acm.org/doi/fullHtml/10.1145/3310148
|
||||
// follow https://github.com/hanwen/go-fuse/blob/master/fuse/api.go
|
||||
fuse.RawFileSystem
|
||||
mount_pb.UnimplementedSeaweedMountServer
|
||||
fs.Inode
|
||||
option *Option
|
||||
metaCache *meta_cache.MetaCache
|
||||
@@ -126,6 +131,9 @@ func (wfs *WFS) maybeReadEntry(inode uint64) (path util.FullPath, fh *FileHandle
|
||||
}
|
||||
var found bool
|
||||
if fh, found = wfs.fhmap.FindFileHandle(inode); found {
|
||||
if fh.entry.Attributes == nil {
|
||||
fh.entry.Attributes = &filer_pb.FuseAttributes{}
|
||||
}
|
||||
return path, fh, fh.entry, fuse.OK
|
||||
}
|
||||
entry, status = wfs.maybeLoadEntry(path)
|
||||
@@ -177,7 +185,12 @@ func (wfs *WFS) getCurrentFiler() pb.ServerAddress {
|
||||
func (option *Option) setupUniqueCacheDirectory() {
|
||||
cacheUniqueId := util.Md5String([]byte(option.MountDirectory + string(option.FilerAddresses[0]) + option.FilerMountRootPath + util.Version()))[0:8]
|
||||
option.uniqueCacheDir = path.Join(option.CacheDir, cacheUniqueId)
|
||||
os.MkdirAll(option.uniqueCacheDir, os.FileMode(0777)&^option.Umask)
|
||||
option.uniqueCacheTempPageDir = filepath.Join(option.uniqueCacheDir, "swap")
|
||||
os.MkdirAll(option.uniqueCacheTempPageDir, os.FileMode(0777)&^option.Umask)
|
||||
}
|
||||
|
||||
func (option *Option) getTempFilePageDir() string {
|
||||
return option.uniqueCacheTempPageDir
|
||||
}
|
||||
|
||||
func (option *Option) getUniqueCacheDir() string {
|
||||
|
||||
@@ -79,25 +79,33 @@ func (wfs *WFS) SetAttr(cancel <-chan struct{}, input *fuse.SetAttrIn, out *fuse
|
||||
if mode, ok := input.GetMode(); ok {
|
||||
// glog.V(4).Infof("setAttr mode %o", mode)
|
||||
entry.Attributes.FileMode = chmod(entry.Attributes.FileMode, mode)
|
||||
if input.NodeId == 1 {
|
||||
wfs.option.MountMode = os.FileMode(chmod(uint32(wfs.option.MountMode), mode))
|
||||
}
|
||||
}
|
||||
|
||||
if uid, ok := input.GetUID(); ok {
|
||||
entry.Attributes.Uid = uid
|
||||
if input.NodeId == 1 {
|
||||
wfs.option.MountUid = uid
|
||||
}
|
||||
}
|
||||
|
||||
if gid, ok := input.GetGID(); ok {
|
||||
entry.Attributes.Gid = gid
|
||||
}
|
||||
|
||||
if mtime, ok := input.GetMTime(); ok {
|
||||
entry.Attributes.Mtime = mtime.Unix()
|
||||
if input.NodeId == 1 {
|
||||
wfs.option.MountGid = gid
|
||||
}
|
||||
}
|
||||
|
||||
if atime, ok := input.GetATime(); ok {
|
||||
entry.Attributes.Mtime = atime.Unix()
|
||||
}
|
||||
|
||||
entry.Attributes.Mtime = time.Now().Unix()
|
||||
if mtime, ok := input.GetMTime(); ok {
|
||||
entry.Attributes.Mtime = mtime.Unix()
|
||||
}
|
||||
|
||||
out.AttrValid = 1
|
||||
wfs.setAttrByPbEntry(&out.Attr, input.NodeId, entry)
|
||||
|
||||
|
||||
@@ -53,9 +53,9 @@ func (wfs *WFS) Lookup(cancel <-chan struct{}, header *fuse.InHeader, name strin
|
||||
return fuse.ENOENT
|
||||
}
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(fullFilePath, localEntry.Mode, len(localEntry.HardLinkId) > 0, localEntry.Inode, true)
|
||||
inode := wfs.inodeToPath.Lookup(fullFilePath, localEntry.Crtime.Unix(), localEntry.IsDirectory(), len(localEntry.HardLinkId) > 0, localEntry.Inode, true)
|
||||
|
||||
if fh, found := wfs.fhmap.FindFileHandle(inode); found {
|
||||
if fh, found := wfs.fhmap.FindFileHandle(inode); found && fh.entry != nil {
|
||||
glog.V(4).Infof("lookup opened file %s size %d", dirPath.Child(localEntry.Name()), filer.FileSize(fh.entry))
|
||||
localEntry = filer.FromPbEntry(string(dirPath), fh.entry)
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ func (wfs *WFS) Mkdir(cancel <-chan struct{}, in *fuse.MkdirIn, name string, out
|
||||
return fuse.EIO
|
||||
}
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(entryFullPath, os.ModeDir, false, 0, true)
|
||||
inode := wfs.inodeToPath.Lookup(entryFullPath, newEntry.Attributes.Crtime, true, false, 0, true)
|
||||
|
||||
wfs.outputPbEntry(out, inode, newEntry)
|
||||
|
||||
|
||||
@@ -162,14 +162,14 @@ func (wfs *WFS) doReadDirectory(input *fuse.ReadIn, out *fuse.DirEntryList, isPl
|
||||
dirEntry.Name = entry.Name()
|
||||
dirEntry.Mode = toSyscallMode(entry.Mode)
|
||||
if !isPlusMode {
|
||||
inode := wfs.inodeToPath.Lookup(dirPath.Child(dirEntry.Name), entry.Mode, len(entry.HardLinkId) > 0, entry.Inode, false)
|
||||
inode := wfs.inodeToPath.Lookup(dirPath.Child(dirEntry.Name), entry.Crtime.Unix(), entry.IsDirectory(), len(entry.HardLinkId) > 0, entry.Inode, false)
|
||||
dirEntry.Ino = inode
|
||||
if !out.AddDirEntry(dirEntry) {
|
||||
isEarlyTerminated = true
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
inode := wfs.inodeToPath.Lookup(dirPath.Child(dirEntry.Name), entry.Mode, len(entry.HardLinkId) > 0, entry.Inode, true)
|
||||
inode := wfs.inodeToPath.Lookup(dirPath.Child(dirEntry.Name), entry.Crtime.Unix(), entry.IsDirectory(), len(entry.HardLinkId) > 0, entry.Inode, true)
|
||||
dirEntry.Ino = inode
|
||||
entryOut := out.AddDirLookupEntry(dirEntry)
|
||||
if entryOut == nil {
|
||||
|
||||
@@ -61,12 +61,13 @@ import (
|
||||
* @param fi file information
|
||||
*/
|
||||
func (wfs *WFS) Open(cancel <-chan struct{}, in *fuse.OpenIn, out *fuse.OpenOut) (status fuse.Status) {
|
||||
fileHandle, code := wfs.AcquireHandle(in.NodeId, in.Uid, in.Gid)
|
||||
if code == fuse.OK {
|
||||
var fileHandle *FileHandle
|
||||
fileHandle, status = wfs.AcquireHandle(in.NodeId, in.Uid, in.Gid)
|
||||
if status == fuse.OK {
|
||||
out.Fh = uint64(fileHandle.fh)
|
||||
// TODO https://github.com/libfuse/libfuse/blob/master/include/fuse_common.h#L64
|
||||
}
|
||||
return code
|
||||
return status
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -51,14 +51,15 @@ func (wfs *WFS) Mknod(cancel <-chan struct{}, in *fuse.MknodIn, name string, out
|
||||
|
||||
entryFullPath := dirFullPath.Child(name)
|
||||
fileMode := toOsFileMode(in.Mode)
|
||||
inode := wfs.inodeToPath.AllocateInode(entryFullPath, fileMode)
|
||||
now := time.Now().Unix()
|
||||
inode := wfs.inodeToPath.AllocateInode(entryFullPath, now)
|
||||
|
||||
newEntry := &filer_pb.Entry{
|
||||
Name: name,
|
||||
IsDirectory: false,
|
||||
Attributes: &filer_pb.FuseAttributes{
|
||||
Mtime: time.Now().Unix(),
|
||||
Crtime: time.Now().Unix(),
|
||||
Mtime: now,
|
||||
Crtime: now,
|
||||
FileMode: uint32(fileMode),
|
||||
Uid: in.Uid,
|
||||
Gid: in.Gid,
|
||||
@@ -76,9 +77,10 @@ func (wfs *WFS) Mknod(cancel <-chan struct{}, in *fuse.MknodIn, name string, out
|
||||
defer wfs.mapPbIdFromFilerToLocal(newEntry)
|
||||
|
||||
request := &filer_pb.CreateEntryRequest{
|
||||
Directory: string(dirFullPath),
|
||||
Entry: newEntry,
|
||||
Signatures: []int32{wfs.signature},
|
||||
Directory: string(dirFullPath),
|
||||
Entry: newEntry,
|
||||
Signatures: []int32{wfs.signature},
|
||||
SkipCheckParentDirectory: true,
|
||||
}
|
||||
|
||||
glog.V(1).Infof("mknod: %v", request)
|
||||
@@ -101,7 +103,7 @@ func (wfs *WFS) Mknod(cancel <-chan struct{}, in *fuse.MknodIn, name string, out
|
||||
}
|
||||
|
||||
// this is to increase nlookup counter
|
||||
inode = wfs.inodeToPath.Lookup(entryFullPath, fileMode, false, inode, true)
|
||||
inode = wfs.inodeToPath.Lookup(entryFullPath, newEntry.Attributes.Crtime, false, false, inode, true)
|
||||
|
||||
wfs.outputPbEntry(out, inode, newEntry)
|
||||
|
||||
|
||||
@@ -140,9 +140,10 @@ func (wfs *WFS) doFlush(fh *FileHandle, uid, gid uint32) fuse.Status {
|
||||
}
|
||||
|
||||
request := &filer_pb.CreateEntryRequest{
|
||||
Directory: string(dir),
|
||||
Entry: entry,
|
||||
Signatures: []int32{wfs.signature},
|
||||
Directory: string(dir),
|
||||
Entry: entry,
|
||||
Signatures: []int32{wfs.signature},
|
||||
SkipCheckParentDirectory: true,
|
||||
}
|
||||
|
||||
glog.V(4).Infof("%s set chunks: %v", fileFullPath, len(entry.Chunks))
|
||||
|
||||
@@ -43,6 +43,8 @@ func (wfs *WFS) Write(cancel <-chan struct{}, in *fuse.WriteIn, data []byte) (wr
|
||||
return 0, fuse.ENOENT
|
||||
}
|
||||
|
||||
fh.dirtyPages.writerPattern.MonitorWriteAt(int64(in.Offset), int(in.Size))
|
||||
|
||||
fh.Lock()
|
||||
defer fh.Unlock()
|
||||
|
||||
@@ -56,7 +58,7 @@ func (wfs *WFS) Write(cancel <-chan struct{}, in *fuse.WriteIn, data []byte) (wr
|
||||
entry.Attributes.FileSize = uint64(max(offset+int64(len(data)), int64(entry.Attributes.FileSize)))
|
||||
// glog.V(4).Infof("%v write [%d,%d) %d", fh.f.fullpath(), req.Offset, req.Offset+int64(len(req.Data)), len(req.Data))
|
||||
|
||||
fh.dirtyPages.AddPage(offset, data)
|
||||
fh.dirtyPages.AddPage(offset, data, fh.dirtyPages.writerPattern.IsStreamingMode())
|
||||
|
||||
written = uint32(len(data))
|
||||
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package mount
|
||||
|
||||
import "github.com/hanwen/go-fuse/v2/fuse"
|
||||
import (
|
||||
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
|
||||
"github.com/hanwen/go-fuse/v2/fuse"
|
||||
)
|
||||
|
||||
func (wfs *WFS) AcquireHandle(inode uint64, uid, gid uint32) (fileHandle *FileHandle, code fuse.Status) {
|
||||
_, _, entry, status := wfs.maybeReadEntry(inode)
|
||||
func (wfs *WFS) AcquireHandle(inode uint64, uid, gid uint32) (fileHandle *FileHandle, status fuse.Status) {
|
||||
var entry *filer_pb.Entry
|
||||
_, _, entry, status = wfs.maybeReadEntry(inode)
|
||||
if status == fuse.OK {
|
||||
fileHandle = wfs.fhmap.AcquireFileHandle(wfs, inode, entry)
|
||||
fileHandle.entry = entry
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package mount
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/chrislusf/seaweedfs/weed/glog"
|
||||
"github.com/chrislusf/seaweedfs/weed/pb/mount_pb"
|
||||
)
|
||||
|
||||
func (wfs *WFS) Configure(ctx context.Context, request *mount_pb.ConfigureRequest) (*mount_pb.ConfigureResponse, error) {
|
||||
if wfs.option.Collection == "" {
|
||||
return nil, fmt.Errorf("mount quota only works when mounted to a new folder with a collection")
|
||||
}
|
||||
glog.V(0).Infof("quota changed from %d to %d", wfs.option.Quota, request.CollectionCapacity)
|
||||
wfs.option.Quota = request.GetCollectionCapacity()
|
||||
return &mount_pb.ConfigureResponse{}, nil
|
||||
}
|
||||
@@ -102,7 +102,7 @@ func (wfs *WFS) Link(cancel <-chan struct{}, in *fuse.LinkIn, name string, out *
|
||||
return fuse.EIO
|
||||
}
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(newEntryPath, oldEntry.FileMode(), true, oldEntry.Attributes.Inode, true)
|
||||
inode := wfs.inodeToPath.Lookup(newEntryPath, oldEntry.Attributes.Crtime, oldEntry.IsDirectory, true, oldEntry.Attributes.Inode, true)
|
||||
|
||||
wfs.outputPbEntry(out, inode, request.Entry)
|
||||
|
||||
|
||||
@@ -10,12 +10,14 @@ import (
|
||||
|
||||
func (wfs *WFS) loopCheckQuota() {
|
||||
|
||||
if wfs.option.Quota <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
|
||||
time.Sleep(61 * time.Second)
|
||||
|
||||
if wfs.option.Quota <= 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
err := wfs.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error {
|
||||
|
||||
request := &filer_pb.StatisticsRequest{
|
||||
@@ -47,7 +49,6 @@ func (wfs *WFS) loopCheckQuota() {
|
||||
glog.Warningf("read quota usage: %v", err)
|
||||
}
|
||||
|
||||
time.Sleep(61 * time.Second)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ func (wfs *WFS) Symlink(cancel <-chan struct{}, header *fuse.InHeader, target st
|
||||
return fuse.EIO
|
||||
}
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(entryFullPath, os.ModeSymlink, false, 0, true)
|
||||
inode := wfs.inodeToPath.Lookup(entryFullPath, request.Entry.Attributes.Crtime, false, false, 0, true)
|
||||
|
||||
wfs.outputPbEntry(out, inode, request.Entry)
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"io"
|
||||
"mime"
|
||||
"mime/multipart"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/textproto"
|
||||
"path/filepath"
|
||||
@@ -65,6 +66,10 @@ var (
|
||||
|
||||
func init() {
|
||||
HttpClient = &http.Client{Transport: &http.Transport{
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 10 * time.Second,
|
||||
KeepAlive: 10 * time.Second,
|
||||
}).DialContext,
|
||||
MaxIdleConns: 1024,
|
||||
MaxIdleConnsPerHost: 1024,
|
||||
}}
|
||||
@@ -261,6 +266,7 @@ func upload_content(fillBufferFunction func(w io.Writer) error, originalDataSize
|
||||
if post_err != nil {
|
||||
if strings.Contains(post_err.Error(), "connection reset by peer") ||
|
||||
strings.Contains(post_err.Error(), "use of closed network connection") {
|
||||
glog.V(1).Infof("repeat error upload request %s: %v", option.UploadUrl, postErr)
|
||||
resp, post_err = HttpClient.Do(req)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ gen:
|
||||
protoc filer.proto --go_out=./filer_pb --go-grpc_out=./filer_pb --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative
|
||||
protoc remote.proto --go_out=./remote_pb --go-grpc_out=./remote_pb --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative
|
||||
protoc iam.proto --go_out=./iam_pb --go-grpc_out=./iam_pb --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative
|
||||
protoc mount.proto --go_out=./mount_pb --go-grpc_out=./mount_pb --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative
|
||||
protoc messaging.proto --go_out=./messaging_pb --go-grpc_out=./messaging_pb --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative
|
||||
# protoc filer.proto --java_out=../../other/java/client/src/main/java
|
||||
cp filer.proto ../../other/java/client/src/main/proto
|
||||
|
||||
@@ -48,6 +48,9 @@ service SeaweedFiler {
|
||||
rpc Statistics (StatisticsRequest) returns (StatisticsResponse) {
|
||||
}
|
||||
|
||||
rpc Ping (PingRequest) returns (PingResponse) {
|
||||
}
|
||||
|
||||
rpc GetFilerConfiguration (GetFilerConfigurationRequest) returns (GetFilerConfigurationResponse) {
|
||||
}
|
||||
|
||||
@@ -181,6 +184,7 @@ message CreateEntryRequest {
|
||||
bool o_excl = 3;
|
||||
bool is_from_other_cluster = 4;
|
||||
repeated int32 signatures = 5;
|
||||
bool skip_check_parent_directory = 6;
|
||||
}
|
||||
|
||||
message CreateEntryResponse {
|
||||
@@ -310,6 +314,16 @@ message StatisticsResponse {
|
||||
uint64 file_count = 6;
|
||||
}
|
||||
|
||||
message PingRequest {
|
||||
string target = 1; // default to ping itself
|
||||
string target_type = 2;
|
||||
}
|
||||
message PingResponse {
|
||||
int64 start_time_ns = 1;
|
||||
int64 remote_time_ns = 2;
|
||||
int64 stop_time_ns = 3;
|
||||
}
|
||||
|
||||
message GetFilerConfigurationRequest {
|
||||
}
|
||||
message GetFilerConfigurationResponse {
|
||||
|
||||
+727
-553
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,7 @@ type SeaweedFilerClient interface {
|
||||
CollectionList(ctx context.Context, in *CollectionListRequest, opts ...grpc.CallOption) (*CollectionListResponse, error)
|
||||
DeleteCollection(ctx context.Context, in *DeleteCollectionRequest, opts ...grpc.CallOption) (*DeleteCollectionResponse, error)
|
||||
Statistics(ctx context.Context, in *StatisticsRequest, opts ...grpc.CallOption) (*StatisticsResponse, error)
|
||||
Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error)
|
||||
GetFilerConfiguration(ctx context.Context, in *GetFilerConfigurationRequest, opts ...grpc.CallOption) (*GetFilerConfigurationResponse, error)
|
||||
SubscribeMetadata(ctx context.Context, in *SubscribeMetadataRequest, opts ...grpc.CallOption) (SeaweedFiler_SubscribeMetadataClient, error)
|
||||
SubscribeLocalMetadata(ctx context.Context, in *SubscribeMetadataRequest, opts ...grpc.CallOption) (SeaweedFiler_SubscribeLocalMetadataClient, error)
|
||||
@@ -212,6 +213,15 @@ func (c *seaweedFilerClient) Statistics(ctx context.Context, in *StatisticsReque
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *seaweedFilerClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) {
|
||||
out := new(PingResponse)
|
||||
err := c.cc.Invoke(ctx, "/filer_pb.SeaweedFiler/Ping", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *seaweedFilerClient) GetFilerConfiguration(ctx context.Context, in *GetFilerConfigurationRequest, opts ...grpc.CallOption) (*GetFilerConfigurationResponse, error) {
|
||||
out := new(GetFilerConfigurationResponse)
|
||||
err := c.cc.Invoke(ctx, "/filer_pb.SeaweedFiler/GetFilerConfiguration", in, out, opts...)
|
||||
@@ -369,6 +379,7 @@ type SeaweedFilerServer interface {
|
||||
CollectionList(context.Context, *CollectionListRequest) (*CollectionListResponse, error)
|
||||
DeleteCollection(context.Context, *DeleteCollectionRequest) (*DeleteCollectionResponse, error)
|
||||
Statistics(context.Context, *StatisticsRequest) (*StatisticsResponse, error)
|
||||
Ping(context.Context, *PingRequest) (*PingResponse, error)
|
||||
GetFilerConfiguration(context.Context, *GetFilerConfigurationRequest) (*GetFilerConfigurationResponse, error)
|
||||
SubscribeMetadata(*SubscribeMetadataRequest, SeaweedFiler_SubscribeMetadataServer) error
|
||||
SubscribeLocalMetadata(*SubscribeMetadataRequest, SeaweedFiler_SubscribeLocalMetadataServer) error
|
||||
@@ -423,6 +434,9 @@ func (UnimplementedSeaweedFilerServer) DeleteCollection(context.Context, *Delete
|
||||
func (UnimplementedSeaweedFilerServer) Statistics(context.Context, *StatisticsRequest) (*StatisticsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Statistics not implemented")
|
||||
}
|
||||
func (UnimplementedSeaweedFilerServer) Ping(context.Context, *PingRequest) (*PingResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented")
|
||||
}
|
||||
func (UnimplementedSeaweedFilerServer) GetFilerConfiguration(context.Context, *GetFilerConfigurationRequest) (*GetFilerConfigurationResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetFilerConfiguration not implemented")
|
||||
}
|
||||
@@ -700,6 +714,24 @@ func _SeaweedFiler_Statistics_Handler(srv interface{}, ctx context.Context, dec
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SeaweedFiler_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(PingRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SeaweedFilerServer).Ping(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/filer_pb.SeaweedFiler/Ping",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SeaweedFilerServer).Ping(ctx, req.(*PingRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SeaweedFiler_GetFilerConfiguration_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetFilerConfigurationRequest)
|
||||
if err := dec(in); err != nil {
|
||||
@@ -909,6 +941,10 @@ var SeaweedFiler_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "Statistics",
|
||||
Handler: _SeaweedFiler_Statistics_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Ping",
|
||||
Handler: _SeaweedFiler_Ping_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetFilerConfiguration",
|
||||
Handler: _SeaweedFiler_GetFilerConfiguration_Handler,
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/chrislusf/seaweedfs/weed/glog"
|
||||
"github.com/chrislusf/seaweedfs/weed/pb/volume_server_pb"
|
||||
"github.com/chrislusf/seaweedfs/weed/util"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
@@ -206,7 +207,15 @@ func WithMasterClient(streamingMode bool, master ServerAddress, grpcDialOption g
|
||||
|
||||
}
|
||||
|
||||
func WithOneOfGrpcMasterClients(streamingMode bool, masterGrpcAddresses []ServerAddress, grpcDialOption grpc.DialOption, fn func(client master_pb.SeaweedClient) error) (err error) {
|
||||
func WithVolumeServerClient(streamingMode bool, volumeServer ServerAddress, grpcDialOption grpc.DialOption, fn func(client volume_server_pb.VolumeServerClient) error) error {
|
||||
return WithGrpcClient(streamingMode, func(grpcConnection *grpc.ClientConn) error {
|
||||
client := volume_server_pb.NewVolumeServerClient(grpcConnection)
|
||||
return fn(client)
|
||||
}, volumeServer.ToGrpcAddress(), grpcDialOption)
|
||||
|
||||
}
|
||||
|
||||
func WithOneOfGrpcMasterClients(streamingMode bool, masterGrpcAddresses map[string]ServerAddress, grpcDialOption grpc.DialOption, fn func(client master_pb.SeaweedClient) error) (err error) {
|
||||
|
||||
for _, masterGrpcAddress := range masterGrpcAddresses {
|
||||
err = WithGrpcClient(streamingMode, func(grpcConnection *grpc.ClientConn) error {
|
||||
|
||||
+46
-1
@@ -35,7 +35,14 @@ service Seaweed {
|
||||
}
|
||||
rpc ReleaseAdminToken (ReleaseAdminTokenRequest) returns (ReleaseAdminTokenResponse) {
|
||||
}
|
||||
|
||||
rpc Ping (PingRequest) returns (PingResponse) {
|
||||
}
|
||||
rpc RaftListClusterServers (RaftListClusterServersRequest) returns (RaftListClusterServersResponse) {
|
||||
}
|
||||
rpc RaftAddServer (RaftAddServerRequest) returns (RaftAddServerResponse) {
|
||||
}
|
||||
rpc RaftRemoveServer (RaftRemoveServerRequest) returns (RaftRemoveServerResponse) {
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
@@ -140,6 +147,8 @@ message VolumeLocation {
|
||||
string leader = 5; // optional when leader is not itself
|
||||
string data_center = 6; // optional when DataCenter is in use
|
||||
uint32 grpc_port = 7;
|
||||
repeated uint32 new_ec_vids = 8;
|
||||
repeated uint32 deleted_ec_vids = 9;
|
||||
}
|
||||
|
||||
message ClusterNodeUpdate {
|
||||
@@ -328,3 +337,39 @@ message ReleaseAdminTokenRequest {
|
||||
}
|
||||
message ReleaseAdminTokenResponse {
|
||||
}
|
||||
|
||||
message PingRequest {
|
||||
string target = 1; // default to ping itself
|
||||
string target_type = 2;
|
||||
}
|
||||
message PingResponse {
|
||||
int64 start_time_ns = 1;
|
||||
int64 remote_time_ns = 2;
|
||||
int64 stop_time_ns = 3;
|
||||
}
|
||||
|
||||
message RaftAddServerRequest {
|
||||
string id = 1;
|
||||
string address = 2;
|
||||
bool voter = 3;
|
||||
}
|
||||
message RaftAddServerResponse {
|
||||
}
|
||||
|
||||
message RaftRemoveServerRequest {
|
||||
string id = 1;
|
||||
bool force = 2;
|
||||
}
|
||||
message RaftRemoveServerResponse {
|
||||
}
|
||||
|
||||
message RaftListClusterServersRequest {
|
||||
}
|
||||
message RaftListClusterServersResponse {
|
||||
message ClusterServers {
|
||||
string id = 1;
|
||||
string address = 2;
|
||||
string suffrage = 3; //
|
||||
}
|
||||
repeated ClusterServers cluster_servers = 1;
|
||||
}
|
||||
|
||||
+1135
-465
File diff suppressed because it is too large
Load Diff
@@ -32,6 +32,10 @@ type SeaweedClient interface {
|
||||
ListClusterNodes(ctx context.Context, in *ListClusterNodesRequest, opts ...grpc.CallOption) (*ListClusterNodesResponse, error)
|
||||
LeaseAdminToken(ctx context.Context, in *LeaseAdminTokenRequest, opts ...grpc.CallOption) (*LeaseAdminTokenResponse, error)
|
||||
ReleaseAdminToken(ctx context.Context, in *ReleaseAdminTokenRequest, opts ...grpc.CallOption) (*ReleaseAdminTokenResponse, error)
|
||||
Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error)
|
||||
RaftListClusterServers(ctx context.Context, in *RaftListClusterServersRequest, opts ...grpc.CallOption) (*RaftListClusterServersResponse, error)
|
||||
RaftAddServer(ctx context.Context, in *RaftAddServerRequest, opts ...grpc.CallOption) (*RaftAddServerResponse, error)
|
||||
RaftRemoveServer(ctx context.Context, in *RaftRemoveServerRequest, opts ...grpc.CallOption) (*RaftRemoveServerResponse, error)
|
||||
}
|
||||
|
||||
type seaweedClient struct {
|
||||
@@ -212,6 +216,42 @@ func (c *seaweedClient) ReleaseAdminToken(ctx context.Context, in *ReleaseAdminT
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *seaweedClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) {
|
||||
out := new(PingResponse)
|
||||
err := c.cc.Invoke(ctx, "/master_pb.Seaweed/Ping", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *seaweedClient) RaftListClusterServers(ctx context.Context, in *RaftListClusterServersRequest, opts ...grpc.CallOption) (*RaftListClusterServersResponse, error) {
|
||||
out := new(RaftListClusterServersResponse)
|
||||
err := c.cc.Invoke(ctx, "/master_pb.Seaweed/RaftListClusterServers", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *seaweedClient) RaftAddServer(ctx context.Context, in *RaftAddServerRequest, opts ...grpc.CallOption) (*RaftAddServerResponse, error) {
|
||||
out := new(RaftAddServerResponse)
|
||||
err := c.cc.Invoke(ctx, "/master_pb.Seaweed/RaftAddServer", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *seaweedClient) RaftRemoveServer(ctx context.Context, in *RaftRemoveServerRequest, opts ...grpc.CallOption) (*RaftRemoveServerResponse, error) {
|
||||
out := new(RaftRemoveServerResponse)
|
||||
err := c.cc.Invoke(ctx, "/master_pb.Seaweed/RaftRemoveServer", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// SeaweedServer is the server API for Seaweed service.
|
||||
// All implementations must embed UnimplementedSeaweedServer
|
||||
// for forward compatibility
|
||||
@@ -230,6 +270,10 @@ type SeaweedServer interface {
|
||||
ListClusterNodes(context.Context, *ListClusterNodesRequest) (*ListClusterNodesResponse, error)
|
||||
LeaseAdminToken(context.Context, *LeaseAdminTokenRequest) (*LeaseAdminTokenResponse, error)
|
||||
ReleaseAdminToken(context.Context, *ReleaseAdminTokenRequest) (*ReleaseAdminTokenResponse, error)
|
||||
Ping(context.Context, *PingRequest) (*PingResponse, error)
|
||||
RaftListClusterServers(context.Context, *RaftListClusterServersRequest) (*RaftListClusterServersResponse, error)
|
||||
RaftAddServer(context.Context, *RaftAddServerRequest) (*RaftAddServerResponse, error)
|
||||
RaftRemoveServer(context.Context, *RaftRemoveServerRequest) (*RaftRemoveServerResponse, error)
|
||||
mustEmbedUnimplementedSeaweedServer()
|
||||
}
|
||||
|
||||
@@ -279,6 +323,18 @@ func (UnimplementedSeaweedServer) LeaseAdminToken(context.Context, *LeaseAdminTo
|
||||
func (UnimplementedSeaweedServer) ReleaseAdminToken(context.Context, *ReleaseAdminTokenRequest) (*ReleaseAdminTokenResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ReleaseAdminToken not implemented")
|
||||
}
|
||||
func (UnimplementedSeaweedServer) Ping(context.Context, *PingRequest) (*PingResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented")
|
||||
}
|
||||
func (UnimplementedSeaweedServer) RaftListClusterServers(context.Context, *RaftListClusterServersRequest) (*RaftListClusterServersResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RaftListClusterServers not implemented")
|
||||
}
|
||||
func (UnimplementedSeaweedServer) RaftAddServer(context.Context, *RaftAddServerRequest) (*RaftAddServerResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RaftAddServer not implemented")
|
||||
}
|
||||
func (UnimplementedSeaweedServer) RaftRemoveServer(context.Context, *RaftRemoveServerRequest) (*RaftRemoveServerResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RaftRemoveServer not implemented")
|
||||
}
|
||||
func (UnimplementedSeaweedServer) mustEmbedUnimplementedSeaweedServer() {}
|
||||
|
||||
// UnsafeSeaweedServer may be embedded to opt out of forward compatibility for this service.
|
||||
@@ -560,6 +616,78 @@ func _Seaweed_ReleaseAdminToken_Handler(srv interface{}, ctx context.Context, de
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Seaweed_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(PingRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SeaweedServer).Ping(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/master_pb.Seaweed/Ping",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SeaweedServer).Ping(ctx, req.(*PingRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Seaweed_RaftListClusterServers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RaftListClusterServersRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SeaweedServer).RaftListClusterServers(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/master_pb.Seaweed/RaftListClusterServers",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SeaweedServer).RaftListClusterServers(ctx, req.(*RaftListClusterServersRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Seaweed_RaftAddServer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RaftAddServerRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SeaweedServer).RaftAddServer(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/master_pb.Seaweed/RaftAddServer",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SeaweedServer).RaftAddServer(ctx, req.(*RaftAddServerRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Seaweed_RaftRemoveServer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RaftRemoveServerRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SeaweedServer).RaftRemoveServer(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/master_pb.Seaweed/RaftRemoveServer",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SeaweedServer).RaftRemoveServer(ctx, req.(*RaftRemoveServerRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// Seaweed_ServiceDesc is the grpc.ServiceDesc for Seaweed service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
@@ -615,6 +743,22 @@ var Seaweed_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "ReleaseAdminToken",
|
||||
Handler: _Seaweed_ReleaseAdminToken_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Ping",
|
||||
Handler: _Seaweed_Ping_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RaftListClusterServers",
|
||||
Handler: _Seaweed_RaftListClusterServers_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RaftAddServer",
|
||||
Handler: _Seaweed_RaftAddServer_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RaftRemoveServer",
|
||||
Handler: _Seaweed_RaftRemoveServer_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package messaging_pb;
|
||||
|
||||
option go_package = "github.com/chrislusf/seaweedfs/weed/pb/mount_pb";
|
||||
option java_package = "seaweedfs.client";
|
||||
option java_outer_classname = "MountProto";
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
service SeaweedMount {
|
||||
|
||||
rpc Configure (ConfigureRequest) returns (ConfigureResponse) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
message ConfigureRequest {
|
||||
int64 collection_capacity = 1;
|
||||
}
|
||||
|
||||
message ConfigureResponse {
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc v3.17.3
|
||||
// source: mount.proto
|
||||
|
||||
package mount_pb
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type ConfigureRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
CollectionCapacity int64 `protobuf:"varint,1,opt,name=collection_capacity,json=collectionCapacity,proto3" json:"collection_capacity,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ConfigureRequest) Reset() {
|
||||
*x = ConfigureRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_mount_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ConfigureRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ConfigureRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ConfigureRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mount_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ConfigureRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ConfigureRequest) Descriptor() ([]byte, []int) {
|
||||
return file_mount_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *ConfigureRequest) GetCollectionCapacity() int64 {
|
||||
if x != nil {
|
||||
return x.CollectionCapacity
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type ConfigureResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *ConfigureResponse) Reset() {
|
||||
*x = ConfigureResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_mount_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ConfigureResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ConfigureResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ConfigureResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mount_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ConfigureResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ConfigureResponse) Descriptor() ([]byte, []int) {
|
||||
return file_mount_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
var File_mount_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_mount_proto_rawDesc = []byte{
|
||||
0x0a, 0x0b, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x6d,
|
||||
0x65, 0x73, 0x73, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x62, 0x22, 0x43, 0x0a, 0x10, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
|
||||
0x2f, 0x0a, 0x13, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x61,
|
||||
0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x63, 0x6f,
|
||||
0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79,
|
||||
0x22, 0x13, 0x0a, 0x11, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x5e, 0x0a, 0x0c, 0x53, 0x65, 0x61, 0x77, 0x65, 0x65, 0x64,
|
||||
0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x4e, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75,
|
||||
0x72, 0x65, 0x12, 0x1e, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x5f, 0x70,
|
||||
0x62, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x5f, 0x70,
|
||||
0x62, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x4f, 0x0a, 0x10, 0x73, 0x65, 0x61, 0x77, 0x65, 0x65, 0x64,
|
||||
0x66, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x42, 0x0a, 0x4d, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x50, 0x72, 0x6f, 0x74, 0x6f, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x2f, 0x63, 0x68, 0x72, 0x69, 0x73, 0x6c, 0x75, 0x73, 0x66, 0x2f, 0x73, 0x65, 0x61, 0x77,
|
||||
0x65, 0x65, 0x64, 0x66, 0x73, 0x2f, 0x77, 0x65, 0x65, 0x64, 0x2f, 0x70, 0x62, 0x2f, 0x6d, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x5f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_mount_proto_rawDescOnce sync.Once
|
||||
file_mount_proto_rawDescData = file_mount_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_mount_proto_rawDescGZIP() []byte {
|
||||
file_mount_proto_rawDescOnce.Do(func() {
|
||||
file_mount_proto_rawDescData = protoimpl.X.CompressGZIP(file_mount_proto_rawDescData)
|
||||
})
|
||||
return file_mount_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_mount_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_mount_proto_goTypes = []interface{}{
|
||||
(*ConfigureRequest)(nil), // 0: messaging_pb.ConfigureRequest
|
||||
(*ConfigureResponse)(nil), // 1: messaging_pb.ConfigureResponse
|
||||
}
|
||||
var file_mount_proto_depIdxs = []int32{
|
||||
0, // 0: messaging_pb.SeaweedMount.Configure:input_type -> messaging_pb.ConfigureRequest
|
||||
1, // 1: messaging_pb.SeaweedMount.Configure:output_type -> messaging_pb.ConfigureResponse
|
||||
1, // [1:2] is the sub-list for method output_type
|
||||
0, // [0:1] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_mount_proto_init() }
|
||||
func file_mount_proto_init() {
|
||||
if File_mount_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_mount_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ConfigureRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_mount_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ConfigureResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_mount_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_mount_proto_goTypes,
|
||||
DependencyIndexes: file_mount_proto_depIdxs,
|
||||
MessageInfos: file_mount_proto_msgTypes,
|
||||
}.Build()
|
||||
File_mount_proto = out.File
|
||||
file_mount_proto_rawDesc = nil
|
||||
file_mount_proto_goTypes = nil
|
||||
file_mount_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
|
||||
package mount_pb
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
// SeaweedMountClient is the client API for SeaweedMount service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type SeaweedMountClient interface {
|
||||
Configure(ctx context.Context, in *ConfigureRequest, opts ...grpc.CallOption) (*ConfigureResponse, error)
|
||||
}
|
||||
|
||||
type seaweedMountClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewSeaweedMountClient(cc grpc.ClientConnInterface) SeaweedMountClient {
|
||||
return &seaweedMountClient{cc}
|
||||
}
|
||||
|
||||
func (c *seaweedMountClient) Configure(ctx context.Context, in *ConfigureRequest, opts ...grpc.CallOption) (*ConfigureResponse, error) {
|
||||
out := new(ConfigureResponse)
|
||||
err := c.cc.Invoke(ctx, "/messaging_pb.SeaweedMount/Configure", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// SeaweedMountServer is the server API for SeaweedMount service.
|
||||
// All implementations must embed UnimplementedSeaweedMountServer
|
||||
// for forward compatibility
|
||||
type SeaweedMountServer interface {
|
||||
Configure(context.Context, *ConfigureRequest) (*ConfigureResponse, error)
|
||||
mustEmbedUnimplementedSeaweedMountServer()
|
||||
}
|
||||
|
||||
// UnimplementedSeaweedMountServer must be embedded to have forward compatible implementations.
|
||||
type UnimplementedSeaweedMountServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedSeaweedMountServer) Configure(context.Context, *ConfigureRequest) (*ConfigureResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Configure not implemented")
|
||||
}
|
||||
func (UnimplementedSeaweedMountServer) mustEmbedUnimplementedSeaweedMountServer() {}
|
||||
|
||||
// UnsafeSeaweedMountServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to SeaweedMountServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeSeaweedMountServer interface {
|
||||
mustEmbedUnimplementedSeaweedMountServer()
|
||||
}
|
||||
|
||||
func RegisterSeaweedMountServer(s grpc.ServiceRegistrar, srv SeaweedMountServer) {
|
||||
s.RegisterService(&SeaweedMount_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _SeaweedMount_Configure_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ConfigureRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SeaweedMountServer).Configure(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/messaging_pb.SeaweedMount/Configure",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SeaweedMountServer).Configure(ctx, req.(*ConfigureRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// SeaweedMount_ServiceDesc is the grpc.ServiceDesc for SeaweedMount service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var SeaweedMount_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "messaging_pb.SeaweedMount",
|
||||
HandlerType: (*SeaweedMountServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Configure",
|
||||
Handler: _SeaweedMount_Configure_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "mount.proto",
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user