mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-21 22:12:36 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa7c65bd4b | ||
|
|
84fdda85e7 | ||
|
|
ad5099e570 | ||
|
|
5abdc0be77 | ||
|
|
ede7a65a50 | ||
|
|
c1255d30ad | ||
|
|
eab7cf4bd3 | ||
|
|
59dd271734 | ||
|
|
4cbba2b1c6 | ||
|
|
71175461ef | ||
|
|
49d971e602 | ||
|
|
94a01fcfcb | ||
|
|
b5f4910412 | ||
|
|
f0907eb83c | ||
|
|
63da4bbb54 | ||
|
|
0c099c1bea | ||
|
|
7a135b7735 | ||
|
|
2789d10342 | ||
|
|
119d5908dd | ||
|
|
7504be58f9 | ||
|
|
96514f0f00 | ||
|
|
20ac710ceb | ||
|
|
6cd1ce8b74 | ||
|
|
f74b29416a | ||
|
|
e9760f261e | ||
|
|
e5fc35ed0c | ||
|
|
2c9d4c8f43 | ||
|
|
e690a2be16 | ||
|
|
232ad2fe65 | ||
|
|
bd1f800efe | ||
|
|
7591336a22 | ||
|
|
8c6ff55226 | ||
|
|
7e600bff5f | ||
|
|
67949e25e9 | ||
|
|
a243d7e047 | ||
|
|
f7f01ac209 | ||
|
|
59cb6146a3 | ||
|
|
5496d68f6a | ||
|
|
2b8ab1534a | ||
|
|
ac574d5572 | ||
|
|
5654d0d60d | ||
|
|
0b4269b6a8 | ||
|
|
0207f5fe9b | ||
|
|
00edcf71fc | ||
|
|
574485ec69 | ||
|
|
0128239c0f | ||
|
|
35c8ea495f | ||
|
|
6a7ed1bd0e | ||
|
|
a0a6aa36fa | ||
|
|
9fdf02bcda | ||
|
|
889a39a24f | ||
|
|
85a2046411 | ||
|
|
9ca7c322b4 | ||
|
|
8c6d706328 | ||
|
|
2954bd71f8 | ||
|
|
ce9e606eb2 | ||
|
|
ee143f9ae0 | ||
|
|
5035b0a109 | ||
|
|
a443e39def | ||
|
|
64971b0d7e | ||
|
|
68b23114b9 | ||
|
|
0c47437ece | ||
|
|
9ec151fa0d | ||
|
|
2b1feb732c | ||
|
|
3adc3da291 | ||
|
|
6923af7280 | ||
|
|
64f6532fbe | ||
|
|
308d4b2dae | ||
|
|
8e4b43a017 | ||
|
|
c218ef20c7 | ||
|
|
1702ce5395 | ||
|
|
fe4794fe92 | ||
|
|
728ed21a80 | ||
|
|
9fb278c92c | ||
|
|
0cda61d539 | ||
|
|
f62df7f695 | ||
|
|
e93d4935e3 | ||
|
|
7a13816e94 | ||
|
|
d5c7dbac4a | ||
|
|
d869a07cd2 | ||
|
|
705285ec60 | ||
|
|
f2de7910fc | ||
|
|
ae98a085d3 | ||
|
|
6022db6d6a | ||
|
|
006c01a519 | ||
|
|
65af3cf4df | ||
|
|
57a95887d2 | ||
|
|
28f45f8fa6 | ||
|
|
c735608685 | ||
|
|
32e94de86a | ||
|
|
60573fd3e2 | ||
|
|
2348e8d8da | ||
|
|
0fe9d2997b | ||
|
|
bdefdee4e6 | ||
|
|
d57d4c5f8f | ||
|
|
98c68d7a79 | ||
|
|
d983aa4c7d | ||
|
|
c5ee03d6af | ||
|
|
cc278a5928 | ||
|
|
16a342eb8a | ||
|
|
796b2eb929 | ||
|
|
53b9b521c9 | ||
|
|
49952ba905 | ||
|
|
99d4594ee8 | ||
|
|
df29281536 | ||
|
|
c3db389e42 | ||
|
|
e9ce099453 | ||
|
|
8707ef00a6 | ||
|
|
13cc2ef723 | ||
|
|
63c84584bb | ||
|
|
4b28c5f6c3 | ||
|
|
da49d25950 | ||
|
|
38f73c8324 | ||
|
|
43d6678d6d | ||
|
|
8ec357b3d3 | ||
|
|
bbc77f7af4 | ||
|
|
cc36f5b01f | ||
|
|
0652805236 | ||
|
|
03a31587ce | ||
|
|
83cd0fc739 | ||
|
|
fbfc90fd1e | ||
|
|
491f7636f8 | ||
|
|
bca4a9de78 | ||
|
|
958125bd02 | ||
|
|
11a496404b | ||
|
|
7f2a8246a9 | ||
|
|
1b942dfa3c | ||
|
|
9a73b0e3c9 | ||
|
|
e281f0fa82 | ||
|
|
24fda6f47f | ||
|
|
7ce97b59d8 | ||
|
|
d1a4e19a3f | ||
|
|
3bd48c4f29 | ||
|
|
3faaa6e360 | ||
|
|
8e125339d5 | ||
|
|
68ea99190f | ||
|
|
43fd11278e | ||
|
|
cca588429b | ||
|
|
0ee208c1a4 | ||
|
|
97b7948cd9 | ||
|
|
c9205458a1 | ||
|
|
1dfcdc53b7 | ||
|
|
701cc133f3 | ||
|
|
8ecd609b48 | ||
|
|
f117f7bf54 | ||
|
|
72d4ff6b28 | ||
|
|
f811fd0903 | ||
|
|
b17b81529e | ||
|
|
e5f9ff983d | ||
|
|
44d0ac95f6 | ||
|
|
18bf556d93 | ||
|
|
21f37a0a75 | ||
|
|
5adfdd7982 | ||
|
|
05f32376eb | ||
|
|
268de45aa5 | ||
|
|
eacaa44dc2 | ||
|
|
6deee4c0b9 | ||
|
|
a31f2907f0 | ||
|
|
001a472057 | ||
|
|
05d2774117 | ||
|
|
975fbc9ee3 | ||
|
|
cd838b1197 | ||
|
|
b7ec879d32 | ||
|
|
aeda4be42c | ||
|
|
7cfaa1a365 | ||
|
|
bfb66b88b1 | ||
|
|
16f0cdc1bf | ||
|
|
1587ce779d | ||
|
|
b686e8c45b | ||
|
|
e2aaa3e2f3 | ||
|
|
ab0ebe1d3b | ||
|
|
4128c1126a | ||
|
|
8b7063634f | ||
|
|
a7383a8a1c | ||
|
|
bec3f63298 | ||
|
|
223c1b3571 | ||
|
|
ccc44059e8 | ||
|
|
8c523d50ad | ||
|
|
65a29ad42a | ||
|
|
a22f37b01c | ||
|
|
a9b41900d8 | ||
|
|
0d8936f6cd | ||
|
|
ff70ba51ac | ||
|
|
dc481c081c | ||
|
|
ca80199ccd | ||
|
|
7b56a6400d | ||
|
|
b1331ba3fe | ||
|
|
6850252e7c | ||
|
|
5a10f27c8d | ||
|
|
46e78e9b3e | ||
|
|
b4de7c09e7 | ||
|
|
b68e76bbac | ||
|
|
7107ded3cd | ||
|
|
e73044f1f0 | ||
|
|
9ac962888c | ||
|
|
ee52f29c33 | ||
|
|
ba45852ca5 | ||
|
|
4f452b71c9 | ||
|
|
3fddbefdb5 | ||
|
|
dded814a62 | ||
|
|
059e88d5df | ||
|
|
9cbb8a14b2 | ||
|
|
1d4e412f93 | ||
|
|
27cf03d031 | ||
|
|
0f85bcaba8 | ||
|
|
d0990651ce | ||
|
|
7be3ab4dc7 | ||
|
|
e2a7399f69 | ||
|
|
6ed2e2a21d | ||
|
|
72ea1a9a21 | ||
|
|
29bc6cb9a2 | ||
|
|
dc936921aa | ||
|
|
9242f3aaeb | ||
|
|
49a8dfb976 | ||
|
|
6a0bb7106b | ||
|
|
05a648bb96 | ||
|
|
c1dc5ab4ac | ||
|
|
318757ef8c | ||
|
|
de8ef28460 | ||
|
|
546efeba8f | ||
|
|
2088f28424 | ||
|
|
c08ac536ed | ||
|
|
9bcf94b2b1 | ||
|
|
a7a914f120 | ||
|
|
2d805beed4 | ||
|
|
c6c97bd83d | ||
|
|
a19c728034 | ||
|
|
19a81d25af | ||
|
|
47d775cf68 | ||
|
|
6bab20d862 | ||
|
|
e9ebe24f2e | ||
|
|
7c39a18ba5 | ||
|
|
a78d0227cd | ||
|
|
12631a3f5b | ||
|
|
95a6e0226d | ||
|
|
7eeff1d8a1 | ||
|
|
93741a6752 | ||
|
|
949ff6475e | ||
|
|
76422cbe35 | ||
|
|
68157f3630 | ||
|
|
2ead7adaff | ||
|
|
00c4e06caa | ||
|
|
f0cc130849 | ||
|
|
2836a58d87 | ||
|
|
188ecc079d | ||
|
|
95e2b83ca5 | ||
|
|
ff7dc3b44c | ||
|
|
ca35a77e85 | ||
|
|
258063de26 | ||
|
|
3b2c39f1be | ||
|
|
2158d4fe4d | ||
|
|
69442d220b | ||
|
|
69c7b7d2a8 | ||
|
|
1b1ab331f6 | ||
|
|
7720533f84 | ||
|
|
05fc7db755 | ||
|
|
02e8f00138 | ||
|
|
c63713774b | ||
|
|
570d2eccec | ||
|
|
605c39ced7 | ||
|
|
ccb3df41f8 | ||
|
|
e64339e8c0 | ||
|
|
223b344c79 | ||
|
|
0e9276b947 | ||
|
|
1f301e4ba4 | ||
|
|
1057d3ac53 | ||
|
|
8461c025ef | ||
|
|
d2c8f01671 | ||
|
|
865b06b7fe | ||
|
|
d24ad92513 | ||
|
|
7bf65c1e99 | ||
|
|
5315fcb820 | ||
|
|
f316de3b5c | ||
|
|
1023bce6f0 | ||
|
|
8109594c6e | ||
|
|
6f9107862f | ||
|
|
48f88f9768 | ||
|
|
d81b20dabb | ||
|
|
e2aa3cf63b | ||
|
|
1f35d32be0 | ||
|
|
40dc283b2d | ||
|
|
72eb6d5b9d | ||
|
|
5a7c40510f | ||
|
|
bb94930196 | ||
|
|
5d5a21ba2d | ||
|
|
c45c12aedc | ||
|
|
507411bdf0 | ||
|
|
c3ffd457ef | ||
|
|
49b5e47bd1 | ||
|
|
fda2fc47b1 | ||
|
|
a539d64896 | ||
|
|
8f7d2d317f | ||
|
|
0b2a92d371 | ||
|
|
ec989b0377 | ||
|
|
9462f5129a | ||
|
|
3ada61c875 | ||
|
|
c34747c79d | ||
|
|
cb53802752 | ||
|
|
889b143fa7 | ||
|
|
f365af81c2 | ||
|
|
00ffbb4c9a | ||
|
|
53e66980b2 | ||
|
|
9921801e0c | ||
|
|
ba6923b223 | ||
|
|
708debca14 | ||
|
|
0c671885bf | ||
|
|
e2115bfbd2 | ||
|
|
0e9c04417d | ||
|
|
2c38f8738f | ||
|
|
e0c45c24f5 | ||
|
|
c587acf3ee | ||
|
|
561bea954d | ||
|
|
8ea9a2434d | ||
|
|
68b1667272 | ||
|
|
08258a819d | ||
|
|
4909bd9684 | ||
|
|
8126ab4b5d | ||
|
|
0db2517994 | ||
|
|
7937db52e1 | ||
|
|
0c66b173a4 | ||
|
|
e02a317d3d | ||
|
|
2d519c6cb6 | ||
|
|
b961fcd338 | ||
|
|
f4decf02df | ||
|
|
0f7d4556d8 | ||
|
|
333cdce485 | ||
|
|
78e8ddf910 | ||
|
|
a8617c1a39 | ||
|
|
5a0f92423e | ||
|
|
6238644c35 | ||
|
|
d1d1fc772c | ||
|
|
5571f4f70a | ||
|
|
5469019852 | ||
|
|
7667d26ebf | ||
|
|
bfac55e6c0 | ||
|
|
5516fa8e80 | ||
|
|
a51447ffcb | ||
|
|
f0afd35eec | ||
|
|
775dfbae85 | ||
|
|
ec09966fd3 | ||
|
|
5df38d610d | ||
|
|
f2cd753bf9 | ||
|
|
01336d71eb | ||
|
|
1154e23e2d | ||
|
|
057ef429ac | ||
|
|
b63b042afc | ||
|
|
0526db12e2 | ||
|
|
e50a5b8e28 | ||
|
|
db6275a0c8 | ||
|
|
9d85569c55 | ||
|
|
85832d02c0 | ||
|
|
1098ed0d78 | ||
|
|
095f66cd64 | ||
|
|
1c94b3d013 | ||
|
|
e6e57db530 | ||
|
|
f9cf9b93d3 | ||
|
|
8ff6c9a0c6 | ||
|
|
48f448ee09 | ||
|
|
69a6da7969 | ||
|
|
18228f3044 | ||
|
|
e9128e75d0 | ||
|
|
69655ba8e5 | ||
|
|
a7012d9729 | ||
|
|
02f728cb54 | ||
|
|
8d3e275735 | ||
|
|
9096f6f4f7 | ||
|
|
402315f117 | ||
|
|
a6be2520c9 | ||
|
|
713c035a6e | ||
|
|
8cfd487608 | ||
|
|
734c980040 | ||
|
|
96ce85f5ae | ||
|
|
c5f38c365d | ||
|
|
df85f7a1eb | ||
|
|
c0b12da4ef | ||
|
|
52fcce81c6 | ||
|
|
882a93dacd | ||
|
|
7412ccdf88 | ||
|
|
dcf614a8c3 | ||
|
|
eed26af266 | ||
|
|
4370a4db63 | ||
|
|
26c222f596 | ||
|
|
13e45e1605 | ||
|
|
8f5170c138 | ||
|
|
46b0cb8c86 | ||
|
|
de730b079d | ||
|
|
59732a0529 | ||
|
|
d2b3416d1c | ||
|
|
ecb234f75a | ||
|
|
270770d7d7 | ||
|
|
679f800caa | ||
|
|
0c0f77e2ae | ||
|
|
8828f485c0 | ||
|
|
d2b23f3d38 | ||
|
|
e23ca3845b | ||
|
|
286e5dd375 | ||
|
|
1e22166939 | ||
|
|
f3dc909b21 | ||
|
|
e84fad9acf | ||
|
|
1a5d29520c | ||
|
|
6b743dbbf9 | ||
|
|
b9ecf1e3a8 | ||
|
|
d84c311699 | ||
|
|
f6a9ad8001 | ||
|
|
42969c9c62 | ||
|
|
8cf0c515bf | ||
|
|
d2ddf1dbdb | ||
|
|
3afbf04007 | ||
|
|
fe60c6ef9a | ||
|
|
0ca641f33c | ||
|
|
bdc7730fdb | ||
|
|
2ae9705442 | ||
|
|
3739717092 | ||
|
|
f690643b47 | ||
|
|
6de786185d | ||
|
|
3bb640b786 | ||
|
|
02fd913b51 | ||
|
|
9e839cb5cc | ||
|
|
56ee1d5ef1 | ||
|
|
81b255df8b | ||
|
|
58bc3ecf47 | ||
|
|
2ca1839d77 | ||
|
|
89933c46d2 | ||
|
|
1c7e404abe | ||
|
|
cb1dbd3135 | ||
|
|
1161c70dab | ||
|
|
9cc84a910f | ||
|
|
767edd3c08 | ||
|
|
9df7d16791 | ||
|
|
f5a69a0e44 | ||
|
|
6ba65c3382 | ||
|
|
10c11b9fd1 | ||
|
|
5d4438a72f | ||
|
|
1ff8285d82 | ||
|
|
0d6f45cb46 | ||
|
|
a3290faf17 | ||
|
|
c6f992b2a3 | ||
|
|
899963ac20 | ||
|
|
c16e366fb2 | ||
|
|
285fdd2dd5 | ||
|
|
c090d6bb25 | ||
|
|
4deac06da0 | ||
|
|
ddff849ea6 | ||
|
|
5c6270a93a | ||
|
|
035b0bae29 | ||
|
|
1752eeb538 | ||
|
|
4b94b03d90 | ||
|
|
99b599aa8a | ||
|
|
5dede5d38d | ||
|
|
35f70c51b0 | ||
|
|
72eec84167 | ||
|
|
8dccefbba6 | ||
|
|
2b28a818f1 | ||
|
|
10464f47d0 | ||
|
|
7374b5b473 | ||
|
|
2595f269d1 | ||
|
|
ac28611817 | ||
|
|
5c14da0f1e | ||
|
|
4cc2165061 | ||
|
|
10fc478557 | ||
|
|
092932af8f | ||
|
|
bdb632fa62 | ||
|
|
2b46df13f8 | ||
|
|
60f5c0a2f5 | ||
|
|
f3746d350f | ||
|
|
a70e772a03 | ||
|
|
182288f860 | ||
|
|
84d91f143f | ||
|
|
7359193e97 | ||
|
|
cc32436d63 | ||
|
|
67537ff05b | ||
|
|
e0c7708b03 | ||
|
|
41d559f54e | ||
|
|
70effac0d3 | ||
|
|
3138805b33 | ||
|
|
a125c8fbe2 | ||
|
|
b9a67d46c5 | ||
|
|
54c8bc8673 | ||
|
|
7ab389e7ec | ||
|
|
93c37cfded | ||
|
|
b23b307e08 | ||
|
|
b938df97a2 | ||
|
|
450222dd64 | ||
|
|
8dc5def435 | ||
|
|
99155e4880 | ||
|
|
2f209675ab | ||
|
|
fb7a1be1c4 | ||
|
|
3f31c4091a | ||
|
|
2faf96f002 | ||
|
|
4be5b4ff5c | ||
|
|
e95166d739 | ||
|
|
a45bbc0b75 | ||
|
|
f0042f62dd | ||
|
|
18c40686d9 | ||
|
|
5a838dbe53 | ||
|
|
6103649ffb | ||
|
|
49c66e88a0 | ||
|
|
01adc567aa | ||
|
|
297b41266b | ||
|
|
b194f91f47 | ||
|
|
ae7129f717 | ||
|
|
9e48bff8ee | ||
|
|
272c7836c3 | ||
|
|
d013d6d968 | ||
|
|
3d624d1e16 | ||
|
|
ecce300964 | ||
|
|
da7bd62822 | ||
|
|
a6d73e0a66 | ||
|
|
ed57a55eae | ||
|
|
44b50b2fdf | ||
|
|
3df153421d | ||
|
|
30156e142a | ||
|
|
141388367e | ||
|
|
44a2538f67 | ||
|
|
e2da647fa3 | ||
|
|
233103f6b2 | ||
|
|
4ab25fa395 | ||
|
|
5dbbe19c8b | ||
|
|
5bcc77b46c | ||
|
|
f5fa0b08fd | ||
|
|
a024254ad7 | ||
|
|
d39b2689a5 | ||
|
|
3986601ee8 | ||
|
|
fa0dab6029 | ||
|
|
8fe75692ee | ||
|
|
2cb8b31ea7 | ||
|
|
8425705643 | ||
|
|
d8bda0b229 | ||
|
|
53ecae7c7b | ||
|
|
586e066897 | ||
|
|
3d9ec2e0b6 | ||
|
|
1a4db87e19 | ||
|
|
c6d4c16079 | ||
|
|
2420c60fc4 | ||
|
|
067eb15e70 | ||
|
|
b624090398 | ||
|
|
215b169562 | ||
|
|
c795183887 | ||
|
|
30dbe98dff | ||
|
|
07f20155fd | ||
|
|
90badb8201 | ||
|
|
a66112c9d2 | ||
|
|
c8884719ea | ||
|
|
253b4ed898 | ||
|
|
4a0ba3a1a9 | ||
|
|
20d33ae025 | ||
|
|
7566782c2e | ||
|
|
e9eb15e56a | ||
|
|
6f683e6572 | ||
|
|
41db292332 | ||
|
|
3668d10664 | ||
|
|
24e11d1e90 | ||
|
|
fc8dd58aea | ||
|
|
a2979aa051 | ||
|
|
08377fecb8 | ||
|
|
17477b37d5 | ||
|
|
c764596f96 | ||
|
|
cc7714fdbe | ||
|
|
facaa36d22 | ||
|
|
8d70ba2eaa | ||
|
|
1cac2f2278 | ||
|
|
9dd09bbb33 | ||
|
|
c2e0a75c1f | ||
|
|
78b1fb921c | ||
|
|
05af54ad10 | ||
|
|
d5bc87a5da | ||
|
|
d4b0dcf442 | ||
|
|
829b195084 | ||
|
|
d474ce6fe3 | ||
|
|
117f8e0bc1 | ||
|
|
f1d207a0fe | ||
|
|
b3eb4fecc7 | ||
|
|
f24bb9e688 | ||
|
|
88d52adfdd | ||
|
|
56eb522b13 | ||
|
|
055374a50b | ||
|
|
cd59573dd3 | ||
|
|
6aa1a56ec8 | ||
|
|
ebe971da2e | ||
|
|
7a81caa31e | ||
|
|
4d0cbd2700 | ||
|
|
7225cb4ac5 | ||
|
|
28a4a1f8d6 | ||
|
|
1e76fc994a | ||
|
|
ed6aa13520 | ||
|
|
ee6c67682c | ||
|
|
9357911a95 | ||
|
|
b71c3cfba4 | ||
|
|
310e31424e | ||
|
|
8b382a8209 | ||
|
|
33b87244ef | ||
|
|
40a8cb9b0a | ||
|
|
7ce3bee0c0 | ||
|
|
492a91e0b0 | ||
|
|
0e3adde47f | ||
|
|
76f24af79a | ||
|
|
5e6dfbc25f | ||
|
|
452c6ef183 | ||
|
|
8295e2feb6 | ||
|
|
c8dea3dd89 | ||
|
|
19caeb7b02 | ||
|
|
bb45dea15a | ||
|
|
e00443a940 | ||
|
|
44f1ba6894 | ||
|
|
6c82326575 | ||
|
|
9cba5cca0b | ||
|
|
21ad9a4ac2 | ||
|
|
e6ba2f9c37 | ||
|
|
d7638b73b5 | ||
|
|
5403ada150 | ||
|
|
fadc1febdb | ||
|
|
ab606dec2a | ||
|
|
f15d7a57f5 | ||
|
|
d350c114c8 | ||
|
|
0a5388744c | ||
|
|
77100754e6 | ||
|
|
62142ff1d2 | ||
|
|
cc34475012 | ||
|
|
99ef280c7c | ||
|
|
3db1642392 | ||
|
|
556cc3a4ca | ||
|
|
615cb24ba6 | ||
|
|
c5de97ddbe | ||
|
|
2b60e2abb1 | ||
|
|
9774cac3a1 | ||
|
|
769fe4b772 | ||
|
|
8f1f8c63e5 | ||
|
|
1fb1b7d7b8 | ||
|
|
4233ad3f07 | ||
|
|
1456616a77 | ||
|
|
fb8036385a | ||
|
|
2d7b4e5bb6 | ||
|
|
ae185b997f | ||
|
|
849f36c1ac | ||
|
|
622fc2fa2f | ||
|
|
6e8bd16819 | ||
|
|
4d55132c7d | ||
|
|
45bffc92a8 | ||
|
|
921e0d5008 | ||
|
|
1a70cb9b63 | ||
|
|
e699d16c85 | ||
|
|
84488ebb33 | ||
|
|
ac9bf71544 | ||
|
|
877c192af2 | ||
|
|
67dd094b35 | ||
|
|
dce1f02c9e | ||
|
|
35ca9638c4 | ||
|
|
b612d5aebd | ||
|
|
9079ce0e7f | ||
|
|
69c768870b | ||
|
|
15859a7daa | ||
|
|
84dce32a57 | ||
|
|
359a08ecba | ||
|
|
0e404cd84b | ||
|
|
759e4f1a75 | ||
|
|
bb42633522 | ||
|
|
064269bb57 | ||
|
|
b70aeb7585 | ||
|
|
42fb03a66e | ||
|
|
2d85ffe7c5 | ||
|
|
a852f8a3f5 | ||
|
|
3d3fa43542 | ||
|
|
2d0a0733ec | ||
|
|
2586621362 | ||
|
|
e5a2bf1287 | ||
|
|
431684798b | ||
|
|
2f136a04a1 | ||
|
|
3325b850cc | ||
|
|
26a4f34a57 | ||
|
|
e8b7d4ad64 | ||
|
|
0b00edfc3b | ||
|
|
085a61cb8f | ||
|
|
4d0b894d37 | ||
|
|
2d237f7b50 | ||
|
|
f37a4cbd0f | ||
|
|
5d77840cff | ||
|
|
dc1309f084 | ||
|
|
42f631f549 | ||
|
|
30c67e3652 | ||
|
|
03d1199d5f | ||
|
|
87a32bfef4 | ||
|
|
6c1c72b1f4 | ||
|
|
33fe0b96e6 | ||
|
|
aeeeee1e26 | ||
|
|
1aa7e99a89 | ||
|
|
45a762223a | ||
|
|
789465d99e | ||
|
|
83c037e093 | ||
|
|
5a29d284fa | ||
|
|
e3f47ddb76 | ||
|
|
3ff307e842 | ||
|
|
a48ebd7c73 | ||
|
|
26a55bbb5c | ||
|
|
ceb620a30a | ||
|
|
b430d1b6ee | ||
|
|
534c4202a5 | ||
|
|
516efdddc7 | ||
|
|
0c16e00ef9 | ||
|
|
fc5a8af09e | ||
|
|
285a4667c2 | ||
|
|
727287a755 | ||
|
|
19895d5f72 | ||
|
|
0f7b43af99 | ||
|
|
d2d36a3f9d | ||
|
|
4596e64710 | ||
|
|
e55aa41690 | ||
|
|
1737af480a | ||
|
|
d06ecc2649 | ||
|
|
fe2edd4b50 | ||
|
|
55d547afec | ||
|
|
9a6aa00e9d | ||
|
|
da0a4e775b | ||
|
|
40945a60cf | ||
|
|
aa6949ef25 | ||
|
|
ba77833343 | ||
|
|
f4cf30b497 | ||
|
|
280e7cf289 | ||
|
|
74052064b6 | ||
|
|
59ace54925 | ||
|
|
50be19d23e | ||
|
|
55e060cf61 | ||
|
|
735e65be17 | ||
|
|
93e84a12f2 | ||
|
|
3942e3b2ef | ||
|
|
957e1a1bc1 | ||
|
|
7ca75347ec | ||
|
|
8f8738867f | ||
|
|
007401f3a0 | ||
|
|
930581cedc | ||
|
|
84397b814a | ||
|
|
89b2ef8d05 | ||
|
|
a46be0ca56 | ||
|
|
9b5f54e367 | ||
|
|
28d58bac62 | ||
|
|
48601bce6c | ||
|
|
9c97b17291 | ||
|
|
aaad4b578b | ||
|
|
c4d32f6937 | ||
|
|
55a8f57381 | ||
|
|
5753749c90 | ||
|
|
38f411219a | ||
|
|
c899bdf063 | ||
|
|
3eb336e0b0 | ||
|
|
76c48ffe27 | ||
|
|
ac71117ee6 | ||
|
|
24efa31e49 | ||
|
|
ac26080bd2 | ||
|
|
e24ba2aadc | ||
|
|
e87e6ef33c | ||
|
|
a4bb37a5fe | ||
|
|
2e56407c6b | ||
|
|
c48ef78670 | ||
|
|
53b300edd8 | ||
|
|
f51bf61a16 | ||
|
|
3a86d4dbfd | ||
|
|
d74cdf0115 | ||
|
|
84312e6799 | ||
|
|
8db58450a0 | ||
|
|
513fd5e0f6 | ||
|
|
10cddc44de | ||
|
|
4fc074db81 | ||
|
|
fa0d973113 | ||
|
|
042de9359c | ||
|
|
a26a37dfa3 | ||
|
|
ef94ff6837 | ||
|
|
8ae3ea4b1d | ||
|
|
9dca75aea8 | ||
|
|
5198c7a7d5 | ||
|
|
c2269123d3 | ||
|
|
39f636c682 | ||
|
|
a8864e2abd | ||
|
|
12a7e87007 | ||
|
|
ccbe02218a | ||
|
|
4bdb17d086 | ||
|
|
a48785c7df | ||
|
|
5861ba4608 | ||
|
|
7a9d27fce8 | ||
|
|
400c8ef8d8 | ||
|
|
cf552417a7 | ||
|
|
31f1cdeac2 | ||
|
|
d861cbd81b | ||
|
|
4ee58922ef | ||
|
|
86185262bb | ||
|
|
79f2e780c1 | ||
|
|
ddc8643ee0 | ||
|
|
f0ad172e80 | ||
|
|
89eb9f6e70 | ||
|
|
46ef1811a1 | ||
|
|
11c120c040 | ||
|
|
6e5df901e4 | ||
|
|
c60f2d333e | ||
|
|
ca998328c2 | ||
|
|
7deb4b20cd | ||
|
|
f4d77e527d | ||
|
|
cd7bf1a72a | ||
|
|
a8114da02d | ||
|
|
ae74d8f02a | ||
|
|
bcd400995a | ||
|
|
ecb60d5f03 | ||
|
|
11c405fc85 | ||
|
|
72e9d9673e | ||
|
|
c31c5e829c | ||
|
|
83cf94ad2d | ||
|
|
1faafce832 | ||
|
|
e983f91b03 | ||
|
|
4b3cc28cab | ||
|
|
d1c813c470 | ||
|
|
372872ebbf | ||
|
|
e332da4837 | ||
|
|
2acf6be24e | ||
|
|
6cbd786db9 | ||
|
|
d41e6826d3 | ||
|
|
d9a2a7f1c4 | ||
|
|
54410ca955 | ||
|
|
b0127645a5 | ||
|
|
198688c717 | ||
|
|
c83ab91e2e | ||
|
|
3074e9b428 | ||
|
|
b971317a16 | ||
|
|
283d703d50 | ||
|
|
609e228578 | ||
|
|
ba92f2e714 | ||
|
|
16c0304416 | ||
|
|
217e0f9066 | ||
|
|
3e669e6d7b | ||
|
|
07f712c83f | ||
|
|
36c79de3f4 | ||
|
|
e41766feb6 | ||
|
|
1adc8f86ea | ||
|
|
6bc09b18c4 | ||
|
|
c04b7e106f | ||
|
|
ffee470cfc | ||
|
|
fc0cbf565f | ||
|
|
e75633c64f | ||
|
|
9d50867d08 | ||
|
|
ff4c1d5965 | ||
|
|
4480d72cab | ||
|
|
8efd331ce0 | ||
|
|
606c6ae8e8 | ||
|
|
270645f8d7 | ||
|
|
90677e1097 | ||
|
|
3f3268cd1b | ||
|
|
ca0f07a188 | ||
|
|
5985a7d38d | ||
|
|
f5de42fae3 | ||
|
|
1e033d45b8 | ||
|
|
52200a903b | ||
|
|
519b0e1e49 | ||
|
|
8e02e138ea | ||
|
|
742ab1ec81 | ||
|
|
0df5b53ad8 | ||
|
|
f62c153274 | ||
|
|
af313dff58 | ||
|
|
5021bea698 | ||
|
|
98c08a3dcd | ||
|
|
0b82edc0d2 | ||
|
|
93f4146ffa | ||
|
|
f952f979d1 | ||
|
|
4d4acc715e | ||
|
|
6deb647a8f | ||
|
|
ba175f81b5 | ||
|
|
995ae91007 | ||
|
|
b06c5b9d99 | ||
|
|
0f02bd210d | ||
|
|
42a761ee20 | ||
|
|
3be061994f | ||
|
|
c5b08bac1b | ||
|
|
e1fc78ed46 | ||
|
|
f5f8eec8e2 | ||
|
|
011e6e90ee | ||
|
|
ed79baa30f | ||
|
|
100ed77387 | ||
|
|
2327c0756b | ||
|
|
6b8892c5ac | ||
|
|
8693cdacae | ||
|
|
a37eca78cd | ||
|
|
c131764c34 | ||
|
|
0a9d76c9eb | ||
|
|
0f64f5b9c8 | ||
|
|
6eee200c13 | ||
|
|
fbb82a5c9c | ||
|
|
8251d1140e | ||
|
|
7cf7e05cbb | ||
|
|
404cf9db47 | ||
|
|
5dca98fe71 | ||
|
|
5e64f65632 | ||
|
|
319743d330 | ||
|
|
8e404a1433 | ||
|
|
bdf2ddddfd | ||
|
|
67e019d54b | ||
|
|
7e8edc3c4a | ||
|
|
cc0df36a9e | ||
|
|
cefe66f159 | ||
|
|
1f984d2645 | ||
|
|
b5880334fc | ||
|
|
e79e2ddeed | ||
|
|
e06807a55b | ||
|
|
a4db1fe32f | ||
|
|
ac875976c0 | ||
|
|
a1e18a1384 | ||
|
|
48188abc7b | ||
|
|
e5164a3c34 | ||
|
|
3472c87c21 | ||
|
|
9385e2224d | ||
|
|
9401890f18 | ||
|
|
fb04fda28b | ||
|
|
a5662c9e5e | ||
|
|
bec74c3e6a | ||
|
|
9f1cab179c | ||
|
|
a95929e53c | ||
|
|
be25bc6766 | ||
|
|
e72e3453e8 | ||
|
|
7f44d953b5 | ||
|
|
4c51e6a660 | ||
|
|
3cf84b5fae | ||
|
|
6b3cc94ac4 | ||
|
|
b61e9f6a1a | ||
|
|
1ebdbad222 | ||
|
|
8a95f9c10c | ||
|
|
96c62bd34d | ||
|
|
4a02389eb0 | ||
|
|
6b7aa9633f | ||
|
|
bd7471d877 | ||
|
|
b8d3f11e92 | ||
|
|
06be5dc6c3 | ||
|
|
69b2dab9c6 | ||
|
|
40938d6a47 | ||
|
|
9f26f2815c | ||
|
|
82b0463fac | ||
|
|
d7719d0542 | ||
|
|
03c7953254 | ||
|
|
82dfe06066 | ||
|
|
020a5d40c3 | ||
|
|
df6cf0a2fa | ||
|
|
26657f1d72 | ||
|
|
9ce82a9cd2 | ||
|
|
60972f1c97 | ||
|
|
a801332b0d | ||
|
|
c42b95c596 | ||
|
|
40a9e88c07 | ||
|
|
d21a5bf5d0 | ||
|
|
85cff10787 | ||
|
|
5f0e68c21e | ||
|
|
b5e10bf511 | ||
|
|
5a78c6ca99 | ||
|
|
4abb511db3 | ||
|
|
3cbc40fa48 | ||
|
|
2f7c7afdec | ||
|
|
d48dd0c738 | ||
|
|
8eb14967ef | ||
|
|
288369cfc7 | ||
|
|
5d931eff27 | ||
|
|
f315eb2bb8 | ||
|
|
1dd5bc134c | ||
|
|
b465095db1 | ||
|
|
df461402cc | ||
|
|
102a951377 | ||
|
|
f6e2566ee5 | ||
|
|
27e24162f2 | ||
|
|
41cc6e661b | ||
|
|
b2c1c209a5 | ||
|
|
0a51df02cb | ||
|
|
e9b1853d63 | ||
|
|
b1a86cf808 | ||
|
|
aa5179ce3c | ||
|
|
bf94149920 | ||
|
|
c5705e7a35 | ||
|
|
04604b89e1 | ||
|
|
eb54993a4e | ||
|
|
9672f9e1b2 | ||
|
|
69694a17be | ||
|
|
c00dd5e62e | ||
|
|
06da02739d | ||
|
|
91a3ac9731 | ||
|
|
4b1ed227d1 | ||
|
|
10164d0386 | ||
|
|
22a07a12d2 | ||
|
|
050a7f9599 | ||
|
|
3a3699867b | ||
|
|
90510e3137 | ||
|
|
46b9f5cff4 | ||
|
|
7194a5e7bf | ||
|
|
9f00f95bfb | ||
|
|
a4cfffc264 | ||
|
|
ca100568f7 | ||
|
|
352ba23f83 | ||
|
|
29e62aba00 | ||
|
|
35d939a1d2 | ||
|
|
2d4c2db81d | ||
|
|
6d3a96eb56 | ||
|
|
cb423312a4 | ||
|
|
972327f966 | ||
|
|
2a68ddb963 | ||
|
|
5fbcaaf37a | ||
|
|
e19b6b2d0a | ||
|
|
2d567e00aa | ||
|
|
7d57664c2d | ||
|
|
d41202f1b3 | ||
|
|
d66645ecda | ||
|
|
17d02264f3 | ||
|
|
5f99eee27c | ||
|
|
4c1d945e46 | ||
|
|
cca66c7fbe | ||
|
|
7f887c78d2 | ||
|
|
fcc52d1e4e | ||
|
|
40dc5ac904 | ||
|
|
aba47fd9e8 | ||
|
|
d084334ffd | ||
|
|
0e35836cc1 | ||
|
|
58cdcc6d6e | ||
|
|
79280e1513 | ||
|
|
4db21012c1 | ||
|
|
2e19760442 | ||
|
|
828fbf3fb7 | ||
|
|
130ccdeb2e | ||
|
|
5933a925df | ||
|
|
80a97e20c7 | ||
|
|
111b7a84f1 | ||
|
|
bfb4e3e5cb | ||
|
|
6ecf540720 | ||
|
|
5d446673a6 | ||
|
|
d91964904c | ||
|
|
42d7e6fae6 | ||
|
|
ca546f47e1 | ||
|
|
6d729fa742 | ||
|
|
216de41ed9 | ||
|
|
105fcd7bfc | ||
|
|
bb3af2d70b | ||
|
|
15b018da34 | ||
|
|
348e21a08c | ||
|
|
831953c55c | ||
|
|
4bf93d6e63 | ||
|
|
0e02f7e258 | ||
|
|
737bde5ab7 | ||
|
|
5ba4b479f8 | ||
|
|
bf5b795717 | ||
|
|
5be83dd4a9 | ||
|
|
9d8ca513d9 | ||
|
|
f5b5e4da2d | ||
|
|
828f6e9f4d | ||
|
|
387c6f4218 | ||
|
|
36e12ce6f5 | ||
|
|
5b16820924 | ||
|
|
190fada1ef | ||
|
|
453170f42f | ||
|
|
76da6c09d9 | ||
|
|
592af77f9c | ||
|
|
c6d3735605 | ||
|
|
c2ad66e4bf | ||
|
|
35a4253ef3 | ||
|
|
55ec837c0b | ||
|
|
5e2ea4ca2e | ||
|
|
aafb3706b8 | ||
|
|
05a7930c4b | ||
|
|
019f500c9c | ||
|
|
9d30d4223a | ||
|
|
6dc0f53757 | ||
|
|
34fb2efbc2 | ||
|
|
302dbb1b9c | ||
|
|
a1895179cd | ||
|
|
d888e9a90f | ||
|
|
60686a0bb7 | ||
|
|
3b2a9c98ef | ||
|
|
df72dc206d | ||
|
|
726edab054 | ||
|
|
bdfed16d42 | ||
|
|
1bd880dcdb | ||
|
|
9d402ebe9f | ||
|
|
e9eddfb8a2 | ||
|
|
8363be8548 | ||
|
|
38fc200e56 | ||
|
|
1444e9d275 | ||
|
|
3a96461be3 | ||
|
|
ecfe0ec253 | ||
|
|
7413d59750 | ||
|
|
400de380f4 | ||
|
|
2e89c8c9ae | ||
|
|
c5cb346a08 | ||
|
|
f5cc96f289 | ||
|
|
280c10ec8f | ||
|
|
40ff30b83f | ||
|
|
c0842fe99f | ||
|
|
0c5c51eb98 | ||
|
|
d520bc2b08 | ||
|
|
bd727b7b53 | ||
|
|
e982b06bcd | ||
|
|
bcf32591b7 | ||
|
|
be9c7c21ec | ||
|
|
02e146f3e1 | ||
|
|
5511722420 | ||
|
|
4b75981d69 | ||
|
|
cee929793a | ||
|
|
c46d16b2f3 | ||
|
|
6e43e8ce17 | ||
|
|
015d16f43f | ||
|
|
d680676d45 | ||
|
|
65fbc0575f | ||
|
|
540441fd38 | ||
|
|
c9722dceb2 | ||
|
|
1b1c018165 | ||
|
|
2cca07b44c | ||
|
|
f29ae0db76 | ||
|
|
b67b22f119 | ||
|
|
5cdff56731 | ||
|
|
eb65cbf002 | ||
|
|
e52c94640e | ||
|
|
014a31d11a | ||
|
|
f2fcb77808 | ||
|
|
984fdd6192 | ||
|
|
9abb041763 | ||
|
|
678c54d705 | ||
|
|
4ff2c5c4c9 | ||
|
|
026b1f96bf | ||
|
|
3b76a51f5f | ||
|
|
70434df105 | ||
|
|
d3c31c69a7 | ||
|
|
543c8daa6d | ||
|
|
7a045de6e0 | ||
|
|
5f7b024891 | ||
|
|
ee21c0042e | ||
|
|
c276117fef | ||
|
|
1d848641d7 | ||
|
|
d3a7196635 | ||
|
|
02be7ea2fc | ||
|
|
b1b21e0564 | ||
|
|
9d6b6a4aea | ||
|
|
7ba75e3d5a | ||
|
|
9edd964627 | ||
|
|
37f104f88f | ||
|
|
620b91f23e | ||
|
|
90cdf9dcac | ||
|
|
72b0d9d8c4 | ||
|
|
2270737344 | ||
|
|
44bdfb2d15 | ||
|
|
62191b08ea | ||
|
|
30b30b8fe0 | ||
|
|
5da63e045e | ||
|
|
6a4546d2c0 | ||
|
|
1c233ad986 | ||
|
|
151c281f36 | ||
|
|
d493d626ba | ||
|
|
0cfbe8f059 | ||
|
|
258e93bc86 | ||
|
|
03c643aa6b | ||
|
|
7635f6b9fa | ||
|
|
1af6c96cd0 | ||
|
|
a2383b3b12 | ||
|
|
7ef4c24f18 | ||
|
|
1ad3200094 | ||
|
|
98c93ca465 | ||
|
|
ee082ae402 | ||
|
|
ac67c3e0e7 | ||
|
|
ee7cdf3668 | ||
|
|
a6d421508a | ||
|
|
50df484d86 | ||
|
|
f69356f589 | ||
|
|
565f7a6e72 | ||
|
|
a37473ae60 | ||
|
|
6593a0f3d1 | ||
|
|
a1210d1e8d | ||
|
|
b961cd6208 | ||
|
|
f465d63b5d | ||
|
|
60d7b809c1 | ||
|
|
c576ad04ac | ||
|
|
7ffe736d20 | ||
|
|
c78409a598 | ||
|
|
29575dadc5 | ||
|
|
73958e357d | ||
|
|
776f497469 | ||
|
|
e1992c83de | ||
|
|
1147aaf23d | ||
|
|
4de2d6774a | ||
|
|
c2ad6f1047 | ||
|
|
816ef0ed30 | ||
|
|
f23f34d85d | ||
|
|
352ac2f271 | ||
|
|
eab6e31d34 | ||
|
|
c8f56f5712 | ||
|
|
3575d41009 | ||
|
|
6daa932f5c | ||
|
|
dd9f3a0104 | ||
|
|
aa17311063 | ||
|
|
e6b12e6de3 | ||
|
|
127097cd2b | ||
|
|
3f8b0da677 | ||
|
|
5579caf5a5 | ||
|
|
3fd164a224 | ||
|
|
a657d09879 | ||
|
|
f72f037be5 | ||
|
|
2149390195 | ||
|
|
4d93226f2c | ||
|
|
ca74f64a39 | ||
|
|
3dd0510ebe | ||
|
|
5f39dde894 | ||
|
|
add7906d7e | ||
|
|
cd866664a8 | ||
|
|
790252a979 | ||
|
|
632c94d438 | ||
|
|
0611233f16 | ||
|
|
68775d29e3 | ||
|
|
7403cd43c5 | ||
|
|
b314d78e97 | ||
|
|
53ca7e66ef | ||
|
|
38efc6f572 | ||
|
|
ad70107eb4 | ||
|
|
3097b9a9b7 | ||
|
|
ebf320ec22 | ||
|
|
a0c6db361c | ||
|
|
36f95e50a9 | ||
|
|
43101ccea0 | ||
|
|
38bbef7ec1 | ||
|
|
cb9cc29518 | ||
|
|
3fe628f04e | ||
|
|
f8446b42ab | ||
|
|
b9b5b932c5 | ||
|
|
71f0c19515 | ||
|
|
8b169aa47c | ||
|
|
50202d1391 | ||
|
|
8726ef34c1 | ||
|
|
7f458d5e78 | ||
|
|
0bc3a1f9e8 | ||
|
|
4f4c52a6c7 | ||
|
|
51b4963e2e | ||
|
|
876dbe3d26 | ||
|
|
861f8fab9b | ||
|
|
881f05f5a0 | ||
|
|
ef76365ec2 | ||
|
|
7ce647f27e | ||
|
|
4bd8a692d8 | ||
|
|
712b3e9e53 | ||
|
|
4ce56bac08 | ||
|
|
0604afcda7 | ||
|
|
7d9dc3c6a2 | ||
|
|
487e435679 | ||
|
|
0f426ce34d | ||
|
|
94eac4f00e | ||
|
|
885ca34748 | ||
|
|
a0e84c4fbc | ||
|
|
c959aaa19b | ||
|
|
755b524814 | ||
|
|
0cfed8c3cb | ||
|
|
770393a48c | ||
|
|
2bf5ea87d6 | ||
|
|
821c46edf1 | ||
|
|
d221a937df | ||
|
|
1a11967fd9 | ||
|
|
73a31789b4 | ||
|
|
a6e8d606b4 | ||
|
|
d6c79e16b2 | ||
|
|
b373c1de93 | ||
|
|
259c66d978 | ||
|
|
91a3314d36 | ||
|
|
2646f5a784 | ||
|
|
b6fba0c03f | ||
|
|
12a7833586 | ||
|
|
9e06ef66b9 | ||
|
|
5b1def9080 | ||
|
|
ad36c7b0d7 | ||
|
|
a833021132 | ||
|
|
5e4b5109dd | ||
|
|
15c60cbb26 | ||
|
|
928efc642c | ||
|
|
7256902fb0 | ||
|
|
7fca4324f9 | ||
|
|
94ea3bd3a5 | ||
|
|
5138d3954f | ||
|
|
690d7c10b8 | ||
|
|
35ba277a97 | ||
|
|
25b48a3e11 | ||
|
|
9c1efdf11b | ||
|
|
8f3a51f2b8 | ||
|
|
6a2a9b67e8 | ||
|
|
694df89331 | ||
|
|
8c3177d835 | ||
|
|
42e5ef4b01 | ||
|
|
9fa7977714 | ||
|
|
ce416d765f | ||
|
|
82c167aaca | ||
|
|
7f90d14f10 | ||
|
|
502554887f | ||
|
|
c3af72d950 | ||
|
|
ee4b208b8a | ||
|
|
430aca474c | ||
|
|
91f26b3b9b | ||
|
|
2fb4c60540 | ||
|
|
24ec17219b | ||
|
|
a331bbb3ae | ||
|
|
5353e38469 | ||
|
|
2396ac234c | ||
|
|
609daaf387 | ||
|
|
9c56b46886 | ||
|
|
d67ccb66c0 | ||
|
|
76430790b9 | ||
|
|
15da5834e1 | ||
|
|
132f275d04 | ||
|
|
db62090f88 | ||
|
|
1c7e1295dc | ||
|
|
2260864b45 | ||
|
|
b7fef8f693 | ||
|
|
9abf016af1 | ||
|
|
d9e8479c06 | ||
|
|
3cdf5945a2 | ||
|
|
f696a2b2a7 | ||
|
|
daa8157fc2 | ||
|
|
f56e6d231e | ||
|
|
1bf22c0b5b | ||
|
|
1d88865869 | ||
|
|
23014b6810 | ||
|
|
97dcae827b | ||
|
|
2e8dba571b | ||
|
|
bf5873022d | ||
|
|
5cffddebb9 | ||
|
|
933f2f4cfd | ||
|
|
94525aa0fd | ||
|
|
f6a419c26c | ||
|
|
7c52a35942 | ||
|
|
c45d6a865b | ||
|
|
a9db24cd05 | ||
|
|
ac4d4a65af | ||
|
|
8baba93fce | ||
|
|
51eadaf2b6 | ||
|
|
0d2ec832e2 | ||
|
|
715b199eeb | ||
|
|
66cd219b15 | ||
|
|
17372ac3da | ||
|
|
d156c74ec0 | ||
|
|
e9cd798bd3 | ||
|
|
70da715d8d | ||
|
|
93a7df500f | ||
|
|
6a573d62e0 | ||
|
|
d19bbee98d |
@@ -0,0 +1,77 @@
|
|||||||
|
name: "go: build dev binaries"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Delete old release assets
|
||||||
|
uses: mknejp/delete-release-assets@v1
|
||||||
|
with:
|
||||||
|
token: ${{ github.token }}
|
||||||
|
tag: dev
|
||||||
|
fail-if-no-assets: false
|
||||||
|
assets: |
|
||||||
|
weed-*
|
||||||
|
|
||||||
|
build_dev:
|
||||||
|
needs: cleanup
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
goos: [linux, windows, darwin, freebsd]
|
||||||
|
goarch: [amd64, arm, arm64]
|
||||||
|
exclude:
|
||||||
|
- goarch: arm
|
||||||
|
goos: darwin
|
||||||
|
- goarch: 386
|
||||||
|
goos: darwin
|
||||||
|
- goarch: arm
|
||||||
|
goos: windows
|
||||||
|
- goarch: arm64
|
||||||
|
goos: windows
|
||||||
|
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Check out code into the Go module directory
|
||||||
|
uses: actions/checkout@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.20
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
goos: ${{ matrix.goos }}
|
||||||
|
goarch: ${{ matrix.goarch }}
|
||||||
|
release_tag: dev
|
||||||
|
overwrite: true
|
||||||
|
pre_command: export CGO_ENABLED=0
|
||||||
|
build_flags: -tags 5BytesOffset # optional, default is
|
||||||
|
ldflags: -extldflags -static -X github.com/chrislusf/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||||
|
# Where to run `go build .`
|
||||||
|
project_path: weed
|
||||||
|
binary_name: weed-large-disk
|
||||||
|
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.20
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
goos: ${{ matrix.goos }}
|
||||||
|
goarch: ${{ matrix.goarch }}
|
||||||
|
release_tag: dev
|
||||||
|
overwrite: true
|
||||||
|
pre_command: export CGO_ENABLED=0
|
||||||
|
ldflags: -extldflags -static -X github.com/chrislusf/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||||
|
# Where to run `go build .`
|
||||||
|
project_path: weed
|
||||||
|
binary_name: weed-normal-disk
|
||||||
|
asset_name: "weed-${{ env.BUILD_TIME }}-${{ matrix.goos }}-${{ matrix.goarch }}"
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
# This is a basic workflow to help you get started with Actions
|
||||||
|
|
||||||
|
name: "go: build versioned binaries"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
|
||||||
|
# Allows you to run this workflow manually from the Actions tab
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
build-release-binaries:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
goos: [linux, windows, darwin, freebsd]
|
||||||
|
goarch: [amd64, arm, arm64]
|
||||||
|
exclude:
|
||||||
|
- goarch: arm
|
||||||
|
goos: darwin
|
||||||
|
- goarch: 386
|
||||||
|
goos: darwin
|
||||||
|
- goarch: arm
|
||||||
|
goos: windows
|
||||||
|
- goarch: arm64
|
||||||
|
goos: windows
|
||||||
|
|
||||||
|
# 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
|
||||||
|
- name: Go Release Binaries Normal Volume Size
|
||||||
|
uses: wangyoucao577/go-release-action@v1.20
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
goos: ${{ matrix.goos }}
|
||||||
|
goarch: ${{ matrix.goarch }}
|
||||||
|
overwrite: true
|
||||||
|
pre_command: export CGO_ENABLED=0
|
||||||
|
# build_flags: -tags 5BytesOffset # optional, default is
|
||||||
|
ldflags: -extldflags -static -X github.com/chrislusf/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||||
|
# Where to run `go build .`
|
||||||
|
project_path: weed
|
||||||
|
binary_name: weed
|
||||||
|
asset_name: "${{ matrix.goos }}_${{ matrix.goarch }}"
|
||||||
|
- name: Go Release Large Disk Binaries
|
||||||
|
uses: wangyoucao577/go-release-action@v1.20
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
goos: ${{ matrix.goos }}
|
||||||
|
goarch: ${{ matrix.goarch }}
|
||||||
|
overwrite: true
|
||||||
|
pre_command: export CGO_ENABLED=0
|
||||||
|
build_flags: -tags 5BytesOffset # optional, default is
|
||||||
|
ldflags: -extldflags -static -X github.com/chrislusf/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
||||||
|
# Where to run `go build .`
|
||||||
|
project_path: weed
|
||||||
|
binary_name: weed
|
||||||
|
asset_name: "${{ matrix.goos }}_${{ matrix.goarch }}_large_disk"
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
name: Cleanup
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
|
|
||||||
build:
|
|
||||||
name: Build
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
|
|
||||||
- name: Delete old release assets
|
|
||||||
uses: mknejp/delete-release-assets@v1
|
|
||||||
with:
|
|
||||||
token: ${{ github.token }}
|
|
||||||
tag: dev
|
|
||||||
fail-if-no-assets: false
|
|
||||||
assets: |
|
|
||||||
weed-*
|
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
name: "docker: build dev containers"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
workflow_dispatch: []
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
build-dev-containers:
|
||||||
|
runs-on: [ubuntu-latest]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
-
|
||||||
|
name: Docker meta
|
||||||
|
id: docker_meta
|
||||||
|
uses: docker/metadata-action@v3
|
||||||
|
with:
|
||||||
|
images: |
|
||||||
|
chrislusf/seaweedfs
|
||||||
|
ghcr.io/chrislusf/seaweedfs
|
||||||
|
tags: |
|
||||||
|
type=raw,value=dev
|
||||||
|
labels: |
|
||||||
|
org.opencontainers.image.title=seaweedfs
|
||||||
|
org.opencontainers.image.description=SeaweedFS is a distributed storage system for blobs, objects, files, and data lake, to store and serve billions of files fast!
|
||||||
|
org.opencontainers.image.vendor=Chris Lu
|
||||||
|
-
|
||||||
|
name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
with:
|
||||||
|
buildkitd-flags: "--debug"
|
||||||
|
-
|
||||||
|
name: Login to Docker Hub
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@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
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ secrets.GHCR_USERNAME }}
|
||||||
|
password: ${{ secrets.GHCR_TOKEN }}
|
||||||
|
-
|
||||||
|
name: Build
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: ./docker
|
||||||
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
file: ./docker/Dockerfile.go_build
|
||||||
|
platforms: linux/amd64, linux/arm, linux/arm64, linux/386
|
||||||
|
tags: ${{ steps.docker_meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.docker_meta.outputs.labels }}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
name: "docker: build latest container"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
workflow_dispatch: []
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
build-latest-container:
|
||||||
|
runs-on: [ubuntu-latest]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
-
|
||||||
|
name: Docker meta
|
||||||
|
id: docker_meta
|
||||||
|
uses: docker/metadata-action@v3
|
||||||
|
with:
|
||||||
|
images: |
|
||||||
|
chrislusf/seaweedfs
|
||||||
|
ghcr.io/chrislusf/seaweedfs
|
||||||
|
tags: |
|
||||||
|
type=raw,value=dev
|
||||||
|
labels: |
|
||||||
|
org.opencontainers.image.title=seaweedfs
|
||||||
|
org.opencontainers.image.description=SeaweedFS is a distributed storage system for blobs, objects, files, and data lake, to store and serve billions of files fast!
|
||||||
|
org.opencontainers.image.vendor=Chris Lu
|
||||||
|
-
|
||||||
|
name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
with:
|
||||||
|
buildkitd-flags: "--debug"
|
||||||
|
-
|
||||||
|
name: Login to Docker Hub
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@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
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ secrets.GHCR_USERNAME }}
|
||||||
|
password: ${{ secrets.GHCR_TOKEN }}
|
||||||
|
-
|
||||||
|
name: Build
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: ./docker
|
||||||
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
file: ./docker/Dockerfile.go_build
|
||||||
|
platforms: linux/amd64, linux/arm, linux/arm64, linux/386
|
||||||
|
tags: ${{ steps.docker_meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.docker_meta.outputs.labels }}
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
name: "docker: build release containers"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
workflow_dispatch: []
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-default-release-container:
|
||||||
|
runs-on: [ubuntu-latest]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
-
|
||||||
|
name: Docker meta
|
||||||
|
id: docker_meta
|
||||||
|
uses: docker/metadata-action@v3
|
||||||
|
with:
|
||||||
|
images: |
|
||||||
|
chrislusf/seaweedfs
|
||||||
|
ghcr.io/chrislusf/seaweedfs
|
||||||
|
tags: |
|
||||||
|
type=ref,event=tag
|
||||||
|
flavor: |
|
||||||
|
latest=false
|
||||||
|
labels: |
|
||||||
|
org.opencontainers.image.title=seaweedfs
|
||||||
|
org.opencontainers.image.description=SeaweedFS is a distributed storage system for blobs, objects, files, and data lake, to store and serve billions of files fast!
|
||||||
|
org.opencontainers.image.vendor=Chris Lu
|
||||||
|
-
|
||||||
|
name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
with:
|
||||||
|
buildkitd-flags: "--debug"
|
||||||
|
-
|
||||||
|
name: Login to Docker Hub
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@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
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ secrets.GHCR_USERNAME }}
|
||||||
|
password: ${{ secrets.GHCR_TOKEN }}
|
||||||
|
-
|
||||||
|
name: Build
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: ./docker
|
||||||
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
file: ./docker/Dockerfile.go_build
|
||||||
|
platforms: linux/amd64, linux/arm, linux/arm64, linux/386
|
||||||
|
tags: ${{ steps.docker_meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.docker_meta.outputs.labels }}
|
||||||
|
build-large-release-container:
|
||||||
|
runs-on: [ubuntu-latest]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
-
|
||||||
|
name: Docker meta
|
||||||
|
id: docker_meta
|
||||||
|
uses: docker/metadata-action@v3
|
||||||
|
with:
|
||||||
|
images: |
|
||||||
|
chrislusf/seaweedfs
|
||||||
|
ghcr.io/chrislusf/seaweedfs
|
||||||
|
tags: |
|
||||||
|
type=ref,event=tag,suffix=_large_disk
|
||||||
|
flavor: |
|
||||||
|
latest=false
|
||||||
|
labels: |
|
||||||
|
org.opencontainers.image.title=seaweedfs
|
||||||
|
org.opencontainers.image.description=SeaweedFS is a distributed storage system for blobs, objects, files, and data lake, to store and serve billions of files fast!
|
||||||
|
org.opencontainers.image.vendor=Chris Lu
|
||||||
|
-
|
||||||
|
name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
with:
|
||||||
|
buildkitd-flags: "--debug"
|
||||||
|
-
|
||||||
|
name: Login to Docker Hub
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@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
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ secrets.GHCR_USERNAME }}
|
||||||
|
password: ${{ secrets.GHCR_TOKEN }}
|
||||||
|
-
|
||||||
|
name: Build
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: ./docker
|
||||||
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
file: ./docker/Dockerfile.go_build_large
|
||||||
|
platforms: linux/amd64, linux/arm, linux/arm64, linux/386
|
||||||
|
tags: ${{ steps.docker_meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.docker_meta.outputs.labels }}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
name: Go
|
name: "go: build binary"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -6,6 +6,10 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.head_ref }}/go
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
build:
|
build:
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
name: Release
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
|
|
||||||
build:
|
|
||||||
name: Build
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
goos: [linux, windows, darwin, freebsd ]
|
|
||||||
goarch: [amd64, arm]
|
|
||||||
exclude:
|
|
||||||
- goarch: arm
|
|
||||||
goos: darwin
|
|
||||||
- goarch: arm
|
|
||||||
goos: windows
|
|
||||||
|
|
||||||
steps:
|
|
||||||
|
|
||||||
- name: Check out code into the Go module directory
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Wait for the deletion
|
|
||||||
uses: jakejarvis/wait-action@master
|
|
||||||
with:
|
|
||||||
time: '30s'
|
|
||||||
|
|
||||||
- name: Set BUILD_TIME env
|
|
||||||
run: echo BUILD_TIME=$(date -u +%Y-%m-%d-%H-%M) >> ${GITHUB_ENV}
|
|
||||||
|
|
||||||
- name: Go Release Binaries
|
|
||||||
uses: wangyoucao577/go-release-action@v1.14
|
|
||||||
with:
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
goos: ${{ matrix.goos }}
|
|
||||||
goarch: ${{ matrix.goarch }}
|
|
||||||
release_tag: dev
|
|
||||||
overwrite: true
|
|
||||||
build_flags: -tags 5BytesOffset # optional, default is
|
|
||||||
ldflags: -extldflags -static -X github.com/chrislusf/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
|
||||||
# Where to run `go build .`
|
|
||||||
project_path: weed
|
|
||||||
binary_name: weed-large-disk
|
|
||||||
asset_name: "weed-large-disk-${{ env.BUILD_TIME }}-${{ matrix.goos }}-${{ matrix.goarch }}"
|
|
||||||
|
|
||||||
- name: Go Release Binaries
|
|
||||||
uses: wangyoucao577/go-release-action@v1.14
|
|
||||||
with:
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
goos: ${{ matrix.goos }}
|
|
||||||
goarch: ${{ matrix.goarch }}
|
|
||||||
release_tag: dev
|
|
||||||
overwrite: true
|
|
||||||
ldflags: -extldflags -static -X github.com/chrislusf/seaweedfs/weed/util.COMMIT=${{github.sha}}
|
|
||||||
# Where to run `go build .`
|
|
||||||
project_path: weed
|
|
||||||
binary_name: weed-
|
|
||||||
asset_name: "weed-${{ env.BUILD_TIME }}-${{ matrix.goos }}-${{ matrix.goarch }}"
|
|
||||||
-47
@@ -1,47 +0,0 @@
|
|||||||
sudo: false
|
|
||||||
language: go
|
|
||||||
go:
|
|
||||||
- 1.14.x
|
|
||||||
- 1.15.x
|
|
||||||
|
|
||||||
before_install:
|
|
||||||
- export PATH=/home/travis/gopath/bin:$PATH
|
|
||||||
|
|
||||||
install:
|
|
||||||
- export CGO_ENABLED="0"
|
|
||||||
- go env
|
|
||||||
|
|
||||||
script:
|
|
||||||
- env GO111MODULE=on go test ./weed/...
|
|
||||||
|
|
||||||
before_deploy:
|
|
||||||
- make release
|
|
||||||
deploy:
|
|
||||||
provider: releases
|
|
||||||
skip_cleanup: true
|
|
||||||
api_key:
|
|
||||||
secure: ERL986+ncQ8lwAJUYDrQ8s2/FxF/cyNIwJIFCqspnWxQgGNNyokET9HapmlPSxjpFRF0q6L2WCg9OY3mSVRq4oI6hg1igOQ12KlLyN71XSJ3c8w0Ay5ho48TQ9l3f3Iu97mntBCe9l0R9pnT8wj1VI8YJxloXwUMG2yeTjA9aBI=
|
|
||||||
file:
|
|
||||||
- build/linux_arm.tar.gz
|
|
||||||
- build/linux_arm64.tar.gz
|
|
||||||
- build/linux_386.tar.gz
|
|
||||||
- build/linux_amd64.tar.gz
|
|
||||||
- build/linux_amd64_large_disk.tar.gz
|
|
||||||
- build/darwin_amd64.tar.gz
|
|
||||||
- build/darwin_amd64_large_disk.tar.gz
|
|
||||||
- build/windows_386.zip
|
|
||||||
- build/windows_amd64.zip
|
|
||||||
- build/windows_amd64_large_disk.zip
|
|
||||||
- build/freebsd_arm.tar.gz
|
|
||||||
- build/freebsd_amd64.tar.gz
|
|
||||||
- build/freebsd_386.tar.gz
|
|
||||||
- build/netbsd_arm.tar.gz
|
|
||||||
- build/netbsd_amd64.tar.gz
|
|
||||||
- build/netbsd_386.tar.gz
|
|
||||||
- build/openbsd_arm.tar.gz
|
|
||||||
- build/openbsd_amd64.tar.gz
|
|
||||||
- build/openbsd_386.tar.gz
|
|
||||||
on:
|
|
||||||
tags: true
|
|
||||||
repo: chrislusf/seaweedfs
|
|
||||||
go: 1.15.x
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
BINARY = weed/weed
|
|
||||||
package = github.com/chrislusf/seaweedfs/weed
|
|
||||||
|
|
||||||
GO_FLAGS = #-v
|
|
||||||
SOURCE_DIR = ./weed/
|
|
||||||
|
|
||||||
appname := weed
|
|
||||||
|
|
||||||
sources := $(wildcard *.go)
|
|
||||||
|
|
||||||
COMMIT ?= $(shell git rev-parse --short HEAD)
|
|
||||||
LDFLAGS ?= -X github.com/chrislusf/seaweedfs/weed/util.COMMIT=${COMMIT}
|
|
||||||
|
|
||||||
build = CGO_ENABLED=0 GOOS=$(1) GOARCH=$(2) go build -ldflags "-extldflags -static $(LDFLAGS)" -o build/$(appname)$(3) $(SOURCE_DIR)
|
|
||||||
tar = cd build && tar -cvzf $(1)_$(2).tar.gz $(appname)$(3) && rm $(appname)$(3)
|
|
||||||
zip = cd build && zip $(1)_$(2).zip $(appname)$(3) && rm $(appname)$(3)
|
|
||||||
|
|
||||||
build_large = CGO_ENABLED=0 GOOS=$(1) GOARCH=$(2) go build -tags 5BytesOffset -ldflags "-extldflags -static $(LDFLAGS)" -o build/$(appname)$(3) $(SOURCE_DIR)
|
|
||||||
tar_large = cd build && tar -cvzf $(1)_$(2)_large_disk.tar.gz $(appname)$(3) && rm $(appname)$(3)
|
|
||||||
zip_large = cd build && zip $(1)_$(2)_large_disk.zip $(appname)$(3) && rm $(appname)$(3)
|
|
||||||
|
|
||||||
all: build
|
|
||||||
|
|
||||||
.PHONY : clean deps build linux release windows_build darwin_build linux_build bsd_build clean
|
|
||||||
|
|
||||||
clean:
|
|
||||||
go clean -i $(GO_FLAGS) $(SOURCE_DIR)
|
|
||||||
rm -f $(BINARY)
|
|
||||||
rm -rf build/
|
|
||||||
|
|
||||||
deps:
|
|
||||||
go get $(GO_FLAGS) -d $(SOURCE_DIR)
|
|
||||||
rm -rf /home/travis/gopath/src/github.com/coreos/etcd/vendor/golang.org/x/net/trace
|
|
||||||
rm -rf /home/travis/gopath/src/go.etcd.io/etcd/vendor/golang.org/x/net/trace
|
|
||||||
|
|
||||||
build: deps
|
|
||||||
go build $(GO_FLAGS) -ldflags "$(LDFLAGS)" -o $(BINARY) $(SOURCE_DIR)
|
|
||||||
|
|
||||||
install: deps
|
|
||||||
go install $(GO_FLAGS) -ldflags "$(LDFLAGS)" $(SOURCE_DIR)
|
|
||||||
|
|
||||||
linux: deps
|
|
||||||
mkdir -p linux
|
|
||||||
GOOS=linux GOARCH=amd64 go build $(GO_FLAGS) -ldflags "$(LDFLAGS)" -o linux/$(BINARY) $(SOURCE_DIR)
|
|
||||||
|
|
||||||
release: deps windows_build darwin_build linux_build bsd_build 5_byte_linux_build 5_byte_arm64_build 5_byte_darwin_build 5_byte_windows_build
|
|
||||||
|
|
||||||
##### LINUX BUILDS #####
|
|
||||||
5_byte_linux_build:
|
|
||||||
$(call build_large,linux,amd64,)
|
|
||||||
$(call tar_large,linux,amd64)
|
|
||||||
|
|
||||||
5_byte_darwin_build:
|
|
||||||
$(call build_large,darwin,amd64,)
|
|
||||||
$(call tar_large,darwin,amd64)
|
|
||||||
|
|
||||||
5_byte_windows_build:
|
|
||||||
$(call build_large,windows,amd64,.exe)
|
|
||||||
$(call zip_large,windows,amd64,.exe)
|
|
||||||
|
|
||||||
5_byte_arm_build: $(sources)
|
|
||||||
$(call build_large,linux,arm,)
|
|
||||||
$(call tar_large,linux,arm)
|
|
||||||
|
|
||||||
5_byte_arm64_build: $(sources)
|
|
||||||
$(call build_large,linux,arm64,)
|
|
||||||
$(call tar_large,linux,arm64)
|
|
||||||
|
|
||||||
linux_build: build/linux_arm.tar.gz build/linux_arm64.tar.gz build/linux_386.tar.gz build/linux_amd64.tar.gz
|
|
||||||
|
|
||||||
build/linux_386.tar.gz: $(sources)
|
|
||||||
$(call build,linux,386,)
|
|
||||||
$(call tar,linux,386)
|
|
||||||
|
|
||||||
build/linux_amd64.tar.gz: $(sources)
|
|
||||||
$(call build,linux,amd64,)
|
|
||||||
$(call tar,linux,amd64)
|
|
||||||
|
|
||||||
build/linux_arm.tar.gz: $(sources)
|
|
||||||
$(call build,linux,arm,)
|
|
||||||
$(call tar,linux,arm)
|
|
||||||
|
|
||||||
build/linux_arm64.tar.gz: $(sources)
|
|
||||||
$(call build,linux,arm64,)
|
|
||||||
$(call tar,linux,arm64)
|
|
||||||
|
|
||||||
##### DARWIN (MAC) BUILDS #####
|
|
||||||
darwin_build: build/darwin_amd64.tar.gz
|
|
||||||
|
|
||||||
build/darwin_amd64.tar.gz: $(sources)
|
|
||||||
$(call build,darwin,amd64,)
|
|
||||||
$(call tar,darwin,amd64)
|
|
||||||
|
|
||||||
##### WINDOWS BUILDS #####
|
|
||||||
windows_build: build/windows_386.zip build/windows_amd64.zip
|
|
||||||
|
|
||||||
build/windows_386.zip: $(sources)
|
|
||||||
$(call build,windows,386,.exe)
|
|
||||||
$(call zip,windows,386,.exe)
|
|
||||||
|
|
||||||
build/windows_amd64.zip: $(sources)
|
|
||||||
$(call build,windows,amd64,.exe)
|
|
||||||
$(call zip,windows,amd64,.exe)
|
|
||||||
|
|
||||||
##### BSD BUILDS #####
|
|
||||||
bsd_build: build/freebsd_arm.tar.gz build/freebsd_386.tar.gz build/freebsd_amd64.tar.gz \
|
|
||||||
build/netbsd_arm.tar.gz build/netbsd_386.tar.gz build/netbsd_amd64.tar.gz \
|
|
||||||
build/openbsd_arm.tar.gz build/openbsd_386.tar.gz build/openbsd_amd64.tar.gz
|
|
||||||
|
|
||||||
build/freebsd_386.tar.gz: $(sources)
|
|
||||||
$(call build,freebsd,386,)
|
|
||||||
$(call tar,freebsd,386)
|
|
||||||
|
|
||||||
build/freebsd_amd64.tar.gz: $(sources)
|
|
||||||
$(call build,freebsd,amd64,)
|
|
||||||
$(call tar,freebsd,amd64)
|
|
||||||
|
|
||||||
build/freebsd_arm.tar.gz: $(sources)
|
|
||||||
$(call build,freebsd,arm,)
|
|
||||||
$(call tar,freebsd,arm)
|
|
||||||
|
|
||||||
build/netbsd_386.tar.gz: $(sources)
|
|
||||||
$(call build,netbsd,386,)
|
|
||||||
$(call tar,netbsd,386)
|
|
||||||
|
|
||||||
build/netbsd_amd64.tar.gz: $(sources)
|
|
||||||
$(call build,netbsd,amd64,)
|
|
||||||
$(call tar,netbsd,amd64)
|
|
||||||
|
|
||||||
build/netbsd_arm.tar.gz: $(sources)
|
|
||||||
$(call build,netbsd,arm,)
|
|
||||||
$(call tar,netbsd,arm)
|
|
||||||
|
|
||||||
build/openbsd_386.tar.gz: $(sources)
|
|
||||||
$(call build,openbsd,386,)
|
|
||||||
$(call tar,openbsd,386)
|
|
||||||
|
|
||||||
build/openbsd_amd64.tar.gz: $(sources)
|
|
||||||
$(call build,openbsd,amd64,)
|
|
||||||
$(call tar,openbsd,amd64)
|
|
||||||
|
|
||||||
build/openbsd_arm.tar.gz: $(sources)
|
|
||||||
$(call build,openbsd,arm,)
|
|
||||||
$(call tar,openbsd,arm)
|
|
||||||
@@ -3,10 +3,11 @@
|
|||||||
|
|
||||||
[](https://join.slack.com/t/seaweedfs/shared_invite/enQtMzI4MTMwMjU2MzA3LTEyYzZmZWYzOGQ3MDJlZWMzYmI0OTE4OTJiZjJjODBmMzUxNmYwODg0YjY3MTNlMjBmZDQ1NzQ5NDJhZWI2ZmY)
|
[](https://join.slack.com/t/seaweedfs/shared_invite/enQtMzI4MTMwMjU2MzA3LTEyYzZmZWYzOGQ3MDJlZWMzYmI0OTE4OTJiZjJjODBmMzUxNmYwODg0YjY3MTNlMjBmZDQ1NzQ5NDJhZWI2ZmY)
|
||||||
[](https://twitter.com/intent/follow?screen_name=seaweedfs)
|
[](https://twitter.com/intent/follow?screen_name=seaweedfs)
|
||||||
[](https://travis-ci.org/chrislusf/seaweedfs)
|
[](https://github.com/chrislusf/seaweedfs/actions/workflows/go.yml)
|
||||||
[](https://godoc.org/github.com/chrislusf/seaweedfs/weed)
|
[](https://godoc.org/github.com/chrislusf/seaweedfs/weed)
|
||||||
[](https://github.com/chrislusf/seaweedfs/wiki)
|
[](https://github.com/chrislusf/seaweedfs/wiki)
|
||||||
[](https://hub.docker.com/r/chrislusf/seaweedfs/)
|
[](https://hub.docker.com/r/chrislusf/seaweedfs/)
|
||||||
|
[](https://search.maven.org/search?q=g:com.github.chrislusf)
|
||||||
|
|
||||||
|
|
||||||

|

|
||||||
@@ -42,7 +43,9 @@ Your support will be really appreciated by me and other supporters!
|
|||||||
- [SeaweedFS on Twitter](https://twitter.com/SeaweedFS)
|
- [SeaweedFS on Twitter](https://twitter.com/SeaweedFS)
|
||||||
- [SeaweedFS Mailing List](https://groups.google.com/d/forum/seaweedfs)
|
- [SeaweedFS Mailing List](https://groups.google.com/d/forum/seaweedfs)
|
||||||
- [Wiki Documentation](https://github.com/chrislusf/seaweedfs/wiki)
|
- [Wiki Documentation](https://github.com/chrislusf/seaweedfs/wiki)
|
||||||
- [SeaweedFS Introduction Slides](https://www.slideshare.net/chrislusf/seaweedfs-introduction)
|
- [SeaweedFS White Paper](https://github.com/chrislusf/seaweedfs/wiki/SeaweedFS_Architecture.pdf)
|
||||||
|
- [SeaweedFS Introduction Slides 2021.5](https://docs.google.com/presentation/d/1DcxKWlINc-HNCjhYeERkpGXXm6nTCES8mi2W5G0Z4Ts/edit?usp=sharing)
|
||||||
|
- [SeaweedFS Introduction Slides 2019.3](https://www.slideshare.net/chrislusf/seaweedfs-introduction)
|
||||||
|
|
||||||
Table of Contents
|
Table of Contents
|
||||||
=================
|
=================
|
||||||
@@ -66,11 +69,15 @@ Table of Contents
|
|||||||
* [License](#license)
|
* [License](#license)
|
||||||
|
|
||||||
|
|
||||||
## Quick Start ##
|
## Quick Start for S3 API on Docker ##
|
||||||
|
|
||||||
|
`docker run -p 8333:8333 chrislusf/seaweedfs server -s3`
|
||||||
|
|
||||||
|
## Quick Start with single binary ##
|
||||||
* Download the latest binary from https://github.com/chrislusf/seaweedfs/releases and unzip a single binary file `weed` or `weed.exe`
|
* Download the latest binary from https://github.com/chrislusf/seaweedfs/releases and unzip a single binary file `weed` or `weed.exe`
|
||||||
* Run `weed server -dir=/some/data/dir -s3` to start one master, one volume server, one filer, and one S3 gateway.
|
* Run `weed server -dir=/some/data/dir -s3` to start one master, one volume server, one filer, and one S3 gateway.
|
||||||
|
|
||||||
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 thoudsands of machines. That is it!
|
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!
|
||||||
|
|
||||||
## Introduction ##
|
## Introduction ##
|
||||||
|
|
||||||
@@ -79,17 +86,33 @@ SeaweedFS is a simple and highly scalable distributed file system. There are two
|
|||||||
1. to store billions of files!
|
1. to store billions of files!
|
||||||
2. to serve the files fast!
|
2. to serve the files fast!
|
||||||
|
|
||||||
SeaweedFS started as an Object Store to handle small files efficiently. Instead of managing all file metadata in a central master, the central master only manages volumes on volume servers, and these volume servers manage files and their metadata. This relieves concurrency pressure from the central master and spreads file metadata into volume servers, allowing faster file access (O(1), usually just one disk read operation).
|
SeaweedFS started as an Object Store to handle small files efficiently.
|
||||||
|
Instead of managing all file metadata in a central master,
|
||||||
|
the central master only manages volumes on volume servers,
|
||||||
|
and these volume servers manage files and their metadata.
|
||||||
|
This relieves concurrency pressure from the central master and spreads file metadata into volume servers,
|
||||||
|
allowing faster file access (O(1), usually just one disk read operation).
|
||||||
|
|
||||||
SeaweedFS can transparently integrate with the cloud. With hot data on local cluster, and warm data on the cloud with O(1) access time, SeaweedFS can achieve both fast local access time and elastic cloud storage capacity. What's more, the cloud storage access API cost is minimized. Faster and Cheaper than direct cloud storage!
|
There is only 40 bytes of disk storage overhead for each file's metadata.
|
||||||
|
It is so simple with O(1) disk reads that you are welcome to challenge the performance with your actual use cases.
|
||||||
|
|
||||||
There is only 40 bytes of disk storage overhead for each file's metadata. It is so simple with O(1) disk reads that you are welcome to challenge the performance with your actual use cases.
|
SeaweedFS started by implementing [Facebook's Haystack design paper](http://www.usenix.org/event/osdi10/tech/full_papers/Beaver.pdf).
|
||||||
|
Also, SeaweedFS implements erasure coding with ideas from
|
||||||
|
[f4: Facebook’s Warm BLOB Storage System](https://www.usenix.org/system/files/conference/osdi14/osdi14-paper-muralidhar.pdf), and has a lot of similarities with [Facebook’s Tectonic Filesystem](https://www.usenix.org/system/files/fast21-pan.pdf)
|
||||||
|
|
||||||
SeaweedFS started by implementing [Facebook's Haystack design paper](http://www.usenix.org/event/osdi10/tech/full_papers/Beaver.pdf). Also, SeaweedFS implements erasure coding with ideas from [f4: Facebook’s Warm BLOB Storage System](https://www.usenix.org/system/files/conference/osdi14/osdi14-paper-muralidhar.pdf)
|
On top of the object store, optional [Filer] can support directories and POSIX attributes.
|
||||||
|
Filer is a separate linearly-scalable stateless server with customizable metadata stores,
|
||||||
|
e.g., MySql, Postgres, Redis, Cassandra, HBase, Mongodb, Elastic Search, LevelDB, RocksDB, Sqlite, MemSql, TiDB, Etcd, CockroachDB, etc.
|
||||||
|
|
||||||
On top of the object store, optional [Filer] can support directories and POSIX attributes. Filer is a separate linearly-scalable stateless server with customizable metadata stores, e.g., MySql, Postgres, Redis, Cassandra, HBase, Mongodb, Elastic Search, LevelDB, RocksDB, MemSql, TiDB, Etcd, CockroachDB, etc.
|
For any distributed key value stores, the large values can be offloaded to SeaweedFS.
|
||||||
|
With the fast access speed and linearly scalable capacity,
|
||||||
|
SeaweedFS can work as a distributed [Key-Large-Value store][KeyLargeValueStore].
|
||||||
|
|
||||||
For any distributed key value stores, the large values can be offloaded to SeaweedFS. With the fast access speed and linearly scalable capacity, SeaweedFS can work as a distributed [Key-Large-Value store][KeyLargeValueStore].
|
SeaweedFS can transparently integrate with the cloud.
|
||||||
|
With hot data on local cluster, and warm data on the cloud with O(1) access time,
|
||||||
|
SeaweedFS can achieve both fast local access time and elastic cloud storage capacity.
|
||||||
|
What's more, the cloud storage access API cost is minimized.
|
||||||
|
Faster and Cheaper than direct cloud storage!
|
||||||
|
|
||||||
[Back to TOC](#table-of-contents)
|
[Back to TOC](#table-of-contents)
|
||||||
|
|
||||||
@@ -105,6 +128,7 @@ For any distributed key value stores, the large values can be offloaded to Seawe
|
|||||||
* Support ETag, Accept-Range, Last-Modified, etc.
|
* Support ETag, Accept-Range, Last-Modified, etc.
|
||||||
* Support in-memory/leveldb/readonly mode tuning for memory/performance balance.
|
* Support in-memory/leveldb/readonly mode tuning for memory/performance balance.
|
||||||
* Support rebalancing the writable and readonly volumes.
|
* Support rebalancing the writable and readonly volumes.
|
||||||
|
* [Customizable Multiple Storage Tiers][TieredStorage]: Customizable storage disk types to balance performance and cost.
|
||||||
* [Transparent cloud integration][CloudTier]: unlimited capacity via tiered cloud storage for warm data.
|
* [Transparent cloud integration][CloudTier]: unlimited capacity via tiered cloud storage for warm data.
|
||||||
* [Erasure Coding for warm storage][ErasureCoding] Rack-Aware 10.4 erasure coding reduces storage cost and increases availability.
|
* [Erasure Coding for warm storage][ErasureCoding] Rack-Aware 10.4 erasure coding reduces storage cost and increases availability.
|
||||||
|
|
||||||
@@ -122,6 +146,8 @@ For any distributed key value stores, the large values can be offloaded to Seawe
|
|||||||
* [WebDAV] accesses as a mapped drive on Mac and Windows, or from mobile devices.
|
* [WebDAV] accesses as a mapped drive on Mac and Windows, or from mobile devices.
|
||||||
* [AES256-GCM Encrypted Storage][FilerDataEncryption] safely stores the encrypted data.
|
* [AES256-GCM Encrypted Storage][FilerDataEncryption] safely stores the encrypted data.
|
||||||
* [Super Large Files][SuperLargeFiles] stores large or super large files in tens of TB.
|
* [Super Large Files][SuperLargeFiles] stores large or super large files in tens of TB.
|
||||||
|
* [Cloud Drive][CloudDrive] mounts cloud storage to local cluster, cached for fast read and write with asynchronous write back.
|
||||||
|
* [Gateway to Remote Object Store][GatewayToRemoteObjectStore] mirrors bucket operations to remote object storage, in addition to [Cloud Drive][CloudDrive]
|
||||||
|
|
||||||
## Kubernetes ##
|
## Kubernetes ##
|
||||||
* [Kubernetes CSI Driver][SeaweedFsCsiDriver] A Container Storage Interface (CSI) Driver. [](https://hub.docker.com/r/chrislusf/seaweedfs-csi-driver/)
|
* [Kubernetes CSI Driver][SeaweedFsCsiDriver] A Container Storage Interface (CSI) Driver. [](https://hub.docker.com/r/chrislusf/seaweedfs-csi-driver/)
|
||||||
@@ -135,6 +161,7 @@ For any distributed key value stores, the large values can be offloaded to Seawe
|
|||||||
[Hadoop]: https://github.com/chrislusf/seaweedfs/wiki/Hadoop-Compatible-File-System
|
[Hadoop]: https://github.com/chrislusf/seaweedfs/wiki/Hadoop-Compatible-File-System
|
||||||
[WebDAV]: https://github.com/chrislusf/seaweedfs/wiki/WebDAV
|
[WebDAV]: https://github.com/chrislusf/seaweedfs/wiki/WebDAV
|
||||||
[ErasureCoding]: https://github.com/chrislusf/seaweedfs/wiki/Erasure-coding-for-warm-storage
|
[ErasureCoding]: https://github.com/chrislusf/seaweedfs/wiki/Erasure-coding-for-warm-storage
|
||||||
|
[TieredStorage]: https://github.com/chrislusf/seaweedfs/wiki/Tiered-Storage
|
||||||
[CloudTier]: https://github.com/chrislusf/seaweedfs/wiki/Cloud-Tier
|
[CloudTier]: https://github.com/chrislusf/seaweedfs/wiki/Cloud-Tier
|
||||||
[FilerDataEncryption]: https://github.com/chrislusf/seaweedfs/wiki/Filer-Data-Encryption
|
[FilerDataEncryption]: https://github.com/chrislusf/seaweedfs/wiki/Filer-Data-Encryption
|
||||||
[FilerTTL]: https://github.com/chrislusf/seaweedfs/wiki/Filer-Stores
|
[FilerTTL]: https://github.com/chrislusf/seaweedfs/wiki/Filer-Stores
|
||||||
@@ -143,6 +170,9 @@ For any distributed key value stores, the large values can be offloaded to Seawe
|
|||||||
[ActiveActiveAsyncReplication]: https://github.com/chrislusf/seaweedfs/wiki/Filer-Active-Active-cross-cluster-continuous-synchronization
|
[ActiveActiveAsyncReplication]: https://github.com/chrislusf/seaweedfs/wiki/Filer-Active-Active-cross-cluster-continuous-synchronization
|
||||||
[FilerStoreReplication]: https://github.com/chrislusf/seaweedfs/wiki/Filer-Store-Replication
|
[FilerStoreReplication]: https://github.com/chrislusf/seaweedfs/wiki/Filer-Store-Replication
|
||||||
[KeyLargeValueStore]: https://github.com/chrislusf/seaweedfs/wiki/Filer-as-a-Key-Large-Value-Store
|
[KeyLargeValueStore]: https://github.com/chrislusf/seaweedfs/wiki/Filer-as-a-Key-Large-Value-Store
|
||||||
|
[CloudDrive]: https://github.com/chrislusf/seaweedfs/wiki/Cloud-Drive-Architecture
|
||||||
|
[GatewayToRemoteObjectStore]: https://github.com/chrislusf/seaweedfs/wiki/Gateway-to-Remote-Object-Storage
|
||||||
|
|
||||||
|
|
||||||
[Back to TOC](#table-of-contents)
|
[Back to TOC](#table-of-contents)
|
||||||
|
|
||||||
@@ -296,7 +326,7 @@ When requesting a file key, an optional "dataCenter" parameter can limit the ass
|
|||||||
|
|
||||||
[Back to TOC](#table-of-contents)
|
[Back to TOC](#table-of-contents)
|
||||||
|
|
||||||
## Architecture ##
|
## Object Store Architecture ##
|
||||||
|
|
||||||
Usually distributed file systems split each file into chunks, a central master keeps a mapping of filenames, chunk indices to chunk handles, and also which chunks each chunk server has.
|
Usually distributed file systems split each file into chunks, a central master keeps a mapping of filenames, chunk indices to chunk handles, and also which chunks each chunk server has.
|
||||||
|
|
||||||
@@ -374,7 +404,7 @@ The architectures are mostly the same. SeaweedFS aims to store and read files fa
|
|||||||
|
|
||||||
* SeaweedFS optimizes for small files, ensuring O(1) disk seek operation, and can also handle large files.
|
* SeaweedFS optimizes for small files, ensuring O(1) disk seek operation, and can also handle large files.
|
||||||
* SeaweedFS statically assigns a volume id for a file. Locating file content becomes just a lookup of the volume id, which can be easily cached.
|
* SeaweedFS statically assigns a volume id for a file. Locating file content becomes just a lookup of the volume id, which can be easily cached.
|
||||||
* SeaweedFS Filer metadata store can be any well-known and proven data stores, e.g., Redis, Cassandra, HBase, Mongodb, Elastic Search, MySql, Postgres, MemSql, TiDB, CockroachDB, Etcd etc, and is easy to customized.
|
* SeaweedFS Filer metadata store can be any well-known and proven data stores, e.g., Redis, Cassandra, HBase, Mongodb, Elastic Search, MySql, Postgres, Sqlite, MemSql, TiDB, CockroachDB, Etcd etc, and is easy to customized.
|
||||||
* SeaweedFS Volume server also communicates directly with clients via HTTP, supporting range queries, direct uploads, etc.
|
* SeaweedFS Volume server also communicates directly with clients via HTTP, supporting range queries, direct uploads, etc.
|
||||||
|
|
||||||
| System | File Metadata | File Content Read| POSIX | REST API | Optimized for large number of small files |
|
| System | File Metadata | File Content Read| POSIX | REST API | Optimized for large number of small files |
|
||||||
@@ -412,11 +442,11 @@ SeaweedFS has a centralized master group to look up free volumes, while Ceph use
|
|||||||
|
|
||||||
Same as SeaweedFS, Ceph is also based on the object store RADOS. Ceph is rather complicated with mixed reviews.
|
Same as SeaweedFS, Ceph is also based on the object store RADOS. Ceph is rather complicated with mixed reviews.
|
||||||
|
|
||||||
Ceph uses CRUSH hashing to automatically manage the data placement, which is efficient to locate the data. But the data has to be placed according to the CRUSH algorithm. Any wrong configuration would cause data loss. SeaweedFS places data by assigning them to any writable volumes. If writes to one volume failed, just pick another volume to write. Adding more volumes are also as simple as it can be.
|
Ceph uses CRUSH hashing to automatically manage the data placement, which is efficient to locate the data. But the data has to be placed according to the CRUSH algorithm. Any wrong configuration would cause data loss. Topology changes, such as adding new servers to increase capacity, will cause data migration with high IO cost to fit the CRUSH algorithm. SeaweedFS places data by assigning them to any writable volumes. If writes to one volume failed, just pick another volume to write. Adding more volumes are also as simple as it can be.
|
||||||
|
|
||||||
SeaweedFS is optimized for small files. Small files are stored as one continuous block of content, with at most 8 unused bytes between files. Small file access is O(1) disk read.
|
SeaweedFS is optimized for small files. Small files are stored as one continuous block of content, with at most 8 unused bytes between files. Small file access is O(1) disk read.
|
||||||
|
|
||||||
SeaweedFS Filer uses off-the-shelf stores, such as MySql, Postgres, Mongodb, Redis, Elastic Search, Cassandra, HBase, MemSql, TiDB, CockroachCB, Etcd, to manage file directories. These stores are proven, scalable, and easier to manage.
|
SeaweedFS Filer uses off-the-shelf stores, such as MySql, Postgres, Sqlite, Mongodb, Redis, Elastic Search, Cassandra, HBase, MemSql, TiDB, CockroachCB, Etcd, to manage file directories. These stores are proven, scalable, and easier to manage.
|
||||||
|
|
||||||
| SeaweedFS | comparable to Ceph | advantage |
|
| SeaweedFS | comparable to Ceph | advantage |
|
||||||
| ------------- | ------------- | ---------------- |
|
| ------------- | ------------- | ---------------- |
|
||||||
@@ -562,6 +592,7 @@ The text of this page is available for modification and reuse under the terms of
|
|||||||
|
|
||||||
[Back to TOC](#table-of-contents)
|
[Back to TOC](#table-of-contents)
|
||||||
|
|
||||||
## Stargazers over time ##
|
## Stargazers over time
|
||||||
|
|
||||||
|
[](https://starchart.cc/chrislusf/seaweedfs)
|
||||||
|
|
||||||
[](https://starcharts.herokuapp.com/chrislusf/seaweedfs)
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
<h1 align="center">Sponsors & Backers</h1>
|
<h1 align="center">Sponsors & Backers</h1>
|
||||||
|
|
||||||
- [Become a backer or sponsor on Patreon](https://www.patreon.com/seaweedfs).
|
- [Become a backer or sponsor on Patreon](https://www.patreon.com/seaweedfs).
|
||||||
@@ -12,3 +13,4 @@
|
|||||||
|
|
||||||
- [ColorfulClouds Tech Co. Ltd.](https://caiyunai.com/)
|
- [ColorfulClouds Tech Co. Ltd.](https://caiyunai.com/)
|
||||||
- [Haravan - Ecommerce Platform](https://www.haravan.com)
|
- [Haravan - Ecommerce Platform](https://www.haravan.com)
|
||||||
|
- PeterCxy - Creator of Shelter App
|
||||||
|
|||||||
+9
-2
@@ -1,11 +1,16 @@
|
|||||||
FROM alpine
|
FROM alpine
|
||||||
|
|
||||||
|
# 'latest' or 'dev'
|
||||||
|
ARG RELEASE=latest
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
ARCH=$(if [ $(uname -m) == "x86_64" ] && [ $(getconf LONG_BIT) == "64" ]; then echo "amd64"; \
|
ARCH=$(if [ $(uname -m) == "x86_64" ] && [ $(getconf LONG_BIT) == "64" ]; then echo "amd64"; \
|
||||||
elif [ $(uname -m) == "x86_64" ] && [ $(getconf LONG_BIT) == "32" ]; then echo "386"; \
|
elif [ $(uname -m) == "x86_64" ] && [ $(getconf LONG_BIT) == "32" ]; then echo "386"; \
|
||||||
elif [ $(uname -m) == "aarch64" ]; then echo "arm64"; \
|
elif [ $(uname -m) == "aarch64" ]; then echo "arm64"; \
|
||||||
elif [ $(uname -m) == "armv7l" ]; then echo "arm"; \
|
elif [ $(uname -m) == "armv7l" ]; then echo "arm"; \
|
||||||
elif [ $(uname -m) == "armv6l" ]; then echo "arm"; fi;) && \
|
elif [ $(uname -m) == "armv6l" ]; then echo "arm"; \
|
||||||
|
elif [ $(uname -m) == "s390x" ]; then echo "s390x"; \
|
||||||
|
elif [ $(uname -m) == "ppc64le" ]; then echo "ppc64le"; fi;) && \
|
||||||
echo "Building for $ARCH" 1>&2 && \
|
echo "Building for $ARCH" 1>&2 && \
|
||||||
SUPERCRONIC_SHA1SUM=$(echo $ARCH | sed 's/386/e0126b0102b9f388ecd55714358e3ad60d0cebdb/g' | sed 's/amd64/5ddf8ea26b56d4a7ff6faecdd8966610d5cb9d85/g' | sed 's/arm64/e2714c43e7781bf1579c85aa61259245f56dbba1/g' | sed 's/arm/47481c3341bc3a1ae91a728e0cc63c8e6d3791ad/g') && \
|
SUPERCRONIC_SHA1SUM=$(echo $ARCH | sed 's/386/e0126b0102b9f388ecd55714358e3ad60d0cebdb/g' | sed 's/amd64/5ddf8ea26b56d4a7ff6faecdd8966610d5cb9d85/g' | sed 's/arm64/e2714c43e7781bf1579c85aa61259245f56dbba1/g' | sed 's/arm/47481c3341bc3a1ae91a728e0cc63c8e6d3791ad/g') && \
|
||||||
SUPERCRONIC_URL=https://github.com/aptible/supercronic/releases/download/v0.1.9/supercronic-linux-$ARCH && \
|
SUPERCRONIC_URL=https://github.com/aptible/supercronic/releases/download/v0.1.9/supercronic-linux-$ARCH && \
|
||||||
@@ -13,7 +18,7 @@ RUN \
|
|||||||
# Install SeaweedFS and Supercronic ( for cron job mode )
|
# Install SeaweedFS and Supercronic ( for cron job mode )
|
||||||
apk add --no-cache --virtual build-dependencies --update wget curl ca-certificates && \
|
apk add --no-cache --virtual build-dependencies --update wget curl ca-certificates && \
|
||||||
apk add fuse && \
|
apk add fuse && \
|
||||||
wget -P /tmp https://github.com/$(curl -s -L https://github.com/chrislusf/seaweedfs/releases/latest | egrep -o "chrislusf/seaweedfs/releases/download/.*/linux_$ARCH.tar.gz") && \
|
wget -P /tmp https://github.com/$(curl -s -L https://github.com/chrislusf/seaweedfs/releases/${RELEASE} | egrep -o "chrislusf/seaweedfs/releases/download/.*/linux_$ARCH.tar.gz" | head -n 1) && \
|
||||||
tar -C /usr/bin/ -xzvf /tmp/linux_$ARCH.tar.gz && \
|
tar -C /usr/bin/ -xzvf /tmp/linux_$ARCH.tar.gz && \
|
||||||
curl -fsSLO "$SUPERCRONIC_URL" && \
|
curl -fsSLO "$SUPERCRONIC_URL" && \
|
||||||
echo "${SUPERCRONIC_SHA1SUM} ${SUPERCRONIC}" | sha1sum -c - && \
|
echo "${SUPERCRONIC_SHA1SUM} ${SUPERCRONIC}" | sha1sum -c - && \
|
||||||
@@ -37,6 +42,8 @@ EXPOSE 19333
|
|||||||
EXPOSE 9333
|
EXPOSE 9333
|
||||||
# s3 server http port
|
# s3 server http port
|
||||||
EXPOSE 8333
|
EXPOSE 8333
|
||||||
|
# webdav server http port
|
||||||
|
EXPOSE 7333
|
||||||
|
|
||||||
RUN mkdir -p /data/filerldb2
|
RUN mkdir -p /data/filerldb2
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
FROM gcc:11 as builder
|
||||||
|
RUN mkdir -p /go/src/github.com/chrislusf/
|
||||||
|
RUN git clone https://github.com/chrislusf/seaweedfs /go/src/github.com/chrislusf/seaweedfs
|
||||||
|
ARG BRANCH=${BRANCH:-master}
|
||||||
|
RUN cd /go/src/github.com/chrislusf/seaweedfs && git checkout $BRANCH
|
||||||
|
RUN cd /go/src/github.com/chrislusf/seaweedfs/weed \
|
||||||
|
&& apt-get update \
|
||||||
|
&& apt-get install -y golang-src \
|
||||||
|
&& export LDFLAGS="-X github.com/chrislusf/seaweedfs/weed/util.COMMIT=$(git rev-parse --short HEAD)" \
|
||||||
|
&& CGO_ENABLED=0 go install -ldflags "-extldflags -static ${LDFLAGS}" -compiler=gccgo -tags gccgo,noasm
|
||||||
|
|
||||||
|
FROM alpine AS final
|
||||||
|
LABEL author="Chris Lu"
|
||||||
|
COPY --from=builder /go/bin/weed /usr/bin/
|
||||||
|
RUN mkdir -p /etc/seaweedfs
|
||||||
|
COPY --from=builder /go/src/github.com/chrislusf/seaweedfs/docker/filer.toml /etc/seaweedfs/filer.toml
|
||||||
|
COPY --from=builder /go/src/github.com/chrislusf/seaweedfs/docker/entrypoint.sh /entrypoint.sh
|
||||||
|
RUN apk add fuse # for weed mount
|
||||||
|
|
||||||
|
# volume server gprc port
|
||||||
|
EXPOSE 18080
|
||||||
|
# volume server http port
|
||||||
|
EXPOSE 8080
|
||||||
|
# filer server gprc port
|
||||||
|
EXPOSE 18888
|
||||||
|
# filer server http port
|
||||||
|
EXPOSE 8888
|
||||||
|
# master server shared gprc port
|
||||||
|
EXPOSE 19333
|
||||||
|
# master server shared http port
|
||||||
|
EXPOSE 9333
|
||||||
|
# s3 server http port
|
||||||
|
EXPOSE 8333
|
||||||
|
# webdav server http port
|
||||||
|
EXPOSE 7333
|
||||||
|
|
||||||
|
RUN mkdir -p /data/filerldb2
|
||||||
|
|
||||||
|
VOLUME /data
|
||||||
|
|
||||||
|
RUN chmod +x /entrypoint.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["/entrypoint.sh"]
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
FROM frolvlad/alpine-glibc as builder
|
FROM amd64/golang:1.17-alpine as builder
|
||||||
RUN apk add git go g++ fuse
|
RUN apk add git g++ fuse
|
||||||
RUN mkdir -p /go/src/github.com/chrislusf/
|
RUN mkdir -p /go/src/github.com/chrislusf/
|
||||||
RUN git clone https://github.com/chrislusf/seaweedfs /go/src/github.com/chrislusf/seaweedfs
|
RUN git clone https://github.com/chrislusf/seaweedfs /go/src/github.com/chrislusf/seaweedfs
|
||||||
ARG BRANCH=${BRANCH:-master}
|
ARG BRANCH=${BRANCH:-master}
|
||||||
RUN cd /go/src/github.com/chrislusf/seaweedfs && git checkout $BRANCH
|
RUN cd /go/src/github.com/chrislusf/seaweedfs && git checkout $BRANCH
|
||||||
RUN cd /go/src/github.com/chrislusf/seaweedfs/weed \
|
RUN cd /go/src/github.com/chrislusf/seaweedfs/weed \
|
||||||
&& export LDFLAGS="-X github.com/chrislusf/seaweedfs/weed/util.COMMIT=$(git rev-parse --short HEAD)" \
|
&& export LDFLAGS="-X github.com/chrislusf/seaweedfs/weed/util.COMMIT=$(git rev-parse --short HEAD)" \
|
||||||
&& go install -ldflags "${LDFLAGS}"
|
&& CGO_ENABLED=0 go install -ldflags "-extldflags -static ${LDFLAGS}"
|
||||||
|
|
||||||
FROM alpine AS final
|
FROM alpine AS final
|
||||||
LABEL author="Chris Lu"
|
LABEL author="Chris Lu"
|
||||||
COPY --from=builder /root/go/bin/weed /usr/bin/
|
COPY --from=builder /go/bin/weed /usr/bin/
|
||||||
RUN mkdir -p /etc/seaweedfs
|
RUN mkdir -p /etc/seaweedfs
|
||||||
COPY --from=builder /go/src/github.com/chrislusf/seaweedfs/docker/filer.toml /etc/seaweedfs/filer.toml
|
COPY --from=builder /go/src/github.com/chrislusf/seaweedfs/docker/filer.toml /etc/seaweedfs/filer.toml
|
||||||
COPY --from=builder /go/src/github.com/chrislusf/seaweedfs/docker/entrypoint.sh /entrypoint.sh
|
COPY --from=builder /go/src/github.com/chrislusf/seaweedfs/docker/entrypoint.sh /entrypoint.sh
|
||||||
@@ -30,6 +30,8 @@ EXPOSE 19333
|
|||||||
EXPOSE 9333
|
EXPOSE 9333
|
||||||
# s3 server http port
|
# s3 server http port
|
||||||
EXPOSE 8333
|
EXPOSE 8333
|
||||||
|
# webdav server http port
|
||||||
|
EXPOSE 7333
|
||||||
|
|
||||||
RUN mkdir -p /data/filerldb2
|
RUN mkdir -p /data/filerldb2
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
FROM frolvlad/alpine-glibc as builder
|
FROM amd64/golang:1.17-alpine as builder
|
||||||
RUN apk add git go g++ fuse
|
RUN apk add git g++ fuse
|
||||||
RUN mkdir -p /go/src/github.com/chrislusf/
|
RUN mkdir -p /go/src/github.com/chrislusf/
|
||||||
RUN git clone https://github.com/chrislusf/seaweedfs /go/src/github.com/chrislusf/seaweedfs
|
RUN git clone https://github.com/chrislusf/seaweedfs /go/src/github.com/chrislusf/seaweedfs
|
||||||
ARG BRANCH=${BRANCH:-master}
|
ARG BRANCH=${BRANCH:-master}
|
||||||
RUN cd /go/src/github.com/chrislusf/seaweedfs && git checkout $BRANCH
|
RUN cd /go/src/github.com/chrislusf/seaweedfs && git checkout $BRANCH
|
||||||
RUN cd /go/src/github.com/chrislusf/seaweedfs/weed \
|
RUN cd /go/src/github.com/chrislusf/seaweedfs/weed \
|
||||||
&& export LDFLAGS="-X github.com/chrislusf/seaweedfs/weed/util.COMMIT=$(git rev-parse --short HEAD)" \
|
&& export LDFLAGS="-X github.com/chrislusf/seaweedfs/weed/util.COMMIT=$(git rev-parse --short HEAD)" \
|
||||||
&& go install -tags 5BytesOffset -ldflags "${LDFLAGS}"
|
&& CGO_ENABLED=0 go install -tags 5BytesOffset -ldflags "-extldflags -static ${LDFLAGS}"
|
||||||
|
|
||||||
FROM alpine AS final
|
FROM alpine AS final
|
||||||
LABEL author="Chris Lu"
|
LABEL author="Chris Lu"
|
||||||
COPY --from=builder /root/go/bin/weed /usr/bin/
|
COPY --from=builder /go/bin/weed /usr/bin/
|
||||||
RUN mkdir -p /etc/seaweedfs
|
RUN mkdir -p /etc/seaweedfs
|
||||||
COPY --from=builder /go/src/github.com/chrislusf/seaweedfs/docker/filer.toml /etc/seaweedfs/filer.toml
|
COPY --from=builder /go/src/github.com/chrislusf/seaweedfs/docker/filer.toml /etc/seaweedfs/filer.toml
|
||||||
COPY --from=builder /go/src/github.com/chrislusf/seaweedfs/docker/entrypoint.sh /entrypoint.sh
|
COPY --from=builder /go/src/github.com/chrislusf/seaweedfs/docker/entrypoint.sh /entrypoint.sh
|
||||||
@@ -30,6 +30,8 @@ EXPOSE 19333
|
|||||||
EXPOSE 9333
|
EXPOSE 9333
|
||||||
# s3 server http port
|
# s3 server http port
|
||||||
EXPOSE 8333
|
EXPOSE 8333
|
||||||
|
# webdav server http port
|
||||||
|
EXPOSE 7333
|
||||||
|
|
||||||
RUN mkdir -p /data/filerldb2
|
RUN mkdir -p /data/filerldb2
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ EXPOSE 19333
|
|||||||
EXPOSE 9333
|
EXPOSE 9333
|
||||||
# s3 server http port
|
# s3 server http port
|
||||||
EXPOSE 8333
|
EXPOSE 8333
|
||||||
|
# webdav server http port
|
||||||
|
EXPOSE 7333
|
||||||
|
|
||||||
RUN mkdir -p /data/filerldb2
|
RUN mkdir -p /data/filerldb2
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
FROM ubuntu:20.04
|
||||||
|
|
||||||
|
RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
git \
|
||||||
|
sudo \
|
||||||
|
debianutils \
|
||||||
|
python3-pip \
|
||||||
|
python3-virtualenv \
|
||||||
|
python3-dev \
|
||||||
|
libevent-dev \
|
||||||
|
libffi-dev \
|
||||||
|
libxml2-dev \
|
||||||
|
libxslt-dev \
|
||||||
|
zlib1g-dev && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get clean && \
|
||||||
|
rm -rf /var/lib/apt/lists/* && \
|
||||||
|
git clone https://github.com/ceph/s3-tests.git /opt/s3-tests
|
||||||
|
|
||||||
|
WORKDIR /opt/s3-tests
|
||||||
|
RUN ./bootstrap
|
||||||
|
|
||||||
|
ENV \
|
||||||
|
NOSETESTS_EXCLUDE="" \
|
||||||
|
NOSETESTS_ATTR="" \
|
||||||
|
NOSETESTS_OPTIONS="" \
|
||||||
|
S3TEST_CONF="/s3test.conf"
|
||||||
|
|
||||||
|
ENTRYPOINT ["/bin/bash", "-c"]
|
||||||
|
CMD ["sleep 10 && exec ./virtualenv/bin/nosetests ${NOSETESTS_OPTIONS-} ${NOSETESTS_ATTR:+-a $NOSETESTS_ATTR} ${NOSETESTS_EXCLUDE:+-e $NOSETESTS_EXCLUDE}"]
|
||||||
+41
-10
@@ -4,34 +4,65 @@ all: gen
|
|||||||
|
|
||||||
gen: dev
|
gen: dev
|
||||||
|
|
||||||
build:
|
binary:
|
||||||
cd ../weed; GOOS=linux go build; mv weed ../docker/
|
export SWCOMMIT=$(shell git rev-parse --short HEAD)
|
||||||
|
export SWLDFLAGS="-X github.com/chrislusf/seaweedfs/weed/util.COMMIT=$(SWCOMMIT)"
|
||||||
|
cd ../weed; CGO_ENABLED=0 GOOS=linux go build -ldflags "-extldflags -static $(SWLDFLAGS)"; mv weed ../docker/
|
||||||
|
|
||||||
|
build: binary
|
||||||
docker build --no-cache -t chrislusf/seaweedfs:local -f Dockerfile.local .
|
docker build --no-cache -t chrislusf/seaweedfs:local -f Dockerfile.local .
|
||||||
rm ./weed
|
rm ./weed
|
||||||
|
|
||||||
|
s3tests_build:
|
||||||
|
docker build --no-cache -t chrislusf/ceph-s3-tests:local -f Dockerfile.s3tests .
|
||||||
|
|
||||||
dev: build
|
dev: build
|
||||||
docker-compose -f local-dev-compose.yml -p seaweedfs up
|
docker-compose -f compose/local-dev-compose.yml -p seaweedfs up
|
||||||
|
|
||||||
|
dev_tls: build certstrap
|
||||||
|
ENV_FILE="tls.env" docker-compose -f compose/local-dev-compose.yml -p seaweedfs up
|
||||||
|
|
||||||
dev_mount: build
|
dev_mount: build
|
||||||
docker-compose -f local-mount-compose.yml -p seaweedfs up
|
docker-compose -f compose/local-mount-compose.yml -p seaweedfs up
|
||||||
|
|
||||||
|
run_image: build
|
||||||
|
docker run --rm -ti --device /dev/fuse --cap-add SYS_ADMIN --entrypoint /bin/sh chrislusf/seaweedfs:local
|
||||||
|
|
||||||
|
profile_mount: build
|
||||||
|
docker-compose -f compose/local-mount-profile-compose.yml -p seaweedfs up
|
||||||
|
|
||||||
k8s: build
|
k8s: build
|
||||||
docker-compose -f local-k8s-compose.yml -p seaweedfs up
|
docker-compose -f compose/local-k8s-compose.yml -p seaweedfs up
|
||||||
|
|
||||||
dev_registry: build
|
dev_registry: build
|
||||||
docker-compose -f local-registry-compose.yml -p seaweedfs up
|
docker-compose -f compose/local-registry-compose.yml -p seaweedfs up
|
||||||
|
|
||||||
dev_replicate: build
|
dev_replicate: build
|
||||||
docker-compose -f local-replicate-compose.yml -p seaweedfs up
|
docker-compose -f compose/local-replicate-compose.yml -p seaweedfs up
|
||||||
|
|
||||||
cluster: build
|
cluster: build
|
||||||
docker-compose -f local-cluster-compose.yml -p seaweedfs up
|
docker-compose -f compose/local-cluster-compose.yml -p seaweedfs up
|
||||||
|
|
||||||
2clusters: build
|
2clusters: build
|
||||||
docker-compose -f local-clusters-compose.yml -p seaweedfs up
|
docker-compose -f compose/local-clusters-compose.yml -p seaweedfs up
|
||||||
|
|
||||||
|
s3tests: build s3tests_build
|
||||||
|
docker-compose -f compose/local-s3tests-compose.yml -p seaweedfs up
|
||||||
|
|
||||||
filer_etcd: build
|
filer_etcd: build
|
||||||
docker stack deploy -c swarm-etcd.yml fs
|
docker stack deploy -c compose/swarm-etcd.yml fs
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm ./weed
|
rm ./weed
|
||||||
|
|
||||||
|
certstrap:
|
||||||
|
go get github.com/square/certstrap
|
||||||
|
certstrap --depot-path compose/tls init --passphrase "" --common-name "SeaweedFS CA" || true
|
||||||
|
certstrap --depot-path compose/tls request-cert --passphrase "" --common-name volume01.dev || true
|
||||||
|
certstrap --depot-path compose/tls request-cert --passphrase "" --common-name master01.dev || true
|
||||||
|
certstrap --depot-path compose/tls request-cert --passphrase "" --common-name filer01.dev || true
|
||||||
|
certstrap --depot-path compose/tls request-cert --passphrase "" --common-name client01.dev || true
|
||||||
|
certstrap --depot-path compose/tls sign --CA "SeaweedFS CA" volume01.dev || true
|
||||||
|
certstrap --depot-path compose/tls sign --CA "SeaweedFS CA" master01.dev || true
|
||||||
|
certstrap --depot-path compose/tls sign --CA "SeaweedFS CA" filer01.dev || true
|
||||||
|
certstrap --depot-path compose/tls sign --CA "SeaweedFS CA" client01.dev || true
|
||||||
@@ -19,12 +19,32 @@ services:
|
|||||||
- 9335:9335
|
- 9335:9335
|
||||||
- 19335:19335
|
- 19335:19335
|
||||||
command: "master -ip=master2 -port=9335 -peers=master0:9333,master1:9334,master2:9335 -mdir=/data/m3"
|
command: "master -ip=master2 -port=9335 -peers=master0:9333,master1:9334,master2:9335 -mdir=/data/m3"
|
||||||
volume:
|
volume1:
|
||||||
image: chrislusf/seaweedfs:local
|
image: chrislusf/seaweedfs:local
|
||||||
ports:
|
ports:
|
||||||
- 8080:8080
|
- 8080:8080
|
||||||
- 18080:18080
|
- 18080:18080
|
||||||
command: 'volume -mserver="master0:9333,master1:9334,master2:9335" -port=8080 -ip=volume -publicUrl=localhost:8080'
|
command: 'volume -mserver="master0:9333,master1:9334,master2:9335" -port=8080 -ip=volume1 -publicUrl=localhost:8080 -preStopSeconds=1 -disk=ssd1'
|
||||||
|
depends_on:
|
||||||
|
- master0
|
||||||
|
- master1
|
||||||
|
- master2
|
||||||
|
volume2:
|
||||||
|
image: chrislusf/seaweedfs:local
|
||||||
|
ports:
|
||||||
|
- 8082:8082
|
||||||
|
- 18082:18082
|
||||||
|
command: 'volume -mserver="master0:9333,master1:9334,master2:9335" -port=8082 -ip=volume2 -publicUrl=localhost:8082 -preStopSeconds=1 -disk=ssd1'
|
||||||
|
depends_on:
|
||||||
|
- master0
|
||||||
|
- master1
|
||||||
|
- master2
|
||||||
|
volume3:
|
||||||
|
image: chrislusf/seaweedfs:local
|
||||||
|
ports:
|
||||||
|
- 8083:8083
|
||||||
|
- 18083:18083
|
||||||
|
command: 'volume -mserver="master0:9333,master1:9334,master2:9335" -port=8083 -ip=volume3 -publicUrl=localhost:8083 -preStopSeconds=1'
|
||||||
depends_on:
|
depends_on:
|
||||||
- master0
|
- master0
|
||||||
- master1
|
- master1
|
||||||
@@ -39,7 +59,8 @@ services:
|
|||||||
- master0
|
- master0
|
||||||
- master1
|
- master1
|
||||||
- master2
|
- master2
|
||||||
- volume
|
- volume1
|
||||||
|
- volume2
|
||||||
s3:
|
s3:
|
||||||
image: chrislusf/seaweedfs:local
|
image: chrislusf/seaweedfs:local
|
||||||
ports:
|
ports:
|
||||||
@@ -49,5 +70,6 @@ services:
|
|||||||
- master0
|
- master0
|
||||||
- master1
|
- master1
|
||||||
- master2
|
- master2
|
||||||
- volume
|
- volume1
|
||||||
|
- volume2
|
||||||
- filer
|
- filer
|
||||||
@@ -11,6 +11,10 @@ services:
|
|||||||
- 8888:8888
|
- 8888:8888
|
||||||
- 18888:18888
|
- 18888:18888
|
||||||
command: "server -ip=server1 -filer -volume.max=0 -master.volumeSizeLimitMB=1024 -volume.preStopSeconds=1"
|
command: "server -ip=server1 -filer -volume.max=0 -master.volumeSizeLimitMB=1024 -volume.preStopSeconds=1"
|
||||||
|
volumes:
|
||||||
|
- ./master-cloud.toml:/etc/seaweedfs/master.toml
|
||||||
|
depends_on:
|
||||||
|
- server2
|
||||||
server2:
|
server2:
|
||||||
image: chrislusf/seaweedfs:local
|
image: chrislusf/seaweedfs:local
|
||||||
ports:
|
ports:
|
||||||
@@ -20,4 +24,5 @@ services:
|
|||||||
- 18085:18080
|
- 18085:18080
|
||||||
- 8889:8888
|
- 8889:8888
|
||||||
- 18889:18888
|
- 18889:18888
|
||||||
command: "server -ip=server2 -filer -volume.max=0 -master.volumeSizeLimitMB=1024 -volume.preStopSeconds=1"
|
- 8334:8333
|
||||||
|
command: "server -ip=server2 -filer -s3 -volume.max=0 -master.volumeSizeLimitMB=1024 -volume.preStopSeconds=1"
|
||||||
@@ -6,33 +6,50 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- 9333:9333
|
- 9333:9333
|
||||||
- 19333:19333
|
- 19333:19333
|
||||||
command: "master -ip=master"
|
command: "-v=1 master -ip=master"
|
||||||
|
volumes:
|
||||||
|
- ./tls:/etc/seaweedfs/tls
|
||||||
|
env_file:
|
||||||
|
- ${ENV_FILE:-dev.env}
|
||||||
volume:
|
volume:
|
||||||
image: chrislusf/seaweedfs:local
|
image: chrislusf/seaweedfs:local
|
||||||
ports:
|
ports:
|
||||||
- 8080:8080
|
- 8080:8080
|
||||||
- 18080:18080
|
- 18080:18080
|
||||||
command: "volume -mserver=master:9333 -port=8080 -ip=volume -preStopSeconds=1"
|
command: "-v=1 volume -mserver=master:9333 -port=8080 -ip=volume -preStopSeconds=1"
|
||||||
depends_on:
|
depends_on:
|
||||||
- master
|
- master
|
||||||
|
volumes:
|
||||||
|
- ./tls:/etc/seaweedfs/tls
|
||||||
|
env_file:
|
||||||
|
- ${ENV_FILE:-dev.env}
|
||||||
filer:
|
filer:
|
||||||
image: chrislusf/seaweedfs:local
|
image: chrislusf/seaweedfs:local
|
||||||
ports:
|
ports:
|
||||||
|
- 8111:8111
|
||||||
- 8888:8888
|
- 8888:8888
|
||||||
- 18888:18888
|
- 18888:18888
|
||||||
command: 'filer -master="master:9333"'
|
command: '-v=1 filer -master="master:9333" -iam'
|
||||||
depends_on:
|
depends_on:
|
||||||
- master
|
- master
|
||||||
- volume
|
- volume
|
||||||
|
volumes:
|
||||||
|
- ./tls:/etc/seaweedfs/tls
|
||||||
|
env_file:
|
||||||
|
- ${ENV_FILE:-dev.env}
|
||||||
s3:
|
s3:
|
||||||
image: chrislusf/seaweedfs:local
|
image: chrislusf/seaweedfs:local
|
||||||
ports:
|
ports:
|
||||||
- 8333:8333
|
- 8333:8333
|
||||||
command: 's3 -filer="filer:8888"'
|
command: '-v=1 s3 -filer="filer:8888"'
|
||||||
depends_on:
|
depends_on:
|
||||||
- master
|
- master
|
||||||
- volume
|
- volume
|
||||||
- filer
|
- filer
|
||||||
|
volumes:
|
||||||
|
- ./tls:/etc/seaweedfs/tls
|
||||||
|
env_file:
|
||||||
|
- ${ENV_FILE:-dev.env}
|
||||||
mount:
|
mount:
|
||||||
image: chrislusf/seaweedfs:local
|
image: chrislusf/seaweedfs:local
|
||||||
privileged: true
|
privileged: true
|
||||||
@@ -40,6 +57,10 @@ services:
|
|||||||
- SYS_ADMIN
|
- SYS_ADMIN
|
||||||
mem_limit: 4096m
|
mem_limit: 4096m
|
||||||
command: '-v=4 mount -filer="filer:8888" -dirAutoCreate -dir=/mnt/seaweedfs -cacheCapacityMB=100 -concurrentWriters=128'
|
command: '-v=4 mount -filer="filer:8888" -dirAutoCreate -dir=/mnt/seaweedfs -cacheCapacityMB=100 -concurrentWriters=128'
|
||||||
|
volumes:
|
||||||
|
- ./tls:/etc/seaweedfs/tls
|
||||||
|
env_file:
|
||||||
|
- ${ENV_FILE:-dev.env}
|
||||||
depends_on:
|
depends_on:
|
||||||
- master
|
- master
|
||||||
- volume
|
- volume
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
version: '2'
|
||||||
|
|
||||||
|
services:
|
||||||
|
master:
|
||||||
|
image: chrislusf/seaweedfs:local
|
||||||
|
ports:
|
||||||
|
- 9333:9333
|
||||||
|
- 19333:19333
|
||||||
|
command: "master -ip=master -volumeSizeLimitMB=1024"
|
||||||
|
volume:
|
||||||
|
image: chrislusf/seaweedfs:local
|
||||||
|
ports:
|
||||||
|
- 8080:8080
|
||||||
|
- 18080:18080
|
||||||
|
command: "volume -mserver=master:9333 -port=8080 -ip=volume -max=0 -preStopSeconds=1"
|
||||||
|
depends_on:
|
||||||
|
- master
|
||||||
|
s3:
|
||||||
|
image: chrislusf/seaweedfs:local
|
||||||
|
ports:
|
||||||
|
- 8888:8888
|
||||||
|
- 18888:18888
|
||||||
|
- 8333:8333
|
||||||
|
command: '-v 1 filer -master="master:9333" -s3 -s3.config=/etc/seaweedfs/s3.json -s3.port=8333'
|
||||||
|
volumes:
|
||||||
|
- ./s3.json:/etc/seaweedfs/s3.json
|
||||||
|
depends_on:
|
||||||
|
- master
|
||||||
|
- volume
|
||||||
|
minio-gateway-s3:
|
||||||
|
image: minio/minio
|
||||||
|
ports:
|
||||||
|
- 9000:9000
|
||||||
|
command: 'minio gateway s3 http://s3:8333'
|
||||||
|
restart: on-failure
|
||||||
|
environment:
|
||||||
|
MINIO_ACCESS_KEY: "some_access_key1"
|
||||||
|
MINIO_SECRET_KEY: "some_secret_key1"
|
||||||
|
depends_on:
|
||||||
|
- s3
|
||||||
|
minio-warp:
|
||||||
|
image: minio/warp
|
||||||
|
command: 'mixed --duration=5m --obj.size=3mb --autoterm'
|
||||||
|
restart: on-failure
|
||||||
|
environment:
|
||||||
|
WARP_HOST: "minio-gateway-s3:9000"
|
||||||
|
WARP_ACCESS_KEY: "some_access_key1"
|
||||||
|
WARP_SECRET_KEY: "some_secret_key1"
|
||||||
|
depends_on:
|
||||||
|
- minio-gateway-s3
|
||||||
@@ -30,7 +30,7 @@ services:
|
|||||||
mount_1:
|
mount_1:
|
||||||
image: chrislusf/seaweedfs:local
|
image: chrislusf/seaweedfs:local
|
||||||
privileged: true
|
privileged: true
|
||||||
entrypoint: '/bin/sh -c "mkdir -p t1 && mkdir -p cache/t1 && weed -v=4 mount -filer=filer:8888 -cacheDir=./cache/t1 -dir=./t1 -filer.path=/c1" -volumeServerAccess=filerProxy'
|
entrypoint: '/bin/sh -c "mkdir -p t1 && mkdir -p cache/t1 && weed -v=4 mount -filer=filer:8888 -cacheDir=./cache/t1 -dir=./t1 -filer.path=/c1 -volumeServerAccess=filerProxy"'
|
||||||
depends_on:
|
depends_on:
|
||||||
- master
|
- master
|
||||||
- volume
|
- volume
|
||||||
@@ -38,7 +38,7 @@ services:
|
|||||||
mount_2:
|
mount_2:
|
||||||
image: chrislusf/seaweedfs:local
|
image: chrislusf/seaweedfs:local
|
||||||
privileged: true
|
privileged: true
|
||||||
entrypoint: '/bin/sh -c "mkdir -p t2 && mkdir -p cache/t2 && weed -v=4 mount -filer=filer:8888 -cacheDir=./cache/t2 -dir=./t2 -filer.path=/c1" -volumeServerAcess=publicUrl'
|
entrypoint: '/bin/sh -c "mkdir -p t2 && mkdir -p cache/t2 && weed -v=4 mount -filer=filer:8888 -cacheDir=./cache/t2 -dir=./t2 -filer.path=/c1"'
|
||||||
depends_on:
|
depends_on:
|
||||||
- master
|
- master
|
||||||
- volume
|
- volume
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
version: '2'
|
||||||
|
|
||||||
|
services:
|
||||||
|
master:
|
||||||
|
image: chrislusf/seaweedfs:local
|
||||||
|
ports:
|
||||||
|
- 9333:9333
|
||||||
|
- 19333:19333
|
||||||
|
command: "master -ip=master"
|
||||||
|
volume:
|
||||||
|
image: chrislusf/seaweedfs:local
|
||||||
|
ports:
|
||||||
|
- 7455:8080
|
||||||
|
- 9325:9325
|
||||||
|
volumes:
|
||||||
|
- /Volumes/mobile_disk/99:/data
|
||||||
|
command: 'volume -mserver="master:9333" -port=8080 -metricsPort=9325 -preStopSeconds=1 -publicUrl=localhost:7455'
|
||||||
|
depends_on:
|
||||||
|
- master
|
||||||
|
filer:
|
||||||
|
image: chrislusf/seaweedfs:local
|
||||||
|
ports:
|
||||||
|
- 8888:8888
|
||||||
|
- 18888:18888
|
||||||
|
- 9326:9326
|
||||||
|
volumes:
|
||||||
|
- /Volumes/mobile_disk/99:/data
|
||||||
|
command: 'filer -master="master:9333" -metricsPort=9326'
|
||||||
|
tty: true
|
||||||
|
stdin_open: true
|
||||||
|
depends_on:
|
||||||
|
- master
|
||||||
|
- volume
|
||||||
|
mount:
|
||||||
|
image: chrislusf/seaweedfs:local
|
||||||
|
privileged: true
|
||||||
|
cap_add:
|
||||||
|
- SYS_ADMIN
|
||||||
|
devices:
|
||||||
|
- fuse
|
||||||
|
volumes:
|
||||||
|
- /Volumes/mobile_disk/99:/data
|
||||||
|
entrypoint: '/bin/sh -c "mkdir -p t1 && weed -v=4 mount -filer=filer:8888 -dir=./t1 -cacheCapacityMB=0 -memprofile=/data/mount.mem.pprof"'
|
||||||
|
depends_on:
|
||||||
|
- master
|
||||||
|
- volume
|
||||||
|
- filer
|
||||||
@@ -15,24 +15,18 @@ services:
|
|||||||
command: "volume -mserver=master:9333 -port=8080 -ip=volume -max=0 -preStopSeconds=1"
|
command: "volume -mserver=master:9333 -port=8080 -ip=volume -max=0 -preStopSeconds=1"
|
||||||
depends_on:
|
depends_on:
|
||||||
- master
|
- master
|
||||||
filer:
|
s3:
|
||||||
image: chrislusf/seaweedfs:local
|
image: chrislusf/seaweedfs:local
|
||||||
ports:
|
ports:
|
||||||
- 8888:8888
|
- 8888:8888
|
||||||
- 18888:18888
|
- 18888:18888
|
||||||
command: 'filer -master="master:9333"'
|
|
||||||
depends_on:
|
|
||||||
- master
|
|
||||||
- volume
|
|
||||||
s3:
|
|
||||||
image: chrislusf/seaweedfs:local
|
|
||||||
ports:
|
|
||||||
- 8333:8333
|
- 8333:8333
|
||||||
command: '-v 9 s3 -filer="filer:8888"'
|
command: '-v 9 filer -master="master:9333" -s3 -s3.config=/etc/seaweedfs/s3.json -s3.port=8333'
|
||||||
|
volumes:
|
||||||
|
- ./s3.json:/etc/seaweedfs/s3.json
|
||||||
depends_on:
|
depends_on:
|
||||||
- master
|
- master
|
||||||
- volume
|
- volume
|
||||||
- filer
|
|
||||||
minio:
|
minio:
|
||||||
image: minio/minio
|
image: minio/minio
|
||||||
ports:
|
ports:
|
||||||
@@ -56,4 +56,6 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- 5672:5672
|
- 5672:5672
|
||||||
- 15671:15671
|
- 15671:15671
|
||||||
- 15672:15672
|
- 15672:15672
|
||||||
|
environment:
|
||||||
|
RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS: "-rabbit log_levels [{connection,error},{queue,debug}]"
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
version: '2'
|
||||||
|
|
||||||
|
services:
|
||||||
|
master:
|
||||||
|
image: chrislusf/seaweedfs:local
|
||||||
|
ports:
|
||||||
|
- 9333:9333
|
||||||
|
- 19333:19333
|
||||||
|
command: "master -ip=master -volumeSizeLimitMB=16"
|
||||||
|
environment:
|
||||||
|
WEED_MASTER_VOLUME_GROWTH_COPY_1: 1
|
||||||
|
WEED_MASTER_VOLUME_GROWTH_COPY_OTHER: 1
|
||||||
|
volume:
|
||||||
|
image: chrislusf/seaweedfs:local
|
||||||
|
ports:
|
||||||
|
- 8080:8080
|
||||||
|
- 18080:18080
|
||||||
|
command: "volume -mserver=master:9333 -port=8080 -ip=volume -preStopSeconds=1"
|
||||||
|
depends_on:
|
||||||
|
- master
|
||||||
|
s3:
|
||||||
|
image: chrislusf/seaweedfs:local
|
||||||
|
ports:
|
||||||
|
- 8888:8888
|
||||||
|
- 18888:18888
|
||||||
|
- 8000:8000
|
||||||
|
command: 'filer -master="master:9333" -s3 -s3.config=/etc/seaweedfs/s3.json -s3.port=8000'
|
||||||
|
volumes:
|
||||||
|
- ./s3.json:/etc/seaweedfs/s3.json
|
||||||
|
depends_on:
|
||||||
|
- master
|
||||||
|
- volume
|
||||||
|
s3tests:
|
||||||
|
image: chrislusf/ceph-s3-tests:local
|
||||||
|
volumes:
|
||||||
|
- ./s3tests.conf:/opt/s3-tests/s3tests.conf
|
||||||
|
environment:
|
||||||
|
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: "(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)"
|
||||||
|
depends_on:
|
||||||
|
- master
|
||||||
|
- volume
|
||||||
|
- s3
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
# Put this file to one of the location, with descending priority
|
||||||
|
# ./master.toml
|
||||||
|
# $HOME/.seaweedfs/master.toml
|
||||||
|
# /etc/seaweedfs/master.toml
|
||||||
|
# this file is read by master
|
||||||
|
|
||||||
|
[master.maintenance]
|
||||||
|
# periodically run these scripts are the same as running them from 'weed shell'
|
||||||
|
scripts = """
|
||||||
|
lock
|
||||||
|
ec.encode -fullPercent=95 -quietFor=1h
|
||||||
|
ec.rebuild -force
|
||||||
|
ec.balance -force
|
||||||
|
volume.balance -force
|
||||||
|
volume.fix.replication
|
||||||
|
unlock
|
||||||
|
"""
|
||||||
|
sleep_minutes = 17 # sleep minutes between each script execution
|
||||||
|
|
||||||
|
# configurations for tiered cloud storage
|
||||||
|
# old volumes are transparently moved to cloud for cost efficiency
|
||||||
|
[storage.backend]
|
||||||
|
[storage.backend.s3.default]
|
||||||
|
enabled = true
|
||||||
|
aws_access_key_id = "any" # if empty, loads from the shared credentials file (~/.aws/credentials).
|
||||||
|
aws_secret_access_key = "any" # if empty, loads from the shared credentials file (~/.aws/credentials).
|
||||||
|
region = "us-east-2"
|
||||||
|
bucket = "volume_bucket" # an existing bucket
|
||||||
|
endpoint = "http://server2:8333"
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
{
|
||||||
|
"identities": [
|
||||||
|
{
|
||||||
|
"name": "anonymous",
|
||||||
|
"actions": [
|
||||||
|
"Read"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "some_admin_user",
|
||||||
|
"credentials": [
|
||||||
|
{
|
||||||
|
"accessKey": "some_access_key1",
|
||||||
|
"secretKey": "some_secret_key1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"actions": [
|
||||||
|
"Admin",
|
||||||
|
"Read",
|
||||||
|
"List",
|
||||||
|
"Tagging",
|
||||||
|
"Write"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "s3_tests",
|
||||||
|
"credentials": [
|
||||||
|
{
|
||||||
|
"accessKey": "ABCDEFGHIJKLMNOPQRST",
|
||||||
|
"secretKey": "abcdefghijklmnopqrstuvwxyzabcdefghijklmn"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accessKey": "0555b35654ad1656d804",
|
||||||
|
"secretKey": "h7GhxuBLTrlhVUyxSPUKUV8r/2EI4ngqJxD7iBdBYLhwluN30JaT3Q=="
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"actions": [
|
||||||
|
"Admin",
|
||||||
|
"Read",
|
||||||
|
"List",
|
||||||
|
"Tagging",
|
||||||
|
"Write"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "s3_tests_alt",
|
||||||
|
"credentials": [
|
||||||
|
{
|
||||||
|
"accessKey": "NOPQRSTUVWXYZABCDEFG",
|
||||||
|
"secretKey": "nopqrstuvwxyzabcdefghijklmnabcdefghijklm"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"actions": [
|
||||||
|
"Admin",
|
||||||
|
"Read",
|
||||||
|
"List",
|
||||||
|
"Tagging",
|
||||||
|
"Write"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "s3_tests_tenant",
|
||||||
|
"credentials": [
|
||||||
|
{
|
||||||
|
"accessKey": "HIJKLMNOPQRSTUVWXYZA",
|
||||||
|
"secretKey": "opqrstuvwxyzabcdefghijklmnopqrstuvwxyzab"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"actions": [
|
||||||
|
"Admin",
|
||||||
|
"Read",
|
||||||
|
"List",
|
||||||
|
"Tagging",
|
||||||
|
"Write"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "some_read_only_user",
|
||||||
|
"credentials": [
|
||||||
|
{
|
||||||
|
"accessKey": "some_access_key2",
|
||||||
|
"secretKey": "some_secret_key2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"actions": [
|
||||||
|
"Read"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "some_normal_user",
|
||||||
|
"credentials": [
|
||||||
|
{
|
||||||
|
"accessKey": "some_access_key3",
|
||||||
|
"secretKey": "some_secret_key3"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"actions": [
|
||||||
|
"Read",
|
||||||
|
"List",
|
||||||
|
"Tagging",
|
||||||
|
"Write"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
## this section is just used for host, port and bucket_prefix
|
||||||
|
|
||||||
|
# host set for rgw in vstart.sh
|
||||||
|
host = s3
|
||||||
|
|
||||||
|
# port set for rgw in vstart.sh
|
||||||
|
port = 8000
|
||||||
|
|
||||||
|
## say "False" to disable TLS
|
||||||
|
is_secure = False
|
||||||
|
|
||||||
|
[fixtures]
|
||||||
|
## all the buckets created will start with this prefix;
|
||||||
|
## {random} will be filled with random characters to pad
|
||||||
|
## the prefix to 30 characters long, and avoid collisions
|
||||||
|
bucket prefix = yournamehere-{random}-
|
||||||
|
|
||||||
|
[s3 main]
|
||||||
|
# main display_name set in vstart.sh
|
||||||
|
display_name = M. Tester
|
||||||
|
|
||||||
|
# main user_idname set in vstart.sh
|
||||||
|
user_id = testid
|
||||||
|
|
||||||
|
# main email set in vstart.sh
|
||||||
|
email = tester@ceph.com
|
||||||
|
|
||||||
|
# zonegroup api_name for bucket location
|
||||||
|
api_name = default
|
||||||
|
|
||||||
|
## main AWS access key
|
||||||
|
access_key = 0555b35654ad1656d804
|
||||||
|
|
||||||
|
## main AWS secret key
|
||||||
|
secret_key = h7GhxuBLTrlhVUyxSPUKUV8r/2EI4ngqJxD7iBdBYLhwluN30JaT3Q==
|
||||||
|
|
||||||
|
## replace with key id obtained when secret is created, or delete if KMS not tested
|
||||||
|
#kms_keyid = 01234567-89ab-cdef-0123-456789abcdef
|
||||||
|
|
||||||
|
[s3 alt]
|
||||||
|
# alt display_name set in vstart.sh
|
||||||
|
display_name = john.doe
|
||||||
|
## alt email set in vstart.sh
|
||||||
|
email = john.doe@example.com
|
||||||
|
|
||||||
|
# alt user_id set in vstart.sh
|
||||||
|
user_id = 56789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234
|
||||||
|
|
||||||
|
# alt AWS access key set in vstart.sh
|
||||||
|
access_key = NOPQRSTUVWXYZABCDEFG
|
||||||
|
|
||||||
|
# alt AWS secret key set in vstart.sh
|
||||||
|
secret_key = nopqrstuvwxyzabcdefghijklmnabcdefghijklm
|
||||||
|
|
||||||
|
[s3 tenant]
|
||||||
|
# tenant display_name set in vstart.sh
|
||||||
|
display_name = testx$tenanteduser
|
||||||
|
|
||||||
|
# tenant user_id set in vstart.sh
|
||||||
|
user_id = 9876543210abcdef0123456789abcdef0123456789abcdef0123456789abcdef
|
||||||
|
|
||||||
|
# tenant AWS secret key set in vstart.sh
|
||||||
|
access_key = HIJKLMNOPQRSTUVWXYZA
|
||||||
|
|
||||||
|
# tenant AWS secret key set in vstart.sh
|
||||||
|
secret_key = opqrstuvwxyzabcdefghijklmnopqrstuvwxyzab
|
||||||
|
|
||||||
|
# tenant email set in vstart.sh
|
||||||
|
email = tenanteduser@example.com
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
WEED_GRPC_CA=/etc/seaweedfs/tls/SeaweedFS_CA.crt
|
||||||
|
WEED_GRPC_ALLOWED_WILDCARD_DOMAIN=".dev"
|
||||||
|
WEED_GRPC_MASTER_CERT=/etc/seaweedfs/tls/master01.dev.crt
|
||||||
|
WEED_GRPC_MASTER_KEY=/etc/seaweedfs/tls/master01.dev.key
|
||||||
|
WEED_GRPC_VOLUME_CERT=/etc/seaweedfs/tls/volume01.dev.crt
|
||||||
|
WEED_GRPC_VOLUME_KEY=/etc/seaweedfs/tls/volume01.dev.key
|
||||||
|
WEED_GRPC_FILER_CERT=/etc/seaweedfs/tls/filer01.dev.crt
|
||||||
|
WEED_GRPC_FILER_KEY=/etc/seaweedfs/tls/filer01.dev.key
|
||||||
|
WEED_GRPC_CLIENT_CERT=/etc/seaweedfs/tls/client01.dev.crt
|
||||||
|
WEED_GRPC_CLIENT_KEY=/etc/seaweedfs/tls/client01.dev.key
|
||||||
|
WEED_GRPC_MASTER_ALLOWED_COMMONNAMES="volume01.dev,master01.dev,filer01.dev,client01.dev"
|
||||||
|
WEED_GRPC_VOLUME_ALLOWED_COMMONNAMES="volume01.dev,master01.dev,filer01.dev,client01.dev"
|
||||||
|
WEED_GRPC_FILER_ALLOWED_COMMONNAMES="volume01.dev,master01.dev,filer01.dev,client01.dev"
|
||||||
|
WEED_GRPC_CLIENT_ALLOWED_COMMONNAMES="volume01.dev,master01.dev,filer01.dev,client01.dev"
|
||||||
@@ -60,9 +60,9 @@ case "$1" in
|
|||||||
'cronjob')
|
'cronjob')
|
||||||
MASTER=${WEED_MASTER-localhost:9333}
|
MASTER=${WEED_MASTER-localhost:9333}
|
||||||
FIX_REPLICATION_CRON_SCHEDULE=${CRON_SCHEDULE-*/7 * * * * *}
|
FIX_REPLICATION_CRON_SCHEDULE=${CRON_SCHEDULE-*/7 * * * * *}
|
||||||
echo "$FIX_REPLICATION_CRON_SCHEDULE" 'echo "volume.fix.replication" | weed shell -master='$MASTER > /crontab
|
echo "$FIX_REPLICATION_CRON_SCHEDULE" 'echo "lock; volume.fix.replication; unlock" | weed shell -master='$MASTER > /crontab
|
||||||
BALANCING_CRON_SCHEDULE=${CRON_SCHEDULE-25 * * * * *}
|
BALANCING_CRON_SCHEDULE=${CRON_SCHEDULE-25 * * * * *}
|
||||||
echo "$BALANCING_CRON_SCHEDULE" 'echo "volume.balance -c ALL -force" | weed shell -master='$MASTER >> /crontab
|
echo "$BALANCING_CRON_SCHEDULE" 'echo "lock; volume.balance -collection ALL_COLLECTIONS -force; unlock" | weed shell -master='$MASTER >> /crontab
|
||||||
echo "Running Crontab:"
|
echo "Running Crontab:"
|
||||||
cat /crontab
|
cat /crontab
|
||||||
exec supercronic /crontab
|
exec supercronic /crontab
|
||||||
|
|||||||
@@ -48,6 +48,15 @@ services:
|
|||||||
- master
|
- master
|
||||||
- volume
|
- volume
|
||||||
- filer
|
- filer
|
||||||
|
webdav:
|
||||||
|
image: chrislusf/seaweedfs # use a remote image
|
||||||
|
ports:
|
||||||
|
- 7333:7333
|
||||||
|
command: 'webdav -filer="filer:8888"'
|
||||||
|
depends_on:
|
||||||
|
- master
|
||||||
|
- volume
|
||||||
|
- filer
|
||||||
prometheus:
|
prometheus:
|
||||||
image: prom/prometheus:v2.21.0
|
image: prom/prometheus:v2.21.0
|
||||||
ports:
|
ports:
|
||||||
|
|||||||
@@ -33,3 +33,12 @@ services:
|
|||||||
- master
|
- master
|
||||||
- volume
|
- volume
|
||||||
- filer
|
- filer
|
||||||
|
webdav:
|
||||||
|
image: chrislusf/seaweedfs:dev # use a remote dev image
|
||||||
|
ports:
|
||||||
|
- 7333:7333
|
||||||
|
command: 'webdav -filer="filer:8888"'
|
||||||
|
depends_on:
|
||||||
|
- master
|
||||||
|
- volume
|
||||||
|
- filer
|
||||||
|
|||||||
@@ -1,22 +1,34 @@
|
|||||||
module github.com/chrislusf/seaweedfs
|
module github.com/chrislusf/seaweedfs
|
||||||
|
|
||||||
go 1.12
|
go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.44.3
|
cloud.google.com/go v0.94.1 // indirect
|
||||||
github.com/Azure/azure-pipeline-go v0.2.2 // indirect
|
cloud.google.com/go/pubsub v1.3.1
|
||||||
github.com/Azure/azure-storage-blob-go v0.8.0
|
cloud.google.com/go/storage v1.16.1
|
||||||
|
github.com/Azure/azure-pipeline-go v0.2.3
|
||||||
|
github.com/Azure/azure-storage-blob-go v0.14.0
|
||||||
|
github.com/BurntSushi/toml v0.3.1 // indirect
|
||||||
|
github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798 // indirect
|
||||||
github.com/OneOfOne/xxhash v1.2.2
|
github.com/OneOfOne/xxhash v1.2.2
|
||||||
github.com/Shopify/sarama v1.23.1
|
github.com/Shopify/sarama v1.23.1
|
||||||
github.com/aws/aws-sdk-go v1.34.30
|
github.com/aws/aws-sdk-go v1.35.3
|
||||||
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/buraksezer/consistent v0.0.0-20191006190839-693edf70fd72
|
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 v1.1.0
|
||||||
github.com/chrislusf/raft v1.0.4
|
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/coreos/go-semver v0.3.0 // indirect
|
github.com/coreos/go-semver v0.3.0 // indirect
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
github.com/disintegration/imaging v1.6.2
|
github.com/disintegration/imaging v1.6.2
|
||||||
github.com/dustin/go-humanize v1.0.0
|
github.com/dustin/go-humanize v1.0.0
|
||||||
github.com/eapache/go-resiliency v1.2.0 // indirect
|
github.com/eapache/go-resiliency v1.2.0 // indirect
|
||||||
|
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect
|
||||||
|
github.com/eapache/queue v1.1.0 // indirect
|
||||||
github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a
|
github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a
|
||||||
github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c // indirect
|
github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c // indirect
|
||||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect
|
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect
|
||||||
@@ -24,78 +36,167 @@ require (
|
|||||||
github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 // indirect
|
github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 // indirect
|
||||||
github.com/fclairamb/ftpserverlib v0.8.0
|
github.com/fclairamb/ftpserverlib v0.8.0
|
||||||
github.com/frankban/quicktest v1.7.2 // indirect
|
github.com/frankban/quicktest v1.7.2 // indirect
|
||||||
|
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||||
github.com/go-errors/errors v1.1.1 // indirect
|
github.com/go-errors/errors v1.1.1 // indirect
|
||||||
github.com/go-redis/redis/v8 v8.4.4
|
github.com/go-redis/redis/v8 v8.4.4
|
||||||
github.com/go-sql-driver/mysql v1.5.0
|
github.com/go-sql-driver/mysql v1.5.0
|
||||||
github.com/gocql/gocql v0.0.0-20190829130954-e163eff7a8c6
|
github.com/go-stack/stack v1.8.0 // indirect
|
||||||
github.com/gogo/protobuf v1.2.2-0.20190730201129-28a6bbf47e48 // indirect
|
github.com/go-zookeeper/zk v1.0.2 // indirect
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6
|
github.com/gocql/gocql v0.0.0-20210707082121-9a3953d1826d
|
||||||
github.com/golang/protobuf v1.4.2
|
github.com/golang-jwt/jwt v3.2.1+incompatible
|
||||||
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da
|
||||||
|
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/btree v1.0.0
|
||||||
github.com/google/uuid v1.1.1
|
github.com/google/go-cmp v0.5.6 // 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/gorilla/mux v1.7.4
|
||||||
github.com/gorilla/websocket v1.4.1 // indirect
|
github.com/gorilla/websocket v1.4.1 // indirect
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.11.0 // indirect
|
github.com/grpc-ecosystem/go-grpc-middleware v1.1.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.0.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/gofork v1.0.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.10
|
github.com/jcmturner/gokrb5/v8 v8.4.1
|
||||||
github.com/karlseguin/ccache v2.0.3+incompatible
|
github.com/jinzhu/copier v0.2.8
|
||||||
|
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/karlseguin/ccache/v2 v2.0.7
|
||||||
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||||
github.com/klauspost/compress v1.10.9 // indirect
|
github.com/klauspost/compress v1.10.9 // indirect
|
||||||
github.com/klauspost/cpuid v1.2.1 // indirect
|
github.com/klauspost/cpuid v1.2.1 // indirect
|
||||||
github.com/klauspost/crc32 v1.2.0
|
|
||||||
github.com/klauspost/reedsolomon v1.9.2
|
github.com/klauspost/reedsolomon v1.9.2
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect
|
||||||
github.com/kurin/blazer v0.5.3
|
github.com/kurin/blazer v0.5.3
|
||||||
github.com/lib/pq v1.2.0
|
github.com/lib/pq v1.10.0
|
||||||
github.com/lunixbochs/vtclean v1.0.0 // indirect
|
|
||||||
github.com/magiconair/properties v1.8.1 // indirect
|
github.com/magiconair/properties v1.8.1 // indirect
|
||||||
github.com/mattn/go-ieproxy v0.0.0-20190805055040-f9202b1cfdeb // indirect
|
github.com/mailru/easyjson v0.7.1 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.4 // indirect
|
github.com/mattn/go-ieproxy v0.0.1 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.12 // indirect
|
||||||
|
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.1.2 // 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/olivere/elastic/v7 v7.0.19
|
||||||
|
github.com/pelletier/go-toml v1.7.0 // indirect
|
||||||
github.com/peterh/liner v1.1.0
|
github.com/peterh/liner v1.1.0
|
||||||
github.com/pierrec/lz4 v2.2.7+incompatible // indirect
|
github.com/pierrec/lz4 v2.2.7+incompatible // indirect
|
||||||
github.com/prometheus/client_golang v1.3.0
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/rakyll/statik v0.1.7
|
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_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/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563 // indirect
|
||||||
github.com/seaweedfs/fuse v1.1.1
|
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
||||||
|
github.com/seaweedfs/fuse v1.2.0
|
||||||
github.com/seaweedfs/goexif v1.0.2
|
github.com/seaweedfs/goexif v1.0.2
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
github.com/sirupsen/logrus v1.6.0 // indirect
|
||||||
github.com/spaolacci/murmur3 v1.1.0 // 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/jwalterweatherman v1.1.0 // indirect
|
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||||
github.com/spf13/viper v1.4.0
|
github.com/spf13/viper v1.4.0
|
||||||
github.com/stretchr/testify v1.6.1
|
github.com/streadway/amqp v0.0.0-20200108173154-1c71cc93ed71
|
||||||
github.com/syndtr/goleveldb v1.0.0
|
github.com/stretchr/testify v1.7.0
|
||||||
|
github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965
|
||||||
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c
|
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c
|
||||||
github.com/tidwall/gjson v1.3.2
|
github.com/tidwall/gjson v1.8.1
|
||||||
github.com/tidwall/match v1.0.1
|
github.com/tidwall/match v1.0.3
|
||||||
|
github.com/tidwall/pretty v1.1.0 // indirect
|
||||||
|
github.com/tikv/client-go/v2 v2.0.0-alpha.0.20210824090536-16d902a3c7e5
|
||||||
github.com/tsuna/gohbase v0.0.0-20201125011725-348991136365
|
github.com/tsuna/gohbase v0.0.0-20201125011725-348991136365
|
||||||
|
github.com/tylertreat/BoomFilters v0.0.0-20210315201527-1a82519a3e43
|
||||||
github.com/valyala/bytebufferpool v1.0.0
|
github.com/valyala/bytebufferpool v1.0.0
|
||||||
github.com/viant/assertly v0.5.4 // indirect
|
github.com/viant/assertly v0.5.4 // indirect
|
||||||
github.com/viant/ptrie v0.3.0
|
github.com/viant/ptrie v0.3.0
|
||||||
github.com/viant/toolbox v0.33.2 // indirect
|
github.com/viant/toolbox v0.33.2 // indirect
|
||||||
github.com/willf/bitset v1.1.10 // indirect
|
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||||
github.com/willf/bloom v2.0.3+incompatible
|
github.com/xdg-go/scram v1.0.2 // indirect
|
||||||
github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0 // indirect
|
github.com/xdg-go/stringprep v1.0.2 // indirect
|
||||||
go.etcd.io/etcd v3.3.15+incompatible
|
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
|
||||||
go.mongodb.org/mongo-driver v1.3.2
|
go.etcd.io/etcd v3.3.25+incompatible
|
||||||
gocloud.dev v0.16.0
|
go.mongodb.org/mongo-driver v1.7.0
|
||||||
gocloud.dev/pubsub/natspubsub v0.16.0
|
go.opencensus.io v0.23.0 // indirect
|
||||||
gocloud.dev/pubsub/rabbitpubsub v0.16.0
|
go.opentelemetry.io/otel v0.15.0 // indirect
|
||||||
golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect
|
gocloud.dev v0.20.0
|
||||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb
|
gocloud.dev/pubsub/natspubsub v0.20.0
|
||||||
golang.org/x/sync v0.0.0-20200930132711-30421366ff76 // indirect
|
gocloud.dev/pubsub/rabbitpubsub v0.20.0
|
||||||
golang.org/x/sys v0.0.0-20201022201747-fb209a7c41cd
|
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 // indirect
|
||||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114
|
golang.org/x/image v0.0.0-20200119044424-58c23975cae1
|
||||||
google.golang.org/api v0.9.0
|
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d
|
||||||
google.golang.org/appengine v1.6.2 // indirect
|
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect
|
||||||
google.golang.org/grpc v1.29.1
|
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf
|
||||||
google.golang.org/protobuf v1.24.0
|
golang.org/x/text v0.3.6 // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
golang.org/x/tools v0.1.5
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||||
|
google.golang.org/api v0.56.0
|
||||||
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
|
google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83 // indirect
|
||||||
|
google.golang.org/grpc v1.40.0
|
||||||
|
google.golang.org/protobuf v1.27.1
|
||||||
|
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/goidentity.v3 v3.0.0 // indirect
|
||||||
gopkg.in/jcmturner/gokrb5.v7 v7.3.0 // indirect
|
gopkg.in/jcmturner/gokrb5.v7 v7.3.0 // indirect
|
||||||
gopkg.in/karlseguin/expect.v1 v1.0.1 // 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/opt v0.1.1 // indirect
|
||||||
|
modernc.org/sqlite v1.10.7
|
||||||
|
modernc.org/strutil v1.1.0 // indirect
|
||||||
|
modernc.org/token v1.0.0 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/coreos/etcd v3.3.10+incompatible // indirect
|
||||||
|
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 // indirect
|
||||||
|
github.com/d4l3k/messagediff v1.2.1 // indirect
|
||||||
|
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 // indirect
|
||||||
|
github.com/gogo/protobuf v1.3.2 // 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/mattn/go-runewidth v0.0.7 // indirect
|
||||||
|
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||||
|
github.com/pingcap/errors v0.11.5-0.20201126102027-b0a155152ca3 // indirect
|
||||||
|
github.com/pingcap/failpoint v0.0.0-20210316064728-7acb0f0a3dfd // indirect
|
||||||
|
github.com/pingcap/kvproto v0.0.0-20210806074406-317f69fb54b4 // indirect
|
||||||
|
github.com/pingcap/log v0.0.0-20210317133921-96f4fcab92a4 // indirect
|
||||||
|
github.com/pingcap/parser v0.0.0-20210525032559-c37778aff307 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
|
github.com/tikv/pd v1.1.0-beta.0.20210323121136-78679e5e209d // indirect
|
||||||
|
github.com/twmb/murmur3 v1.1.3 // indirect
|
||||||
|
go.etcd.io/etcd/api/v3 v3.5.0 // indirect
|
||||||
|
go.etcd.io/etcd/client/pkg/v3 v3.5.0 // indirect
|
||||||
|
go.etcd.io/etcd/client/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/lint v0.0.0-20210508222113-6edffad5e616 // indirect
|
||||||
|
golang.org/x/mod v0.4.2 // indirect
|
||||||
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
// replace github.com/seaweedfs/fuse => /Users/chris/go/src/github.com/seaweedfs/fuse
|
// replace github.com/seaweedfs/fuse => /Users/chris/go/src/github.com/seaweedfs/fuse
|
||||||
// replace github.com/chrislusf/raft => /Users/chris/go/src/github.com/chrislusf/raft
|
// replace github.com/chrislusf/raft => /Users/chris/go/src/github.com/chrislusf/raft
|
||||||
|
|
||||||
replace go.etcd.io/etcd => go.etcd.io/etcd v0.5.0-alpha.5.0.20200425165423-262c93980547
|
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
## SEAWEEDFS - helm chart (2.x)
|
|
||||||
|
|
||||||
### info:
|
|
||||||
* master/filer/volume are stateful sets with anti-affinity on the hostname,
|
|
||||||
so your deployment will be spread/HA.
|
|
||||||
* chart is using memsql(mysql) as the filer backend to enable HA (multiple filer instances)
|
|
||||||
and backup/HA memsql can provide.
|
|
||||||
* mysql user/password are created in a k8s secret (secret-seaweedfs-db.yaml) and injected to the filer
|
|
||||||
with ENV.
|
|
||||||
* cert config exists and can be enabled, but not been tested.
|
|
||||||
|
|
||||||
### current instances config (AIO):
|
|
||||||
1 instance for each type (master/filer/volume/s3)
|
|
||||||
|
|
||||||
instances need node labels:
|
|
||||||
* sw-volume: true (for volume instance, specific tag)
|
|
||||||
* sw-backend: true (for all others, as they less resource demanding)
|
|
||||||
|
|
||||||
you can update the replicas count for each node type in values.yaml,
|
|
||||||
need to add more nodes with the corresponding label.
|
|
||||||
|
|
||||||
most of the configuration are available through values.yaml
|
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
description: SeaweedFS
|
description: SeaweedFS
|
||||||
name: seaweedfs
|
name: seaweedfs
|
||||||
appVersion: "2.23"
|
appVersion: "2.69"
|
||||||
version: 2.23
|
version: "2.69"
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
## SEAWEEDFS - helm chart (2.x)
|
||||||
|
|
||||||
|
### info:
|
||||||
|
* master/filer/volume are stateful sets with anti-affinity on the hostname,
|
||||||
|
so your deployment will be spread/HA.
|
||||||
|
* chart is using memsql(mysql) as the filer backend to enable HA (multiple filer instances)
|
||||||
|
and backup/HA memsql can provide.
|
||||||
|
* mysql user/password are created in a k8s secret (secret-seaweedfs-db.yaml) and injected to the filer
|
||||||
|
with ENV.
|
||||||
|
* cert config exists and can be enabled, but not been tested.
|
||||||
|
|
||||||
|
### prerequisites
|
||||||
|
kubernetes node have labels which help to define which node(Host) will run which pod.
|
||||||
|
|
||||||
|
s3/filer/master needs the label **sw-backend=true**
|
||||||
|
|
||||||
|
volume need the label **sw-volume=true**
|
||||||
|
|
||||||
|
to label a node to be able to run all pod types in k8s:
|
||||||
|
```
|
||||||
|
kubectl label node YOUR_NODE_NAME sw-volume=true,sw-backend=true
|
||||||
|
```
|
||||||
|
|
||||||
|
on production k8s deployment you will want each pod to have a different host,
|
||||||
|
especially the volume server & the masters, currently all pods (master/volume/filer)
|
||||||
|
have anti-affinity rule to disallow running multiple pod type on the same host.
|
||||||
|
if you still want to run multiple pods of the same type (master/volume/filer) on the same host
|
||||||
|
please set/update the corresponding affinity rule in values.yaml to an empty one:
|
||||||
|
|
||||||
|
```affinity: ""```
|
||||||
|
|
||||||
|
### PVC - storage class ###
|
||||||
|
|
||||||
|
on the volume stateful set added support for K8S PVC, currently example
|
||||||
|
with the simple local-path-provisioner from Rancher (comes included with k3d / k3s)
|
||||||
|
https://github.com/rancher/local-path-provisioner
|
||||||
|
|
||||||
|
you can use ANY storage class you like, just update the correct storage-class
|
||||||
|
for your deployment.
|
||||||
|
|
||||||
|
### current instances config (AIO):
|
||||||
|
1 instance for each type (master/filer+s3/volume)
|
||||||
|
|
||||||
|
you can update the replicas count for each node type in values.yaml,
|
||||||
|
need to add more nodes with the corresponding labels.
|
||||||
|
|
||||||
|
most of the configuration are available through values.yaml
|
||||||
|
|
||||||
@@ -126,3 +126,26 @@ Inject extra environment vars in the format key:value, if populated
|
|||||||
{{- printf "%s%s%s:%s" $registryName $repositoryName $name $tag -}}
|
{{- printf "%s%s%s:%s" $registryName $repositoryName $name $tag -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
|
|
||||||
|
{{/* check if any PVC exists */}}
|
||||||
|
{{- define "volume.pvc_exists" -}}
|
||||||
|
{{- if or (or (eq .Values.volume.data.type "persistentVolumeClaim") (and (eq .Values.volume.idx.type "persistentVolumeClaim") .Values.volume.dir_idx )) (eq .Values.volume.logs.type "persistentVolumeClaim") -}}
|
||||||
|
{{- printf "true" -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- printf "false" -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{/* check if any HostPath exists */}}
|
||||||
|
{{- define "volume.hostpath_exists" -}}
|
||||||
|
{{- if or (or (eq .Values.volume.data.type "hostPath") (and (eq .Values.volume.idx.type "hostPath") .Values.volume.dir_idx )) (eq .Values.volume.logs.type "hostPath") -}}
|
||||||
|
{{- printf "true" -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- if or .Values.global.enableSecurity .Values.volume.extraVolumes -}}
|
||||||
|
{{- printf "true" -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- printf "false" -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
@@ -15,13 +15,13 @@ spec:
|
|||||||
backoffLimit: 2
|
backoffLimit: 2
|
||||||
template:
|
template:
|
||||||
spec:
|
spec:
|
||||||
{{- with .Values.cronjob.nodeSelector }}
|
{{- if .Values.cronjob.nodeSelector }}
|
||||||
nodeSelector:
|
nodeSelector:
|
||||||
{{- toYaml . | nindent 12 }}
|
{{ tpl .Values.cronjob.nodeSelector . | indent 12 | trim }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- with .Values.cronjob.tolerations }}
|
{{- if .Values.cronjob.tolerations }}
|
||||||
tolerations:
|
tolerations:
|
||||||
{{- toYaml . | nindent 12 }}
|
{{ tpl .Values.cronjob.tolerations . | nindent 12 | trim }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
restartPolicy: OnFailure
|
restartPolicy: OnFailure
|
||||||
containers:
|
containers:
|
||||||
@@ -36,10 +36,13 @@ spec:
|
|||||||
- |
|
- |
|
||||||
set -ex
|
set -ex
|
||||||
echo -e "lock\n\
|
echo -e "lock\n\
|
||||||
volume.balance -force\
|
volume.balance -force \
|
||||||
{{ if .Values.volume.dataCenter }} -dataCenter {{ .Values.volume.dataCenter }}{{ end }}\
|
{{ if .Values.volume.dataCenter }} -dataCenter {{ .Values.volume.dataCenter }}{{ end }}\
|
||||||
{{ if .Values.cronjob.collection }} -collection {{ .Values.cronjob.collection }}{{ end }}\n\
|
{{ if .Values.cronjob.collection }} -collection {{ .Values.cronjob.collection }}{{ end }}\n\
|
||||||
volume.fix.replication\nunlock\n" | \
|
{{- if .Values.cronjob.enableFixReplication }}
|
||||||
|
volume.fix.replication -collectionPattern={{ .Values.cronjob.collectionPattern }} \n\
|
||||||
|
{{- end }}
|
||||||
|
unlock\n" | \
|
||||||
/usr/bin/weed shell \
|
/usr/bin/weed shell \
|
||||||
{{- if .Values.cronjob.master }}
|
{{- if .Values.cronjob.master }}
|
||||||
-master {{ .Values.cronjob.master }} \
|
-master {{ .Values.cronjob.master }} \
|
||||||
+1
-1
@@ -28,4 +28,4 @@ spec:
|
|||||||
{{- end }}
|
{{- end }}
|
||||||
selector:
|
selector:
|
||||||
app: {{ template "seaweedfs.name" . }}
|
app: {{ template "seaweedfs.name" . }}
|
||||||
component: filer
|
component: filer
|
||||||
+29
@@ -133,14 +133,36 @@ spec:
|
|||||||
-encryptVolumeData \
|
-encryptVolumeData \
|
||||||
{{- end }}
|
{{- end }}
|
||||||
-ip=${POD_IP} \
|
-ip=${POD_IP} \
|
||||||
|
{{- if .Values.filer.enable_peers }}
|
||||||
{{- if gt (.Values.filer.replicas | int) 1 }}
|
{{- if gt (.Values.filer.replicas | int) 1 }}
|
||||||
-peers=$(echo -n "{{ range $index := until (.Values.filer.replicas | int) }}${SEAWEEDFS_FULLNAME}-filer-{{ $index }}.${SEAWEEDFS_FULLNAME}-filer:{{ $.Values.filer.port }}{{ if lt $index (sub ($.Values.filer.replicas | int) 1) }},{{ end }}{{ end }}" | sed "s/$HOSTNAME.${SEAWEEDFS_FULLNAME}-filer:{{ $.Values.filer.port }}//" | sed 's/,$//; 's/^,//'; s/,,/,/;' ) \
|
-peers=$(echo -n "{{ range $index := until (.Values.filer.replicas | int) }}${SEAWEEDFS_FULLNAME}-filer-{{ $index }}.${SEAWEEDFS_FULLNAME}-filer:{{ $.Values.filer.port }}{{ if lt $index (sub ($.Values.filer.replicas | int) 1) }},{{ end }}{{ end }}" | sed "s/$HOSTNAME.${SEAWEEDFS_FULLNAME}-filer:{{ $.Values.filer.port }}//" | sed 's/,$//; 's/^,//'; s/,,/,/;' ) \
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.filer.s3.enabled }}
|
||||||
|
-s3 \
|
||||||
|
-s3.port={{ .Values.filer.s3.port }} \
|
||||||
|
{{- if .Values.filer.s3.domainName }}
|
||||||
|
-s3.domainName={{ .Values.filer.s3.domainName }} \
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.global.enableSecurity }}
|
||||||
|
-s3.cert.file=/usr/local/share/ca-certificates/client/tls.crt \
|
||||||
|
-s3.key.file=/usr/local/share/ca-certificates/client/tls.key \
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.filer.s3.allowEmptyFolder }}
|
||||||
|
-s3.allowEmptyFolder={{ .Values.filer.s3.allowEmptyFolder }} \
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.filer.s3.enableAuth }}
|
||||||
|
-s3.config=/etc/sw/seaweedfs_s3_config \
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
-master={{ range $index := until (.Values.master.replicas | int) }}${SEAWEEDFS_FULLNAME}-master-{{ $index }}.${SEAWEEDFS_FULLNAME}-master:{{ $.Values.master.port }}{{ if lt $index (sub ($.Values.master.replicas | int) 1) }},{{ end }}{{ end }}
|
-master={{ range $index := until (.Values.master.replicas | int) }}${SEAWEEDFS_FULLNAME}-master-{{ $index }}.${SEAWEEDFS_FULLNAME}-master:{{ $.Values.master.port }}{{ if lt $index (sub ($.Values.master.replicas | int) 1) }},{{ end }}{{ end }}
|
||||||
{{- if or (.Values.global.enableSecurity) (.Values.filer.extraVolumeMounts) }}
|
{{- if or (.Values.global.enableSecurity) (.Values.filer.extraVolumeMounts) }}
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: seaweedfs-filer-log-volume
|
- name: seaweedfs-filer-log-volume
|
||||||
mountPath: "/logs/"
|
mountPath: "/logs/"
|
||||||
|
- mountPath: /etc/sw
|
||||||
|
name: config-users
|
||||||
|
readOnly: true
|
||||||
{{- if .Values.global.enableSecurity }}
|
{{- if .Values.global.enableSecurity }}
|
||||||
- name: security-config
|
- name: security-config
|
||||||
readOnly: true
|
readOnly: true
|
||||||
@@ -198,6 +220,13 @@ spec:
|
|||||||
hostPath:
|
hostPath:
|
||||||
path: /storage/logs/seaweedfs/filer
|
path: /storage/logs/seaweedfs/filer
|
||||||
type: DirectoryOrCreate
|
type: DirectoryOrCreate
|
||||||
|
- name: db-schema-config-volume
|
||||||
|
configMap:
|
||||||
|
name: seaweedfs-db-init-config
|
||||||
|
- name: config-users
|
||||||
|
secret:
|
||||||
|
defaultMode: 420
|
||||||
|
secretName: seaweedfs-s3-secret
|
||||||
{{- if .Values.global.enableSecurity }}
|
{{- if .Values.global.enableSecurity }}
|
||||||
- name: security-config
|
- name: security-config
|
||||||
configMap:
|
configMap:
|
||||||
+10
@@ -90,10 +90,16 @@ spec:
|
|||||||
{{- if .Values.s3.allowEmptyFolder }}
|
{{- if .Values.s3.allowEmptyFolder }}
|
||||||
-allowEmptyFolder={{ .Values.s3.allowEmptyFolder }} \
|
-allowEmptyFolder={{ .Values.s3.allowEmptyFolder }} \
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
{{- if .Values.s3.enableAuth }}
|
||||||
|
-config=/etc/sw/seaweedfs_s3_config \
|
||||||
|
{{- end }}
|
||||||
-filer={{ template "seaweedfs.name" . }}-filer-client:{{ .Values.filer.port }}
|
-filer={{ template "seaweedfs.name" . }}-filer-client:{{ .Values.filer.port }}
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: logs
|
- name: logs
|
||||||
mountPath: "/logs/"
|
mountPath: "/logs/"
|
||||||
|
- mountPath: /etc/sw
|
||||||
|
name: config-users
|
||||||
|
readOnly: true
|
||||||
{{- if .Values.global.enableSecurity }}
|
{{- if .Values.global.enableSecurity }}
|
||||||
- name: security-config
|
- name: security-config
|
||||||
readOnly: true
|
readOnly: true
|
||||||
@@ -144,6 +150,10 @@ spec:
|
|||||||
{{ tpl .Values.s3.resources . | nindent 12 | trim }}
|
{{ tpl .Values.s3.resources . | nindent 12 | trim }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
volumes:
|
volumes:
|
||||||
|
- name: config-users
|
||||||
|
secret:
|
||||||
|
defaultMode: 420
|
||||||
|
secretName: seaweedfs-s3-secret
|
||||||
{{- if eq .Values.s3.logs.type "hostPath" }}
|
{{- if eq .Values.s3.logs.type "hostPath" }}
|
||||||
- name: logs
|
- name: logs
|
||||||
hostPath:
|
hostPath:
|
||||||
+5
-5
@@ -9,15 +9,15 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
ports:
|
ports:
|
||||||
- name: "swfs-s3"
|
- name: "swfs-s3"
|
||||||
port: {{ .Values.s3.port }}
|
port: {{ if .Values.s3.enabled }}{{ .Values.s3.port }}{{ else }}{{ .Values.filer.s3.port }}{{ end }}
|
||||||
targetPort: {{ .Values.s3.port }}
|
targetPort: {{ if .Values.s3.enabled }}{{ .Values.s3.port }}{{ else }}{{ .Values.filer.s3.port }}{{ end }}
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
{{- if .Values.s3.metricsPort }}
|
{{- if and .Values.s3.enabled .Values.s3.metricsPort }}
|
||||||
- name: "swfs-s3-metrics"
|
- name: "metrics"
|
||||||
port: {{ .Values.s3.metricsPort }}
|
port: {{ .Values.s3.metricsPort }}
|
||||||
targetPort: {{ .Values.s3.metricsPort }}
|
targetPort: {{ .Values.s3.metricsPort }}
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
{{- end }}
|
{{- end }}
|
||||||
selector:
|
selector:
|
||||||
app: {{ template "seaweedfs.name" . }}
|
app: {{ template "seaweedfs.name" . }}
|
||||||
component: s3
|
component: {{ if .Values.s3.enabled }}s3{{ else }}filer{{ end }}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
{{- if not (or .Values.filer.s3.skipAuthSecretCreation .Values.s3.skipAuthSecretCreation) }}
|
||||||
|
{{- $access_key_admin := randAlphaNum 16 -}}
|
||||||
|
{{- $secret_key_admin := randAlphaNum 32 -}}
|
||||||
|
{{- $access_key_read := randAlphaNum 16 -}}
|
||||||
|
{{- $secret_key_read := randAlphaNum 32 -}}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
type: Opaque
|
||||||
|
metadata:
|
||||||
|
name: seaweedfs-s3-secret
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
annotations:
|
||||||
|
"helm.sh/resource-policy": keep
|
||||||
|
"helm.sh/hook": "pre-install"
|
||||||
|
stringData:
|
||||||
|
admin_access_key_id: {{ $access_key_admin }}
|
||||||
|
admin_secret_access_key: {{ $secret_key_admin }}
|
||||||
|
read_access_key_id: {{ $access_key_read }}
|
||||||
|
read_secret_access_key: {{ $secret_key_read }}
|
||||||
|
seaweedfs_s3_config: '{"identities":[{"name":"anvAdmin","credentials":[{"accessKey":"{{ $access_key_admin }}","secretKey":"{{ $secret_key_admin }}"}],"actions":["Admin","Read","Write"]},{"name":"anvReadOnly","credentials":[{"accessKey":"{{ $access_key_read }}","secretKey":"{{ $secret_key_read }}"}],"actions":["Read"]}]}'
|
||||||
|
{{- end }}
|
||||||
+1
-1
@@ -23,6 +23,6 @@ spec:
|
|||||||
targetPort: {{ .Values.volume.metricsPort }}
|
targetPort: {{ .Values.volume.metricsPort }}
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
{{- end }}
|
{{- end }}
|
||||||
selector:
|
selector:
|
||||||
app: {{ template "seaweedfs.name" . }}
|
app: {{ template "seaweedfs.name" . }}
|
||||||
component: volume
|
component: volume
|
||||||
+73
-9
@@ -45,6 +45,19 @@ spec:
|
|||||||
priorityClassName: {{ .Values.volume.priorityClassName | quote }}
|
priorityClassName: {{ .Values.volume.priorityClassName | quote }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
enableServiceLinks: false
|
enableServiceLinks: false
|
||||||
|
{{- if .Values.volume.dir_idx }}
|
||||||
|
initContainers:
|
||||||
|
- name: seaweedfs-vol-move-idx
|
||||||
|
image: {{ template "volume.image" . }}
|
||||||
|
imagePullPolicy: {{ .Values.global.pullPolicy | default "IfNotPresent" }}
|
||||||
|
command: [ '/bin/sh', '-c' ]
|
||||||
|
args: ['if ls {{ .Values.volume.dir }}/*.idx >/dev/null 2>&1; then mv {{ .Values.volume.dir }}/*.idx {{ .Values.volume.dir_idx }}/; fi;']
|
||||||
|
volumeMounts:
|
||||||
|
- name: idx
|
||||||
|
mountPath: {{ .Values.volume.dir_idx }}
|
||||||
|
- name: data
|
||||||
|
mountPath: {{ .Values.volume.dir }}
|
||||||
|
{{- end }}
|
||||||
containers:
|
containers:
|
||||||
- name: seaweedfs
|
- name: seaweedfs
|
||||||
image: {{ template "volume.image" . }}
|
image: {{ template "volume.image" . }}
|
||||||
@@ -97,7 +110,7 @@ spec:
|
|||||||
-dataCenter={{ .Values.volume.dataCenter }} \
|
-dataCenter={{ .Values.volume.dataCenter }} \
|
||||||
{{- end }}
|
{{- end }}
|
||||||
-ip.bind={{ .Values.volume.ipBind }} \
|
-ip.bind={{ .Values.volume.ipBind }} \
|
||||||
-read.redirect={{ .Values.volume.readRedirect }} \
|
-readMode={{ .Values.volume.readMode }} \
|
||||||
{{- if .Values.volume.whiteList }}
|
{{- if .Values.volume.whiteList }}
|
||||||
-whiteList={{ .Values.volume.whiteList }} \
|
-whiteList={{ .Values.volume.whiteList }} \
|
||||||
{{- end }}
|
{{- end }}
|
||||||
@@ -118,9 +131,13 @@ spec:
|
|||||||
-compactionMBps={{ .Values.volume.compactionMBps }} \
|
-compactionMBps={{ .Values.volume.compactionMBps }} \
|
||||||
-mserver={{ range $index := until (.Values.master.replicas | int) }}${SEAWEEDFS_FULLNAME}-master-{{ $index }}.${SEAWEEDFS_FULLNAME}-master:{{ $.Values.master.port }}{{ if lt $index (sub ($.Values.master.replicas | int) 1) }},{{ end }}{{ end }}
|
-mserver={{ range $index := until (.Values.master.replicas | int) }}${SEAWEEDFS_FULLNAME}-master-{{ $index }}.${SEAWEEDFS_FULLNAME}-master:{{ $.Values.master.port }}{{ if lt $index (sub ($.Values.master.replicas | int) 1) }},{{ end }}{{ end }}
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: seaweedfs-volume-storage
|
- name: data
|
||||||
mountPath: "/data/"
|
mountPath: "{{ .Values.volume.dir }}/"
|
||||||
- name: seaweedfs-volume-log-volume
|
{{- if .Values.volume.dir_idx }}
|
||||||
|
- name: idx
|
||||||
|
mountPath: "{{ .Values.volume.dir_idx }}/"
|
||||||
|
{{- end }}
|
||||||
|
- name: logs
|
||||||
mountPath: "/logs/"
|
mountPath: "/logs/"
|
||||||
{{- if .Values.global.enableSecurity }}
|
{{- if .Values.global.enableSecurity }}
|
||||||
- name: security-config
|
- name: security-config
|
||||||
@@ -173,15 +190,27 @@ spec:
|
|||||||
resources:
|
resources:
|
||||||
{{ tpl .Values.volume.resources . | nindent 12 | trim }}
|
{{ tpl .Values.volume.resources . | nindent 12 | trim }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
{{- $hostpath_exists := include "volume.hostpath_exists" . -}}
|
||||||
|
{{- if $hostpath_exists }}
|
||||||
volumes:
|
volumes:
|
||||||
- name: seaweedfs-volume-log-volume
|
{{- if eq .Values.volume.data.type "hostPath" }}
|
||||||
hostPath:
|
- name: data
|
||||||
path: /storage/logs/seaweedfs/volume
|
|
||||||
type: DirectoryOrCreate
|
|
||||||
- name: seaweedfs-volume-storage
|
|
||||||
hostPath:
|
hostPath:
|
||||||
path: /storage/object_store/
|
path: /storage/object_store/
|
||||||
type: DirectoryOrCreate
|
type: DirectoryOrCreate
|
||||||
|
{{- end }}
|
||||||
|
{{- if and (eq .Values.volume.idx.type "hostPath") .Values.volume.dir_idx }}
|
||||||
|
- name: idx
|
||||||
|
hostPath:
|
||||||
|
path: /ssd/seaweedfs-volume-idx/
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
{{- end }}
|
||||||
|
{{- if eq .Values.volume.logs.type "hostPath" }}
|
||||||
|
- name: logs
|
||||||
|
hostPath:
|
||||||
|
path: /storage/logs/seaweedfs/volume
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
{{- end }}
|
||||||
{{- if .Values.global.enableSecurity }}
|
{{- if .Values.global.enableSecurity }}
|
||||||
- name: security-config
|
- name: security-config
|
||||||
configMap:
|
configMap:
|
||||||
@@ -205,8 +234,43 @@ spec:
|
|||||||
{{- if .Values.volume.extraVolumes }}
|
{{- if .Values.volume.extraVolumes }}
|
||||||
{{ tpl .Values.volume.extraVolumes . | indent 8 | trim }}
|
{{ tpl .Values.volume.extraVolumes . | indent 8 | trim }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
{{- if .Values.volume.nodeSelector }}
|
{{- if .Values.volume.nodeSelector }}
|
||||||
nodeSelector:
|
nodeSelector:
|
||||||
{{ tpl .Values.volume.nodeSelector . | indent 8 | trim }}
|
{{ tpl .Values.volume.nodeSelector . | indent 8 | trim }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
{{- $pvc_exists := include "volume.pvc_exists" . -}}
|
||||||
|
{{- if $pvc_exists }}
|
||||||
|
volumeClaimTemplates:
|
||||||
|
{{- if eq .Values.volume.data.type "persistentVolumeClaim"}}
|
||||||
|
- metadata:
|
||||||
|
name: data
|
||||||
|
spec:
|
||||||
|
accessModes: [ "ReadWriteOnce" ]
|
||||||
|
storageClassName: {{ .Values.volume.data.storageClass }}
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: {{ .Values.volume.data.size }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if and (eq .Values.volume.idx.type "persistentVolumeClaim") .Values.volume.dir_idx }}
|
||||||
|
- metadata:
|
||||||
|
name: idx
|
||||||
|
spec:
|
||||||
|
accessModes: [ "ReadWriteOnce" ]
|
||||||
|
storageClassName: {{ .Values.volume.idx.storageClass }}
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: {{ .Values.volume.idx.size }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if eq .Values.volume.logs.type "persistentVolumeClaim" }}
|
||||||
|
- metadata:
|
||||||
|
name: logs
|
||||||
|
spec:
|
||||||
|
accessModes: [ "ReadWriteOnce" ]
|
||||||
|
storageClassName: {{ .Values.volume.logs.storageClass }}
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: {{ .Values.volume.logs.size }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
@@ -4,7 +4,6 @@ global:
|
|||||||
registry: ""
|
registry: ""
|
||||||
repository: ""
|
repository: ""
|
||||||
imageName: chrislusf/seaweedfs
|
imageName: chrislusf/seaweedfs
|
||||||
# imageTag: "2.23" - started using {.Chart.appVersion}
|
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
imagePullSecrets: imagepullsecret
|
imagePullSecrets: imagepullsecret
|
||||||
restartPolicy: Always
|
restartPolicy: Always
|
||||||
@@ -136,8 +135,26 @@ volume:
|
|||||||
# limit file size to avoid out of memory, default 256mb
|
# limit file size to avoid out of memory, default 256mb
|
||||||
fileSizeLimitMB: null
|
fileSizeLimitMB: null
|
||||||
# minimum free disk space(in percents). If free disk space lower this value - all volumes marks as ReadOnly
|
# minimum free disk space(in percents). If free disk space lower this value - all volumes marks as ReadOnly
|
||||||
minFreeSpacePercent: 1
|
minFreeSpacePercent: 7
|
||||||
|
|
||||||
|
# can use ANY storage-class , example with local-path-provisner
|
||||||
|
# data:
|
||||||
|
# type: "persistentVolumeClaim"
|
||||||
|
# size: "24Ti"
|
||||||
|
# storageClass: "local-path-provisioner"
|
||||||
|
data:
|
||||||
|
type: "hostPath"
|
||||||
|
size: ""
|
||||||
|
storageClass: ""
|
||||||
|
idx:
|
||||||
|
type: "hostPath"
|
||||||
|
size: ""
|
||||||
|
storageClass: ""
|
||||||
|
|
||||||
|
logs:
|
||||||
|
type: "hostPath"
|
||||||
|
size: ""
|
||||||
|
storageClass: ""
|
||||||
|
|
||||||
# limit background compaction or copying speed in mega bytes per second
|
# limit background compaction or copying speed in mega bytes per second
|
||||||
compactionMBps: "50"
|
compactionMBps: "50"
|
||||||
@@ -157,8 +174,8 @@ volume:
|
|||||||
# Volume server's data center name
|
# Volume server's data center name
|
||||||
dataCenter: null
|
dataCenter: null
|
||||||
|
|
||||||
# Redirect moved or non-local volumes. (default true)
|
# Redirect moved or non-local volumes. (default proxy)
|
||||||
readRedirect: true
|
readMode: proxy
|
||||||
|
|
||||||
# Comma separated Ip addresses having write permission. No limit if empty.
|
# Comma separated Ip addresses having write permission. No limit if empty.
|
||||||
whiteList: null
|
whiteList: null
|
||||||
@@ -229,6 +246,8 @@ filer:
|
|||||||
maxMB: null
|
maxMB: null
|
||||||
# encrypt data on volume servers
|
# encrypt data on volume servers
|
||||||
encryptVolumeData: false
|
encryptVolumeData: false
|
||||||
|
# enable peers sync metadata, for leveldb (localdb for filer but with sync across)
|
||||||
|
enable_peers: false
|
||||||
|
|
||||||
# Whether proxy or redirect to volume server during file GET request
|
# Whether proxy or redirect to volume server during file GET request
|
||||||
redirectOnRead: false
|
redirectOnRead: false
|
||||||
@@ -311,8 +330,19 @@ filer:
|
|||||||
# directories under this folder will be automatically creating a separate bucket
|
# directories under this folder will be automatically creating a separate bucket
|
||||||
WEED_FILER_BUCKETS_FOLDER: "/buckets"
|
WEED_FILER_BUCKETS_FOLDER: "/buckets"
|
||||||
|
|
||||||
|
s3:
|
||||||
|
enabled: true
|
||||||
|
port: 8333
|
||||||
|
#allow empty folders
|
||||||
|
allowEmptyFolder: false
|
||||||
|
# Suffix of the host name, {bucket}.{domainName}
|
||||||
|
domainName: ""
|
||||||
|
# enable user & permission to s3 (need to inject to all services)
|
||||||
|
enableAuth: false
|
||||||
|
skipAuthSecretCreation: false
|
||||||
|
|
||||||
s3:
|
s3:
|
||||||
enabled: true
|
enabled: false
|
||||||
repository: null
|
repository: null
|
||||||
imageName: null
|
imageName: null
|
||||||
imageTag: null
|
imageTag: null
|
||||||
@@ -323,6 +353,9 @@ s3:
|
|||||||
loggingOverrideLevel: null
|
loggingOverrideLevel: null
|
||||||
#allow empty folders
|
#allow empty folders
|
||||||
allowEmptyFolder: true
|
allowEmptyFolder: true
|
||||||
|
# enable user & permission to s3 (need to inject to all services)
|
||||||
|
enableAuth: false
|
||||||
|
skipAuthSecretCreation: false
|
||||||
|
|
||||||
# Suffix of the host name, {bucket}.{domainName}
|
# Suffix of the host name, {bucket}.{domainName}
|
||||||
domainName: ""
|
domainName: ""
|
||||||
@@ -359,17 +392,21 @@ s3:
|
|||||||
storageClass: ""
|
storageClass: ""
|
||||||
|
|
||||||
cronjob:
|
cronjob:
|
||||||
enabled: false
|
enabled: true
|
||||||
|
master: "seaweedfs-master:9333"
|
||||||
|
filer: "seaweedfs-filer-client:8888"
|
||||||
|
tolerations: ""
|
||||||
|
nodeSelector: |
|
||||||
|
sw-backend: "true"
|
||||||
|
replication:
|
||||||
|
enable: true
|
||||||
|
collectionPattern: ""
|
||||||
schedule: "*/7 * * * *"
|
schedule: "*/7 * * * *"
|
||||||
resources: null
|
resources: null
|
||||||
# balance all volumes among volume servers
|
# balance all volumes among volume servers
|
||||||
# ALL|EACH_COLLECTION|<collection_name>
|
# ALL|EACH_COLLECTION|<collection_name>
|
||||||
collection: ""
|
collection: ""
|
||||||
master: ""
|
|
||||||
filer: ""
|
|
||||||
tolerations: ""
|
|
||||||
nodeSelector: |
|
|
||||||
sw-backend: "true"
|
|
||||||
|
|
||||||
certificates:
|
certificates:
|
||||||
commonName: "SeaweedFS CA"
|
commonName: "SeaweedFS CA"
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 86 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 95 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 81 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 62 KiB |
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<groupId>com.github.chrislusf</groupId>
|
<groupId>com.github.chrislusf</groupId>
|
||||||
<artifactId>seaweedfs-client</artifactId>
|
<artifactId>seaweedfs-client</artifactId>
|
||||||
<version>1.5.7</version>
|
<version>1.6.8</version>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.sonatype.oss</groupId>
|
<groupId>org.sonatype.oss</groupId>
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
<protobuf.version>3.9.1</protobuf.version>
|
<protobuf.version>3.9.1</protobuf.version>
|
||||||
<!-- follow https://github.com/grpc/grpc-java -->
|
<!-- follow https://github.com/grpc/grpc-java -->
|
||||||
<grpc.version>1.23.0</grpc.version>
|
<grpc.version>1.23.0</grpc.version>
|
||||||
<guava.version>28.0-jre</guava.version>
|
<guava.version>30.0-jre</guava.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@@ -135,7 +135,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.sonatype.plugins</groupId>
|
<groupId>org.sonatype.plugins</groupId>
|
||||||
<artifactId>nexus-staging-maven-plugin</artifactId>
|
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||||
<version>1.6.7</version>
|
<version>1.6.8</version>
|
||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<serverId>ossrh</serverId>
|
<serverId>ossrh</serverId>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<groupId>com.github.chrislusf</groupId>
|
<groupId>com.github.chrislusf</groupId>
|
||||||
<artifactId>seaweedfs-client</artifactId>
|
<artifactId>seaweedfs-client</artifactId>
|
||||||
<version>1.5.7</version>
|
<version>1.6.8</version>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.sonatype.oss</groupId>
|
<groupId>org.sonatype.oss</groupId>
|
||||||
@@ -130,7 +130,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.sonatype.plugins</groupId>
|
<groupId>org.sonatype.plugins</groupId>
|
||||||
<artifactId>nexus-staging-maven-plugin</artifactId>
|
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||||
<version>1.6.7</version>
|
<version>1.6.8</version>
|
||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<serverId>ossrh</serverId>
|
<serverId>ossrh</serverId>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<groupId>com.github.chrislusf</groupId>
|
<groupId>com.github.chrislusf</groupId>
|
||||||
<artifactId>seaweedfs-client</artifactId>
|
<artifactId>seaweedfs-client</artifactId>
|
||||||
<version>1.5.7</version>
|
<version>1.6.8</version>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.sonatype.oss</groupId>
|
<groupId>org.sonatype.oss</groupId>
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ package seaweedfs.client;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.nio.Buffer;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ByteBufferPool {
|
public class ByteBufferPool {
|
||||||
|
|
||||||
private static final int MIN_BUFFER_SIZE = 8 * 1024 * 1024;
|
private static final int MIN_BUFFER_SIZE = 1 * 1024 * 1024;
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(ByteBufferPool.class);
|
private static final Logger LOG = LoggerFactory.getLogger(ByteBufferPool.class);
|
||||||
|
|
||||||
private static final List<ByteBuffer> bufferList = new ArrayList<>();
|
private static final List<ByteBuffer> bufferList = new ArrayList<>();
|
||||||
@@ -34,7 +35,7 @@ public class ByteBufferPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized void release(ByteBuffer obj) {
|
public static synchronized void release(ByteBuffer obj) {
|
||||||
obj.clear();
|
((Buffer)obj).clear();
|
||||||
bufferList.add(0, obj);
|
bufferList.add(0, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public class FileChunkManifest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static List<FilerProto.FileChunk> resolveChunkManifest(
|
public static List<FilerProto.FileChunk> resolveChunkManifest(
|
||||||
final FilerGrpcClient filerGrpcClient, List<FilerProto.FileChunk> chunks) throws IOException {
|
final FilerClient filerClient, List<FilerProto.FileChunk> chunks) throws IOException {
|
||||||
|
|
||||||
List<FilerProto.FileChunk> dataChunks = new ArrayList<>();
|
List<FilerProto.FileChunk> dataChunks = new ArrayList<>();
|
||||||
|
|
||||||
@@ -35,30 +35,30 @@ public class FileChunkManifest {
|
|||||||
|
|
||||||
// IsChunkManifest
|
// IsChunkManifest
|
||||||
LOG.debug("fetching chunk manifest:{}", chunk);
|
LOG.debug("fetching chunk manifest:{}", chunk);
|
||||||
byte[] data = fetchChunk(filerGrpcClient, chunk);
|
byte[] data = fetchChunk(filerClient, chunk);
|
||||||
FilerProto.FileChunkManifest m = FilerProto.FileChunkManifest.newBuilder().mergeFrom(data).build();
|
FilerProto.FileChunkManifest m = FilerProto.FileChunkManifest.newBuilder().mergeFrom(data).build();
|
||||||
List<FilerProto.FileChunk> resolvedChunks = new ArrayList<>();
|
List<FilerProto.FileChunk> resolvedChunks = new ArrayList<>();
|
||||||
for (FilerProto.FileChunk t : m.getChunksList()) {
|
for (FilerProto.FileChunk t : m.getChunksList()) {
|
||||||
// avoid deprecated chunk.getFileId()
|
// avoid deprecated chunk.getFileId()
|
||||||
resolvedChunks.add(t.toBuilder().setFileId(FilerClient.toFileId(t.getFid())).build());
|
resolvedChunks.add(t.toBuilder().setFileId(FilerClient.toFileId(t.getFid())).build());
|
||||||
}
|
}
|
||||||
dataChunks.addAll(resolveChunkManifest(filerGrpcClient, resolvedChunks));
|
dataChunks.addAll(resolveChunkManifest(filerClient, resolvedChunks));
|
||||||
}
|
}
|
||||||
|
|
||||||
return dataChunks;
|
return dataChunks;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] fetchChunk(final FilerGrpcClient filerGrpcClient, FilerProto.FileChunk chunk) throws IOException {
|
private static byte[] fetchChunk(final FilerClient filerClient, FilerProto.FileChunk chunk) throws IOException {
|
||||||
|
|
||||||
String vid = "" + chunk.getFid().getVolumeId();
|
String vid = "" + chunk.getFid().getVolumeId();
|
||||||
FilerProto.Locations locations = filerGrpcClient.vidLocations.get(vid);
|
FilerProto.Locations locations = filerClient.vidLocations.get(vid);
|
||||||
if (locations == null) {
|
if (locations == null) {
|
||||||
FilerProto.LookupVolumeRequest.Builder lookupRequest = FilerProto.LookupVolumeRequest.newBuilder();
|
FilerProto.LookupVolumeRequest.Builder lookupRequest = FilerProto.LookupVolumeRequest.newBuilder();
|
||||||
lookupRequest.addVolumeIds(vid);
|
lookupRequest.addVolumeIds(vid);
|
||||||
FilerProto.LookupVolumeResponse lookupResponse = filerGrpcClient
|
FilerProto.LookupVolumeResponse lookupResponse = filerClient
|
||||||
.getBlockingStub().lookupVolume(lookupRequest.build());
|
.getBlockingStub().lookupVolume(lookupRequest.build());
|
||||||
locations = lookupResponse.getLocationsMapMap().get(vid);
|
locations = lookupResponse.getLocationsMapMap().get(vid);
|
||||||
filerGrpcClient.vidLocations.put(vid, locations);
|
filerClient.vidLocations.put(vid, locations);
|
||||||
LOG.debug("fetchChunk vid:{} locations:{}", vid, locations);
|
LOG.debug("fetchChunk vid:{} locations:{}", vid, locations);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ public class FileChunkManifest {
|
|||||||
byte[] chunkData = SeaweedRead.chunkCache.getChunk(chunkView.fileId);
|
byte[] chunkData = SeaweedRead.chunkCache.getChunk(chunkView.fileId);
|
||||||
if (chunkData == null) {
|
if (chunkData == null) {
|
||||||
LOG.debug("doFetchFullChunkData:{}", chunkView);
|
LOG.debug("doFetchFullChunkData:{}", chunkView);
|
||||||
chunkData = SeaweedRead.doFetchFullChunkData(chunkView, locations);
|
chunkData = SeaweedRead.doFetchFullChunkData(filerClient, chunkView, locations);
|
||||||
}
|
}
|
||||||
if (chunk.getIsChunkManifest()){
|
if (chunk.getIsChunkManifest()){
|
||||||
LOG.debug("chunk {} size {}", chunkView.fileId, chunkData.length);
|
LOG.debug("chunk {} size {}", chunkView.fileId, chunkData.length);
|
||||||
@@ -86,7 +86,7 @@ public class FileChunkManifest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static List<FilerProto.FileChunk> maybeManifestize(
|
public static List<FilerProto.FileChunk> maybeManifestize(
|
||||||
final FilerGrpcClient filerGrpcClient, List<FilerProto.FileChunk> inputChunks, String parentDirectory) throws IOException {
|
final FilerClient filerClient, List<FilerProto.FileChunk> inputChunks, String parentDirectory) throws IOException {
|
||||||
// the return variable
|
// the return variable
|
||||||
List<FilerProto.FileChunk> chunks = new ArrayList<>();
|
List<FilerProto.FileChunk> chunks = new ArrayList<>();
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ public class FileChunkManifest {
|
|||||||
|
|
||||||
int remaining = dataChunks.size();
|
int remaining = dataChunks.size();
|
||||||
for (int i = 0; i + mergeFactor < dataChunks.size(); i += mergeFactor) {
|
for (int i = 0; i + mergeFactor < dataChunks.size(); i += mergeFactor) {
|
||||||
FilerProto.FileChunk chunk = mergeIntoManifest(filerGrpcClient, dataChunks.subList(i, i + mergeFactor), parentDirectory);
|
FilerProto.FileChunk chunk = mergeIntoManifest(filerClient, dataChunks.subList(i, i + mergeFactor), parentDirectory);
|
||||||
chunks.add(chunk);
|
chunks.add(chunk);
|
||||||
remaining -= mergeFactor;
|
remaining -= mergeFactor;
|
||||||
}
|
}
|
||||||
@@ -113,7 +113,7 @@ public class FileChunkManifest {
|
|||||||
return chunks;
|
return chunks;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static FilerProto.FileChunk mergeIntoManifest(final FilerGrpcClient filerGrpcClient, List<FilerProto.FileChunk> dataChunks, String parentDirectory) throws IOException {
|
private static FilerProto.FileChunk mergeIntoManifest(final FilerClient filerClient, List<FilerProto.FileChunk> dataChunks, String parentDirectory) throws IOException {
|
||||||
// create and serialize the manifest
|
// create and serialize the manifest
|
||||||
dataChunks = FilerClient.beforeEntrySerialization(dataChunks);
|
dataChunks = FilerClient.beforeEntrySerialization(dataChunks);
|
||||||
FilerProto.FileChunkManifest.Builder m = FilerProto.FileChunkManifest.newBuilder().addAllChunks(dataChunks);
|
FilerProto.FileChunkManifest.Builder m = FilerProto.FileChunkManifest.newBuilder().addAllChunks(dataChunks);
|
||||||
@@ -127,8 +127,8 @@ public class FileChunkManifest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FilerProto.FileChunk.Builder manifestChunk = SeaweedWrite.writeChunk(
|
FilerProto.FileChunk.Builder manifestChunk = SeaweedWrite.writeChunk(
|
||||||
filerGrpcClient.getReplication(),
|
filerClient.getReplication(),
|
||||||
filerGrpcClient,
|
filerClient,
|
||||||
minOffset,
|
minOffset,
|
||||||
data, 0, data.length, parentDirectory);
|
data, 0, data.length, parentDirectory);
|
||||||
manifestChunk.setIsChunkManifest(true);
|
manifestChunk.setIsChunkManifest(true);
|
||||||
|
|||||||
@@ -4,25 +4,21 @@ import com.google.common.base.Strings;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class FilerClient {
|
public class FilerClient extends FilerGrpcClient {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(FilerClient.class);
|
private static final Logger LOG = LoggerFactory.getLogger(FilerClient.class);
|
||||||
|
|
||||||
private final FilerGrpcClient filerGrpcClient;
|
|
||||||
|
|
||||||
public FilerClient(String host, int grpcPort) {
|
public FilerClient(String host, int grpcPort) {
|
||||||
filerGrpcClient = new FilerGrpcClient(host, grpcPort);
|
super(host, grpcPort-10000, grpcPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FilerClient(FilerGrpcClient filerGrpcClient) {
|
public FilerClient(String host, int port, int grpcPort) {
|
||||||
this.filerGrpcClient = filerGrpcClient;
|
super(host, port, grpcPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String toFileId(FilerProto.FileId fid) {
|
public static String toFileId(FilerProto.FileId fid) {
|
||||||
@@ -66,24 +62,39 @@ public class FilerClient {
|
|||||||
|
|
||||||
public static FilerProto.Entry afterEntryDeserialization(FilerProto.Entry entry) {
|
public static FilerProto.Entry afterEntryDeserialization(FilerProto.Entry entry) {
|
||||||
if (entry.getChunksList().size() <= 0) {
|
if (entry.getChunksList().size() <= 0) {
|
||||||
return entry;
|
if (entry.getContent().isEmpty()) {
|
||||||
}
|
return entry;
|
||||||
String fileId = entry.getChunks(0).getFileId();
|
} else {
|
||||||
if (fileId != null && fileId.length() != 0) {
|
if (entry.getAttributes().getFileSize() <= 0) {
|
||||||
return entry;
|
FilerProto.Entry.Builder entryBuilder = entry.toBuilder();
|
||||||
}
|
FilerProto.FuseAttributes.Builder attrBuilder = entry.getAttributes().toBuilder();
|
||||||
FilerProto.Entry.Builder entryBuilder = entry.toBuilder();
|
attrBuilder.setFileSize(entry.getContent().size());
|
||||||
entryBuilder.clearChunks();
|
entryBuilder.setAttributes(attrBuilder);
|
||||||
for (FilerProto.FileChunk chunk : entry.getChunksList()) {
|
return entryBuilder.build();
|
||||||
FilerProto.FileChunk.Builder chunkBuilder = chunk.toBuilder();
|
}
|
||||||
chunkBuilder.setFileId(toFileId(chunk.getFid()));
|
|
||||||
String sourceFileId = toFileId(chunk.getSourceFid());
|
|
||||||
if (sourceFileId != null) {
|
|
||||||
chunkBuilder.setSourceFileId(sourceFileId);
|
|
||||||
}
|
}
|
||||||
entryBuilder.addChunks(chunkBuilder);
|
return entry;
|
||||||
|
} else {
|
||||||
|
FilerProto.Entry.Builder entryBuilder = entry.toBuilder();
|
||||||
|
entryBuilder.clearChunks();
|
||||||
|
long fileSize = 0;
|
||||||
|
for (FilerProto.FileChunk chunk : entry.getChunksList()) {
|
||||||
|
fileSize = Math.max(fileSize, chunk.getOffset()+chunk.getSize());
|
||||||
|
FilerProto.FileChunk.Builder chunkBuilder = chunk.toBuilder();
|
||||||
|
chunkBuilder.setFileId(toFileId(chunk.getFid()));
|
||||||
|
String sourceFileId = toFileId(chunk.getSourceFid());
|
||||||
|
if (sourceFileId != null) {
|
||||||
|
chunkBuilder.setSourceFileId(sourceFileId);
|
||||||
|
}
|
||||||
|
entryBuilder.addChunks(chunkBuilder);
|
||||||
|
}
|
||||||
|
if (entry.getAttributes().getFileSize() <= 0) {
|
||||||
|
FilerProto.FuseAttributes.Builder attrBuilder = entry.getAttributes().toBuilder();
|
||||||
|
attrBuilder.setFileSize(fileSize);
|
||||||
|
entryBuilder.setAttributes(attrBuilder);
|
||||||
|
}
|
||||||
|
return entryBuilder.build();
|
||||||
}
|
}
|
||||||
return entryBuilder.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean mkdirs(String path, int mode) {
|
public boolean mkdirs(String path, int mode) {
|
||||||
@@ -100,9 +111,9 @@ public class FilerClient {
|
|||||||
if ("/".equals(path)) {
|
if ("/".equals(path)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Path pathObject = Paths.get(path);
|
String[] dirAndName = SeaweedUtil.toDirAndName(path);
|
||||||
String parent = pathObject.getParent().toString();
|
String parent = dirAndName[0];
|
||||||
String name = pathObject.getFileName().toString();
|
String name = dirAndName[1];
|
||||||
|
|
||||||
mkdirs(parent, mode, uid, gid, userName, groupNames);
|
mkdirs(parent, mode, uid, gid, userName, groupNames);
|
||||||
|
|
||||||
@@ -121,23 +132,32 @@ public class FilerClient {
|
|||||||
|
|
||||||
public boolean mv(String oldPath, String newPath) {
|
public boolean mv(String oldPath, String newPath) {
|
||||||
|
|
||||||
Path oldPathObject = Paths.get(oldPath);
|
String[] oldDirAndName = SeaweedUtil.toDirAndName(oldPath);
|
||||||
String oldParent = oldPathObject.getParent().toString();
|
String oldParent = oldDirAndName[0];
|
||||||
String oldName = oldPathObject.getFileName().toString();
|
String oldName = oldDirAndName[1];
|
||||||
|
|
||||||
Path newPathObject = Paths.get(newPath);
|
String[] newDirAndName = SeaweedUtil.toDirAndName(newPath);
|
||||||
String newParent = newPathObject.getParent().toString();
|
String newParent = newDirAndName[0];
|
||||||
String newName = newPathObject.getFileName().toString();
|
String newName = newDirAndName[1];
|
||||||
|
|
||||||
return atomicRenameEntry(oldParent, oldName, newParent, newName);
|
return atomicRenameEntry(oldParent, oldName, newParent, newName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean exists(String path){
|
||||||
|
|
||||||
|
String[] dirAndName = SeaweedUtil.toDirAndName(path);
|
||||||
|
String parent = dirAndName[0];
|
||||||
|
String entryName = dirAndName[1];
|
||||||
|
|
||||||
|
return lookupEntry(parent, entryName) != null;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean rm(String path, boolean isRecursive, boolean ignoreRecusiveError) {
|
public boolean rm(String path, boolean isRecursive, boolean ignoreRecusiveError) {
|
||||||
|
|
||||||
Path pathObject = Paths.get(path);
|
String[] dirAndName = SeaweedUtil.toDirAndName(path);
|
||||||
String parent = pathObject.getParent().toString();
|
String parent = dirAndName[0];
|
||||||
String name = pathObject.getFileName().toString();
|
String name = dirAndName[1];
|
||||||
|
|
||||||
return deleteEntry(
|
return deleteEntry(
|
||||||
parent,
|
parent,
|
||||||
@@ -148,31 +168,43 @@ public class FilerClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean touch(String path, int mode) {
|
public boolean touch(String path, int mode) {
|
||||||
|
|
||||||
String currentUser = System.getProperty("user.name");
|
String currentUser = System.getProperty("user.name");
|
||||||
return touch(path, mode, 0, 0, currentUser, new String[]{});
|
|
||||||
|
long now = System.currentTimeMillis() / 1000L;
|
||||||
|
return touch(path, now, mode, 0, 0, currentUser, new String[]{});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean touch(String path, int mode, int uid, int gid, String userName, String[] groupNames) {
|
public boolean touch(String path, long modifiedTimeSecond, int mode, int uid, int gid, String userName, String[] groupNames) {
|
||||||
|
|
||||||
Path pathObject = Paths.get(path);
|
String[] dirAndName = SeaweedUtil.toDirAndName(path);
|
||||||
String parent = pathObject.getParent().toString();
|
String parent = dirAndName[0];
|
||||||
String name = pathObject.getFileName().toString();
|
String name = dirAndName[1];
|
||||||
|
|
||||||
FilerProto.Entry entry = lookupEntry(parent, name);
|
FilerProto.Entry entry = lookupEntry(parent, name);
|
||||||
if (entry == null) {
|
if (entry == null) {
|
||||||
return createEntry(
|
return createEntry(
|
||||||
parent,
|
parent,
|
||||||
newFileEntry(name, mode, uid, gid, userName, groupNames).build()
|
newFileEntry(name, modifiedTimeSecond, mode, uid, gid, userName, groupNames).build()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
long now = System.currentTimeMillis() / 1000L;
|
FilerProto.FuseAttributes.Builder attr = entry.getAttributes().toBuilder();
|
||||||
FilerProto.FuseAttributes.Builder attr = entry.getAttributes().toBuilder()
|
if (modifiedTimeSecond>0) {
|
||||||
.setMtime(now)
|
attr.setMtime(modifiedTimeSecond);
|
||||||
.setUid(uid)
|
}
|
||||||
.setGid(gid)
|
if (uid>0) {
|
||||||
.setUserName(userName)
|
attr.setUid(uid);
|
||||||
.clearGroupName()
|
}
|
||||||
.addAllGroupName(Arrays.asList(groupNames));
|
if (gid>0) {
|
||||||
|
attr.setGid(gid);
|
||||||
|
}
|
||||||
|
if (userName!=null) {
|
||||||
|
attr.setUserName(userName);
|
||||||
|
}
|
||||||
|
if (groupNames!=null) {
|
||||||
|
attr.clearGroupName().addAllGroupName(Arrays.asList(groupNames));
|
||||||
|
}
|
||||||
return updateEntry(parent, entry.toBuilder().setAttributes(attr).build());
|
return updateEntry(parent, entry.toBuilder().setAttributes(attr).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,17 +227,15 @@ public class FilerClient {
|
|||||||
.addAllGroupName(Arrays.asList(groupNames)));
|
.addAllGroupName(Arrays.asList(groupNames)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public FilerProto.Entry.Builder newFileEntry(String name, int mode,
|
public FilerProto.Entry.Builder newFileEntry(String name, long modifiedTimeSecond, int mode,
|
||||||
int uid, int gid, String userName, String[] groupNames) {
|
int uid, int gid, String userName, String[] groupNames) {
|
||||||
|
|
||||||
long now = System.currentTimeMillis() / 1000L;
|
|
||||||
|
|
||||||
return FilerProto.Entry.newBuilder()
|
return FilerProto.Entry.newBuilder()
|
||||||
.setName(name)
|
.setName(name)
|
||||||
.setIsDirectory(false)
|
.setIsDirectory(false)
|
||||||
.setAttributes(FilerProto.FuseAttributes.newBuilder()
|
.setAttributes(FilerProto.FuseAttributes.newBuilder()
|
||||||
.setMtime(now)
|
.setMtime(modifiedTimeSecond)
|
||||||
.setCrtime(now)
|
.setCrtime(modifiedTimeSecond)
|
||||||
.setUid(uid)
|
.setUid(uid)
|
||||||
.setGid(gid)
|
.setGid(gid)
|
||||||
.setFileMode(mode)
|
.setFileMode(mode)
|
||||||
@@ -236,7 +266,7 @@ public class FilerClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<FilerProto.Entry> listEntries(String path, String entryPrefix, String lastEntryName, int limit, boolean includeLastEntry) {
|
public List<FilerProto.Entry> listEntries(String path, String entryPrefix, String lastEntryName, int limit, boolean includeLastEntry) {
|
||||||
Iterator<FilerProto.ListEntriesResponse> iter = filerGrpcClient.getBlockingStub().listEntries(FilerProto.ListEntriesRequest.newBuilder()
|
Iterator<FilerProto.ListEntriesResponse> iter = this.getBlockingStub().listEntries(FilerProto.ListEntriesRequest.newBuilder()
|
||||||
.setDirectory(path)
|
.setDirectory(path)
|
||||||
.setPrefix(entryPrefix)
|
.setPrefix(entryPrefix)
|
||||||
.setStartFromFileName(lastEntryName)
|
.setStartFromFileName(lastEntryName)
|
||||||
@@ -253,7 +283,7 @@ public class FilerClient {
|
|||||||
|
|
||||||
public FilerProto.Entry lookupEntry(String directory, String entryName) {
|
public FilerProto.Entry lookupEntry(String directory, String entryName) {
|
||||||
try {
|
try {
|
||||||
FilerProto.Entry entry = filerGrpcClient.getBlockingStub().lookupDirectoryEntry(
|
FilerProto.Entry entry = this.getBlockingStub().lookupDirectoryEntry(
|
||||||
FilerProto.LookupDirectoryEntryRequest.newBuilder()
|
FilerProto.LookupDirectoryEntryRequest.newBuilder()
|
||||||
.setDirectory(directory)
|
.setDirectory(directory)
|
||||||
.setName(entryName)
|
.setName(entryName)
|
||||||
@@ -274,7 +304,7 @@ public class FilerClient {
|
|||||||
public boolean createEntry(String parent, FilerProto.Entry entry) {
|
public boolean createEntry(String parent, FilerProto.Entry entry) {
|
||||||
try {
|
try {
|
||||||
FilerProto.CreateEntryResponse createEntryResponse =
|
FilerProto.CreateEntryResponse createEntryResponse =
|
||||||
filerGrpcClient.getBlockingStub().createEntry(FilerProto.CreateEntryRequest.newBuilder()
|
this.getBlockingStub().createEntry(FilerProto.CreateEntryRequest.newBuilder()
|
||||||
.setDirectory(parent)
|
.setDirectory(parent)
|
||||||
.setEntry(entry)
|
.setEntry(entry)
|
||||||
.build());
|
.build());
|
||||||
@@ -291,7 +321,7 @@ public class FilerClient {
|
|||||||
|
|
||||||
public boolean updateEntry(String parent, FilerProto.Entry entry) {
|
public boolean updateEntry(String parent, FilerProto.Entry entry) {
|
||||||
try {
|
try {
|
||||||
filerGrpcClient.getBlockingStub().updateEntry(FilerProto.UpdateEntryRequest.newBuilder()
|
this.getBlockingStub().updateEntry(FilerProto.UpdateEntryRequest.newBuilder()
|
||||||
.setDirectory(parent)
|
.setDirectory(parent)
|
||||||
.setEntry(entry)
|
.setEntry(entry)
|
||||||
.build());
|
.build());
|
||||||
@@ -304,7 +334,7 @@ public class FilerClient {
|
|||||||
|
|
||||||
public boolean deleteEntry(String parent, String entryName, boolean isDeleteFileChunk, boolean isRecursive, boolean ignoreRecusiveError) {
|
public boolean deleteEntry(String parent, String entryName, boolean isDeleteFileChunk, boolean isRecursive, boolean ignoreRecusiveError) {
|
||||||
try {
|
try {
|
||||||
filerGrpcClient.getBlockingStub().deleteEntry(FilerProto.DeleteEntryRequest.newBuilder()
|
this.getBlockingStub().deleteEntry(FilerProto.DeleteEntryRequest.newBuilder()
|
||||||
.setDirectory(parent)
|
.setDirectory(parent)
|
||||||
.setName(entryName)
|
.setName(entryName)
|
||||||
.setIsDeleteData(isDeleteFileChunk)
|
.setIsDeleteData(isDeleteFileChunk)
|
||||||
@@ -320,7 +350,7 @@ public class FilerClient {
|
|||||||
|
|
||||||
public boolean atomicRenameEntry(String oldParent, String oldName, String newParent, String newName) {
|
public boolean atomicRenameEntry(String oldParent, String oldName, String newParent, String newName) {
|
||||||
try {
|
try {
|
||||||
filerGrpcClient.getBlockingStub().atomicRenameEntry(FilerProto.AtomicRenameEntryRequest.newBuilder()
|
this.getBlockingStub().atomicRenameEntry(FilerProto.AtomicRenameEntryRequest.newBuilder()
|
||||||
.setOldDirectory(oldParent)
|
.setOldDirectory(oldParent)
|
||||||
.setOldName(oldName)
|
.setOldName(oldName)
|
||||||
.setNewDirectory(newParent)
|
.setNewDirectory(newParent)
|
||||||
@@ -334,7 +364,7 @@ public class FilerClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Iterator<FilerProto.SubscribeMetadataResponse> watch(String prefix, String clientName, long sinceNs) {
|
public Iterator<FilerProto.SubscribeMetadataResponse> watch(String prefix, String clientName, long sinceNs) {
|
||||||
return filerGrpcClient.getBlockingStub().subscribeMetadata(FilerProto.SubscribeMetadataRequest.newBuilder()
|
return this.getBlockingStub().subscribeMetadata(FilerProto.SubscribeMetadataRequest.newBuilder()
|
||||||
.setPathPrefix(prefix)
|
.setPathPrefix(prefix)
|
||||||
.setClientName(clientName)
|
.setClientName(clientName)
|
||||||
.setSinceNs(sinceNs)
|
.setSinceNs(sinceNs)
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class FilerGrpcClient {
|
public class FilerGrpcClient {
|
||||||
@@ -26,6 +26,9 @@ public class FilerGrpcClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final int VOLUME_SERVER_ACCESS_DIRECT = 0;
|
||||||
|
public final int VOLUME_SERVER_ACCESS_PUBLIC_URL = 1;
|
||||||
|
public final int VOLUME_SERVER_ACCESS_FILER_PROXY = 2;
|
||||||
public final Map<String, FilerProto.Locations> vidLocations = new HashMap<>();
|
public final Map<String, FilerProto.Locations> vidLocations = new HashMap<>();
|
||||||
private final ManagedChannel channel;
|
private final ManagedChannel channel;
|
||||||
private final SeaweedFilerGrpc.SeaweedFilerBlockingStub blockingStub;
|
private final SeaweedFilerGrpc.SeaweedFilerBlockingStub blockingStub;
|
||||||
@@ -34,12 +37,14 @@ public class FilerGrpcClient {
|
|||||||
private boolean cipher = false;
|
private boolean cipher = false;
|
||||||
private String collection = "";
|
private String collection = "";
|
||||||
private String replication = "";
|
private String replication = "";
|
||||||
|
private int volumeServerAccess = VOLUME_SERVER_ACCESS_DIRECT;
|
||||||
|
private String filerAddress;
|
||||||
|
|
||||||
public FilerGrpcClient(String host, int grpcPort) {
|
public FilerGrpcClient(String host, int port, int grpcPort) {
|
||||||
this(host, grpcPort, sslContext);
|
this(host, port, grpcPort, sslContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FilerGrpcClient(String host, int grpcPort, SslContext sslContext) {
|
public FilerGrpcClient(String host, int port, int grpcPort, SslContext sslContext) {
|
||||||
|
|
||||||
this(sslContext == null ?
|
this(sslContext == null ?
|
||||||
ManagedChannelBuilder.forAddress(host, grpcPort).usePlaintext()
|
ManagedChannelBuilder.forAddress(host, grpcPort).usePlaintext()
|
||||||
@@ -49,6 +54,8 @@ public class FilerGrpcClient {
|
|||||||
.negotiationType(NegotiationType.TLS)
|
.negotiationType(NegotiationType.TLS)
|
||||||
.sslContext(sslContext));
|
.sslContext(sslContext));
|
||||||
|
|
||||||
|
filerAddress = SeaweedUtil.joinHostPort(host, port);
|
||||||
|
|
||||||
FilerProto.GetFilerConfigurationResponse filerConfigurationResponse =
|
FilerProto.GetFilerConfigurationResponse filerConfigurationResponse =
|
||||||
this.getBlockingStub().getFilerConfiguration(
|
this.getBlockingStub().getFilerConfiguration(
|
||||||
FilerProto.GetFilerConfigurationRequest.newBuilder().build());
|
FilerProto.GetFilerConfigurationRequest.newBuilder().build());
|
||||||
@@ -58,7 +65,7 @@ public class FilerGrpcClient {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public FilerGrpcClient(ManagedChannelBuilder<?> channelBuilder) {
|
private FilerGrpcClient(ManagedChannelBuilder<?> channelBuilder) {
|
||||||
channel = channelBuilder.build();
|
channel = channelBuilder.build();
|
||||||
blockingStub = SeaweedFilerGrpc.newBlockingStub(channel);
|
blockingStub = SeaweedFilerGrpc.newBlockingStub(channel);
|
||||||
asyncStub = SeaweedFilerGrpc.newStub(channel);
|
asyncStub = SeaweedFilerGrpc.newStub(channel);
|
||||||
@@ -93,4 +100,39 @@ public class FilerGrpcClient {
|
|||||||
return futureStub;
|
return futureStub;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAccessVolumeServerDirectly() {
|
||||||
|
this.volumeServerAccess = VOLUME_SERVER_ACCESS_DIRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAccessVolumeServerDirectly() {
|
||||||
|
return this.volumeServerAccess == VOLUME_SERVER_ACCESS_DIRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccessVolumeServerByPublicUrl() {
|
||||||
|
this.volumeServerAccess = VOLUME_SERVER_ACCESS_PUBLIC_URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAccessVolumeServerByPublicUrl() {
|
||||||
|
return this.volumeServerAccess == VOLUME_SERVER_ACCESS_PUBLIC_URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccessVolumeServerByFilerProxy() {
|
||||||
|
this.volumeServerAccess = VOLUME_SERVER_ACCESS_FILER_PROXY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAccessVolumeServerByFilerProxy() {
|
||||||
|
return this.volumeServerAccess == VOLUME_SERVER_ACCESS_FILER_PROXY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChunkUrl(String chunkId, String url, String publicUrl) {
|
||||||
|
switch (this.volumeServerAccess) {
|
||||||
|
case VOLUME_SERVER_ACCESS_PUBLIC_URL:
|
||||||
|
return String.format("http://%s/%s", publicUrl, chunkId);
|
||||||
|
case VOLUME_SERVER_ACCESS_FILER_PROXY:
|
||||||
|
return String.format("http://%s/?proxyChunkId=%s", this.filerAddress, chunkId);
|
||||||
|
default:
|
||||||
|
return String.format("http://%s/%s", url, chunkId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package seaweedfs.client;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class RemoteUtil {
|
||||||
|
public static boolean isInRemoteOnly(FilerProto.Entry entry) {
|
||||||
|
if (entry.getChunksList() == null || entry.getChunksList().isEmpty()) {
|
||||||
|
return entry.getRemoteEntry() != null && entry.getRemoteEntry().getRemoteSize() > 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FilerProto.Entry downloadRemoteEntry(FilerClient filerClient, String fullpath, FilerProto.Entry entry) throws IOException {
|
||||||
|
String dir = SeaweedOutputStream.getParentDirectory(fullpath);
|
||||||
|
String name = SeaweedOutputStream.getFileName(fullpath);
|
||||||
|
|
||||||
|
final FilerProto.DownloadToLocalResponse downloadToLocalResponse = filerClient.getBlockingStub()
|
||||||
|
.downloadToLocal(FilerProto.DownloadToLocalRequest.newBuilder()
|
||||||
|
.setDirectory(dir).setName(name).build());
|
||||||
|
|
||||||
|
return downloadToLocalResponse.getEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@@ -16,26 +17,55 @@ public class SeaweedInputStream extends InputStream {
|
|||||||
private static final Logger LOG = LoggerFactory.getLogger(SeaweedInputStream.class);
|
private static final Logger LOG = LoggerFactory.getLogger(SeaweedInputStream.class);
|
||||||
private static final IOException EXCEPTION_STREAM_IS_CLOSED = new IOException("Stream is closed!");
|
private static final IOException EXCEPTION_STREAM_IS_CLOSED = new IOException("Stream is closed!");
|
||||||
|
|
||||||
private final FilerGrpcClient filerGrpcClient;
|
private final FilerClient filerClient;
|
||||||
private final String path;
|
private final String path;
|
||||||
private final FilerProto.Entry entry;
|
|
||||||
private final List<SeaweedRead.VisibleInterval> visibleIntervalList;
|
private final List<SeaweedRead.VisibleInterval> visibleIntervalList;
|
||||||
private final long contentLength;
|
private final long contentLength;
|
||||||
|
private FilerProto.Entry entry;
|
||||||
|
|
||||||
private long position = 0; // cursor of the file
|
private long position = 0; // cursor of the file
|
||||||
|
|
||||||
private boolean closed = false;
|
private boolean closed = false;
|
||||||
|
|
||||||
public SeaweedInputStream(
|
public SeaweedInputStream(
|
||||||
final FilerGrpcClient filerGrpcClient,
|
final FilerClient filerClient,
|
||||||
final String path,
|
final String fullpath) throws IOException {
|
||||||
final FilerProto.Entry entry) throws IOException {
|
this.path = fullpath;
|
||||||
this.filerGrpcClient = filerGrpcClient;
|
this.filerClient = filerClient;
|
||||||
this.path = path;
|
this.entry = filerClient.lookupEntry(
|
||||||
this.entry = entry;
|
SeaweedOutputStream.getParentDirectory(fullpath),
|
||||||
|
SeaweedOutputStream.getFileName(fullpath));
|
||||||
|
if (entry == null) {
|
||||||
|
throw new FileNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RemoteUtil.isInRemoteOnly(entry)) {
|
||||||
|
entry = RemoteUtil.downloadRemoteEntry(filerClient, fullpath, entry);
|
||||||
|
}
|
||||||
|
|
||||||
this.contentLength = SeaweedRead.fileSize(entry);
|
this.contentLength = SeaweedRead.fileSize(entry);
|
||||||
|
|
||||||
this.visibleIntervalList = SeaweedRead.nonOverlappingVisibleIntervals(filerGrpcClient, entry.getChunksList());
|
this.visibleIntervalList = SeaweedRead.nonOverlappingVisibleIntervals(filerClient, entry.getChunksList());
|
||||||
|
|
||||||
|
LOG.debug("new path:{} entry:{} visibleIntervalList:{}", path, entry, visibleIntervalList);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public SeaweedInputStream(
|
||||||
|
final FilerClient filerClient,
|
||||||
|
final String path,
|
||||||
|
final FilerProto.Entry entry) throws IOException {
|
||||||
|
this.filerClient = filerClient;
|
||||||
|
this.path = path;
|
||||||
|
this.entry = entry;
|
||||||
|
|
||||||
|
if (RemoteUtil.isInRemoteOnly(entry)) {
|
||||||
|
this.entry = RemoteUtil.downloadRemoteEntry(filerClient, path, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.contentLength = SeaweedRead.fileSize(entry);
|
||||||
|
|
||||||
|
this.visibleIntervalList = SeaweedRead.nonOverlappingVisibleIntervals(filerClient, entry.getChunksList());
|
||||||
|
|
||||||
LOG.debug("new path:{} entry:{} visibleIntervalList:{}", path, entry, visibleIntervalList);
|
LOG.debug("new path:{} entry:{} visibleIntervalList:{}", path, entry, visibleIntervalList);
|
||||||
|
|
||||||
@@ -90,10 +120,10 @@ public class SeaweedInputStream extends InputStream {
|
|||||||
long bytesRead = 0;
|
long bytesRead = 0;
|
||||||
int len = buf.remaining();
|
int len = buf.remaining();
|
||||||
int start = (int) this.position;
|
int start = (int) this.position;
|
||||||
if (start+len <= entry.getContent().size()) {
|
if (start + len <= entry.getContent().size()) {
|
||||||
entry.getContent().substring(start, start+len).copyTo(buf);
|
entry.getContent().substring(start, start + len).copyTo(buf);
|
||||||
} else {
|
} else {
|
||||||
bytesRead = SeaweedRead.read(this.filerGrpcClient, this.visibleIntervalList, this.position, buf, SeaweedRead.fileSize(entry));
|
bytesRead = SeaweedRead.read(this.filerClient, this.visibleIntervalList, this.position, buf, SeaweedRead.fileSize(entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytesRead > Integer.MAX_VALUE) {
|
if (bytesRead > Integer.MAX_VALUE) {
|
||||||
|
|||||||
@@ -8,22 +8,23 @@ import org.slf4j.LoggerFactory;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InterruptedIOException;
|
import java.io.InterruptedIOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.nio.Buffer;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
public class SeaweedOutputStream extends OutputStream {
|
public class SeaweedOutputStream extends OutputStream {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(SeaweedOutputStream.class);
|
private static final Logger LOG = LoggerFactory.getLogger(SeaweedOutputStream.class);
|
||||||
|
protected final boolean supportFlush = true;
|
||||||
private final FilerGrpcClient filerGrpcClient;
|
private final FilerClient filerClient;
|
||||||
private final String path;
|
private final String path;
|
||||||
private final int bufferSize;
|
private final int bufferSize;
|
||||||
private final int maxConcurrentRequestCount;
|
private final int maxConcurrentRequestCount;
|
||||||
private final ThreadPoolExecutor threadExecutor;
|
private final ThreadPoolExecutor threadExecutor;
|
||||||
private final ExecutorCompletionService<Void> completionService;
|
private final ExecutorCompletionService<Void> completionService;
|
||||||
private final FilerProto.Entry.Builder entry;
|
|
||||||
protected final boolean supportFlush = false; // true;
|
|
||||||
private final ConcurrentLinkedDeque<WriteOperation> writeOperations;
|
private final ConcurrentLinkedDeque<WriteOperation> writeOperations;
|
||||||
|
private final boolean shouldSaveMetadata = false;
|
||||||
|
private FilerProto.Entry.Builder entry;
|
||||||
private long position;
|
private long position;
|
||||||
private boolean closed;
|
private boolean closed;
|
||||||
private volatile IOException lastError;
|
private volatile IOException lastError;
|
||||||
@@ -31,11 +32,19 @@ public class SeaweedOutputStream extends OutputStream {
|
|||||||
private long lastTotalAppendOffset = 0;
|
private long lastTotalAppendOffset = 0;
|
||||||
private ByteBuffer buffer;
|
private ByteBuffer buffer;
|
||||||
private long outputIndex;
|
private long outputIndex;
|
||||||
private String replication = "000";
|
private String replication = "";
|
||||||
|
|
||||||
public SeaweedOutputStream(FilerGrpcClient filerGrpcClient, final String path, FilerProto.Entry.Builder entry,
|
public SeaweedOutputStream(FilerClient filerClient, final String fullpath) {
|
||||||
|
this(filerClient, fullpath, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public SeaweedOutputStream(FilerClient filerClient, final String fullpath, final String replication) {
|
||||||
|
this(filerClient, fullpath, null, 0, 8 * 1024 * 1024, replication);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SeaweedOutputStream(FilerClient filerClient, final String path, FilerProto.Entry.Builder entry,
|
||||||
final long position, final int bufferSize, final String replication) {
|
final long position, final int bufferSize, final String replication) {
|
||||||
this.filerGrpcClient = filerGrpcClient;
|
this.filerClient = filerClient;
|
||||||
this.replication = replication;
|
this.replication = replication;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.position = position;
|
this.position = position;
|
||||||
@@ -58,20 +67,50 @@ public class SeaweedOutputStream extends OutputStream {
|
|||||||
this.completionService = new ExecutorCompletionService<>(this.threadExecutor);
|
this.completionService = new ExecutorCompletionService<>(this.threadExecutor);
|
||||||
|
|
||||||
this.entry = entry;
|
this.entry = entry;
|
||||||
|
if (this.entry == null) {
|
||||||
|
long now = System.currentTimeMillis() / 1000L;
|
||||||
|
|
||||||
|
this.entry = FilerProto.Entry.newBuilder()
|
||||||
|
.setName(getFileName(path))
|
||||||
|
.setIsDirectory(false)
|
||||||
|
.setAttributes(FilerProto.FuseAttributes.newBuilder()
|
||||||
|
.setFileMode(0755)
|
||||||
|
.setReplication(replication)
|
||||||
|
.setCrtime(now)
|
||||||
|
.setMtime(now)
|
||||||
|
.clearGroupName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getParentDirectory(String path) {
|
public static String getParentDirectory(String path) {
|
||||||
|
int protoIndex = path.indexOf("://");
|
||||||
|
if (protoIndex >= 0) {
|
||||||
|
int pathStart = path.indexOf("/", protoIndex+3);
|
||||||
|
path = path.substring(pathStart);
|
||||||
|
}
|
||||||
if (path.equals("/")) {
|
if (path.equals("/")) {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
int lastSlashIndex = path.lastIndexOf("/");
|
int lastSlashIndex = path.lastIndexOf("/");
|
||||||
|
if (lastSlashIndex == 0) {
|
||||||
|
return "/";
|
||||||
|
}
|
||||||
return path.substring(0, lastSlashIndex);
|
return path.substring(0, lastSlashIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getFileName(String path) {
|
||||||
|
if (path.indexOf("/") < 0) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
int lastSlashIndex = path.lastIndexOf("/");
|
||||||
|
return path.substring(lastSlashIndex + 1);
|
||||||
|
}
|
||||||
|
|
||||||
private synchronized void flushWrittenBytesToServiceInternal(final long offset) throws IOException {
|
private synchronized void flushWrittenBytesToServiceInternal(final long offset) throws IOException {
|
||||||
try {
|
try {
|
||||||
SeaweedWrite.writeMeta(filerGrpcClient, getParentDirectory(path), entry);
|
SeaweedWrite.writeMeta(filerClient, getParentDirectory(path), entry);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new IOException(ex);
|
throw new IOException(ex);
|
||||||
}
|
}
|
||||||
@@ -163,6 +202,7 @@ public class SeaweedOutputStream extends OutputStream {
|
|||||||
threadExecutor.shutdownNow();
|
threadExecutor.shutdownNow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void writeCurrentBufferToService() throws IOException {
|
private synchronized void writeCurrentBufferToService() throws IOException {
|
||||||
@@ -178,7 +218,7 @@ public class SeaweedOutputStream extends OutputStream {
|
|||||||
|
|
||||||
private synchronized int submitWriteBufferToService(final ByteBuffer bufferToWrite, final long writePosition) throws IOException {
|
private synchronized int submitWriteBufferToService(final ByteBuffer bufferToWrite, final long writePosition) throws IOException {
|
||||||
|
|
||||||
bufferToWrite.flip();
|
((Buffer)bufferToWrite).flip();
|
||||||
int bytesLength = bufferToWrite.limit() - bufferToWrite.position();
|
int bytesLength = bufferToWrite.limit() - bufferToWrite.position();
|
||||||
|
|
||||||
if (threadExecutor.getQueue().size() >= maxConcurrentRequestCount) {
|
if (threadExecutor.getQueue().size() >= maxConcurrentRequestCount) {
|
||||||
@@ -186,7 +226,7 @@ public class SeaweedOutputStream extends OutputStream {
|
|||||||
}
|
}
|
||||||
final Future<Void> job = completionService.submit(() -> {
|
final Future<Void> job = completionService.submit(() -> {
|
||||||
// System.out.println(path + " is going to save [" + (writePosition) + "," + ((writePosition) + bytesLength) + ")");
|
// System.out.println(path + " is going to save [" + (writePosition) + "," + ((writePosition) + bytesLength) + ")");
|
||||||
SeaweedWrite.writeData(entry, replication, filerGrpcClient, writePosition, bufferToWrite.array(), bufferToWrite.position(), bufferToWrite.limit(), path);
|
SeaweedWrite.writeData(entry, replication, filerClient, writePosition, bufferToWrite.array(), bufferToWrite.position(), bufferToWrite.limit(), path);
|
||||||
// System.out.println(path + " saved [" + (writePosition) + "," + ((writePosition) + bytesLength) + ")");
|
// System.out.println(path + " saved [" + (writePosition) + "," + ((writePosition) + bytesLength) + ")");
|
||||||
ByteBufferPool.release(bufferToWrite);
|
ByteBufferPool.release(bufferToWrite);
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public class SeaweedRead {
|
|||||||
static VolumeIdCache volumeIdCache = new VolumeIdCache(4 * 1024);
|
static VolumeIdCache volumeIdCache = new VolumeIdCache(4 * 1024);
|
||||||
|
|
||||||
// returns bytesRead
|
// returns bytesRead
|
||||||
public static long read(FilerGrpcClient filerGrpcClient, List<VisibleInterval> visibleIntervals,
|
public static long read(FilerClient filerClient, List<VisibleInterval> visibleIntervals,
|
||||||
final long position, final ByteBuffer buf, final long fileSize) throws IOException {
|
final long position, final ByteBuffer buf, final long fileSize) throws IOException {
|
||||||
|
|
||||||
List<ChunkView> chunkViews = viewFromVisibles(visibleIntervals, position, buf.remaining());
|
List<ChunkView> chunkViews = viewFromVisibles(visibleIntervals, position, buf.remaining());
|
||||||
@@ -42,7 +42,7 @@ public class SeaweedRead {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lookupRequest.getVolumeIdsCount() > 0) {
|
if (lookupRequest.getVolumeIdsCount() > 0) {
|
||||||
FilerProto.LookupVolumeResponse lookupResponse = filerGrpcClient
|
FilerProto.LookupVolumeResponse lookupResponse = filerClient
|
||||||
.getBlockingStub().lookupVolume(lookupRequest.build());
|
.getBlockingStub().lookupVolume(lookupRequest.build());
|
||||||
Map<String, FilerProto.Locations> vid2Locations = lookupResponse.getLocationsMapMap();
|
Map<String, FilerProto.Locations> vid2Locations = lookupResponse.getLocationsMapMap();
|
||||||
for (Map.Entry<String, FilerProto.Locations> entry : vid2Locations.entrySet()) {
|
for (Map.Entry<String, FilerProto.Locations> entry : vid2Locations.entrySet()) {
|
||||||
@@ -64,14 +64,15 @@ public class SeaweedRead {
|
|||||||
startOffset += gap;
|
startOffset += gap;
|
||||||
}
|
}
|
||||||
|
|
||||||
FilerProto.Locations locations = knownLocations.get(parseVolumeId(chunkView.fileId));
|
String volumeId = parseVolumeId(chunkView.fileId);
|
||||||
|
FilerProto.Locations locations = knownLocations.get(volumeId);
|
||||||
if (locations == null || locations.getLocationsCount() == 0) {
|
if (locations == null || locations.getLocationsCount() == 0) {
|
||||||
LOG.error("failed to locate {}", chunkView.fileId);
|
LOG.error("failed to locate {}", chunkView.fileId);
|
||||||
// log here!
|
volumeIdCache.clearLocations(volumeId);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int len = readChunkView(startOffset, buf, chunkView, locations);
|
int len = readChunkView(filerClient, startOffset, buf, chunkView, locations);
|
||||||
|
|
||||||
LOG.debug("read [{},{}) {} size {}", startOffset, startOffset + len, chunkView.fileId, chunkView.size);
|
LOG.debug("read [{},{}) {} size {}", startOffset, startOffset + len, chunkView.fileId, chunkView.size);
|
||||||
|
|
||||||
@@ -93,12 +94,12 @@ public class SeaweedRead {
|
|||||||
return readCount;
|
return readCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int readChunkView(long startOffset, ByteBuffer buf, ChunkView chunkView, FilerProto.Locations locations) throws IOException {
|
private static int readChunkView(FilerClient filerClient, long startOffset, ByteBuffer buf, ChunkView chunkView, FilerProto.Locations locations) throws IOException {
|
||||||
|
|
||||||
byte[] chunkData = chunkCache.getChunk(chunkView.fileId);
|
byte[] chunkData = chunkCache.getChunk(chunkView.fileId);
|
||||||
|
|
||||||
if (chunkData == null) {
|
if (chunkData == null) {
|
||||||
chunkData = doFetchFullChunkData(chunkView, locations);
|
chunkData = doFetchFullChunkData(filerClient, chunkView, locations);
|
||||||
chunkCache.setChunk(chunkView.fileId, chunkData);
|
chunkCache.setChunk(chunkView.fileId, chunkData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,13 +111,13 @@ public class SeaweedRead {
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] doFetchFullChunkData(ChunkView chunkView, FilerProto.Locations locations) throws IOException {
|
public static byte[] doFetchFullChunkData(FilerClient filerClient, ChunkView chunkView, FilerProto.Locations locations) throws IOException {
|
||||||
|
|
||||||
byte[] data = null;
|
byte[] data = null;
|
||||||
IOException lastException = null;
|
IOException lastException = null;
|
||||||
for (long waitTime = 1000L; waitTime < 10 * 1000; waitTime += waitTime / 2) {
|
for (long waitTime = 1000L; waitTime < 10 * 1000; waitTime += waitTime / 2) {
|
||||||
for (FilerProto.Location location : locations.getLocationsList()) {
|
for (FilerProto.Location location : locations.getLocationsList()) {
|
||||||
String url = String.format("http://%s/%s", location.getUrl(), chunkView.fileId);
|
String url = filerClient.getChunkUrl(chunkView.fileId, location.getUrl(), location.getPublicUrl());
|
||||||
try {
|
try {
|
||||||
data = doFetchOneFullChunkData(chunkView, url);
|
data = doFetchOneFullChunkData(chunkView, url);
|
||||||
lastException = null;
|
lastException = null;
|
||||||
@@ -145,7 +146,7 @@ public class SeaweedRead {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] doFetchOneFullChunkData(ChunkView chunkView, String url) throws IOException {
|
private static byte[] doFetchOneFullChunkData(ChunkView chunkView, String url) throws IOException {
|
||||||
|
|
||||||
HttpGet request = new HttpGet(url);
|
HttpGet request = new HttpGet(url);
|
||||||
|
|
||||||
@@ -221,9 +222,9 @@ public class SeaweedRead {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static List<VisibleInterval> nonOverlappingVisibleIntervals(
|
public static List<VisibleInterval> nonOverlappingVisibleIntervals(
|
||||||
final FilerGrpcClient filerGrpcClient, List<FilerProto.FileChunk> chunkList) throws IOException {
|
final FilerClient filerClient, List<FilerProto.FileChunk> chunkList) throws IOException {
|
||||||
|
|
||||||
chunkList = FileChunkManifest.resolveChunkManifest(filerGrpcClient, chunkList);
|
chunkList = FileChunkManifest.resolveChunkManifest(filerClient, chunkList);
|
||||||
|
|
||||||
FilerProto.FileChunk[] chunks = chunkList.toArray(new FilerProto.FileChunk[0]);
|
FilerProto.FileChunk[] chunks = chunkList.toArray(new FilerProto.FileChunk[0]);
|
||||||
Arrays.sort(chunks, new Comparator<FilerProto.FileChunk>() {
|
Arrays.sort(chunks, new Comparator<FilerProto.FileChunk>() {
|
||||||
|
|||||||
@@ -27,4 +27,30 @@ public class SeaweedUtil {
|
|||||||
public static CloseableHttpClient getClosableHttpClient() {
|
public static CloseableHttpClient getClosableHttpClient() {
|
||||||
return httpClient;
|
return httpClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String[] toDirAndName(String fullpath) {
|
||||||
|
if (fullpath == null) {
|
||||||
|
return new String[]{"/", ""};
|
||||||
|
}
|
||||||
|
if (fullpath.endsWith("/")) {
|
||||||
|
fullpath = fullpath.substring(0, fullpath.length() - 1);
|
||||||
|
}
|
||||||
|
if (fullpath.length() == 0) {
|
||||||
|
return new String[]{"/", ""};
|
||||||
|
}
|
||||||
|
int sep = fullpath.lastIndexOf("/");
|
||||||
|
String parent = sep == 0 ? "/" : fullpath.substring(0, sep);
|
||||||
|
String name = fullpath.substring(sep + 1);
|
||||||
|
return new String[]{parent, name};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String joinHostPort(String host, int port) {
|
||||||
|
if (host.startsWith("[") && host.endsWith("]")) {
|
||||||
|
return host + ":" + port;
|
||||||
|
}
|
||||||
|
if (host.indexOf(':')>=0) {
|
||||||
|
return "[" + host + "]:" + port;
|
||||||
|
}
|
||||||
|
return host + ":" + port;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package seaweedfs.client;
|
package seaweedfs.client;
|
||||||
|
|
||||||
|
import com.google.common.base.Strings;
|
||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
import org.apache.http.client.methods.HttpPost;
|
import org.apache.http.client.methods.HttpPost;
|
||||||
@@ -23,41 +24,46 @@ public class SeaweedWrite {
|
|||||||
|
|
||||||
public static void writeData(FilerProto.Entry.Builder entry,
|
public static void writeData(FilerProto.Entry.Builder entry,
|
||||||
final String replication,
|
final String replication,
|
||||||
final FilerGrpcClient filerGrpcClient,
|
final FilerClient filerClient,
|
||||||
final long offset,
|
final long offset,
|
||||||
final byte[] bytes,
|
final byte[] bytes,
|
||||||
final long bytesOffset, final long bytesLength,
|
final long bytesOffset, final long bytesLength,
|
||||||
final String path) throws IOException {
|
final String path) throws IOException {
|
||||||
FilerProto.FileChunk.Builder chunkBuilder = writeChunk(
|
FilerProto.FileChunk.Builder chunkBuilder = writeChunk(
|
||||||
replication, filerGrpcClient, offset, bytes, bytesOffset, bytesLength, path);
|
replication, filerClient, offset, bytes, bytesOffset, bytesLength, path);
|
||||||
synchronized (entry) {
|
synchronized (entry) {
|
||||||
entry.addChunks(chunkBuilder);
|
entry.addChunks(chunkBuilder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FilerProto.FileChunk.Builder writeChunk(final String replication,
|
public static FilerProto.FileChunk.Builder writeChunk(final String replication,
|
||||||
final FilerGrpcClient filerGrpcClient,
|
final FilerClient filerClient,
|
||||||
final long offset,
|
final long offset,
|
||||||
final byte[] bytes,
|
final byte[] bytes,
|
||||||
final long bytesOffset,
|
final long bytesOffset,
|
||||||
final long bytesLength,
|
final long bytesLength,
|
||||||
final String path) throws IOException {
|
final String path) throws IOException {
|
||||||
FilerProto.AssignVolumeResponse response = filerGrpcClient.getBlockingStub().assignVolume(
|
FilerProto.AssignVolumeResponse response = filerClient.getBlockingStub().assignVolume(
|
||||||
FilerProto.AssignVolumeRequest.newBuilder()
|
FilerProto.AssignVolumeRequest.newBuilder()
|
||||||
.setCollection(filerGrpcClient.getCollection())
|
.setCollection(filerClient.getCollection())
|
||||||
.setReplication(replication == null ? filerGrpcClient.getReplication() : replication)
|
.setReplication(Strings.isNullOrEmpty(replication) ? filerClient.getReplication() : replication)
|
||||||
.setDataCenter("")
|
.setDataCenter("")
|
||||||
.setTtlSec(0)
|
.setTtlSec(0)
|
||||||
.setPath(path)
|
.setPath(path)
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
|
if (!Strings.isNullOrEmpty(response.getError())) {
|
||||||
|
throw new IOException(response.getError());
|
||||||
|
}
|
||||||
|
|
||||||
String fileId = response.getFileId();
|
String fileId = response.getFileId();
|
||||||
String url = response.getUrl();
|
|
||||||
String auth = response.getAuth();
|
String auth = response.getAuth();
|
||||||
String targetUrl = String.format("http://%s/%s", url, fileId);
|
|
||||||
|
String targetUrl = filerClient.getChunkUrl(fileId, response.getLocation().getUrl(), response.getLocation().getPublicUrl());
|
||||||
|
|
||||||
ByteString cipherKeyString = com.google.protobuf.ByteString.EMPTY;
|
ByteString cipherKeyString = com.google.protobuf.ByteString.EMPTY;
|
||||||
byte[] cipherKey = null;
|
byte[] cipherKey = null;
|
||||||
if (filerGrpcClient.isCipher()) {
|
if (filerClient.isCipher()) {
|
||||||
cipherKey = genCipherKey();
|
cipherKey = genCipherKey();
|
||||||
cipherKeyString = ByteString.copyFrom(cipherKey);
|
cipherKeyString = ByteString.copyFrom(cipherKey);
|
||||||
}
|
}
|
||||||
@@ -75,15 +81,15 @@ public class SeaweedWrite {
|
|||||||
.setCipherKey(cipherKeyString);
|
.setCipherKey(cipherKeyString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeMeta(final FilerGrpcClient filerGrpcClient,
|
public static void writeMeta(final FilerClient filerClient,
|
||||||
final String parentDirectory,
|
final String parentDirectory,
|
||||||
final FilerProto.Entry.Builder entry) throws IOException {
|
final FilerProto.Entry.Builder entry) throws IOException {
|
||||||
|
|
||||||
synchronized (entry) {
|
synchronized (entry) {
|
||||||
List<FilerProto.FileChunk> chunks = FileChunkManifest.maybeManifestize(filerGrpcClient, entry.getChunksList(), parentDirectory);
|
List<FilerProto.FileChunk> chunks = FileChunkManifest.maybeManifestize(filerClient, entry.getChunksList(), parentDirectory);
|
||||||
entry.clearChunks();
|
entry.clearChunks();
|
||||||
entry.addAllChunks(chunks);
|
entry.addAllChunks(chunks);
|
||||||
filerGrpcClient.getBlockingStub().createEntry(
|
filerClient.getBlockingStub().createEntry(
|
||||||
FilerProto.CreateEntryRequest.newBuilder()
|
FilerProto.CreateEntryRequest.newBuilder()
|
||||||
.setDirectory(parentDirectory)
|
.setDirectory(parentDirectory)
|
||||||
.setEntry(entry)
|
.setEntry(entry)
|
||||||
|
|||||||
@@ -26,6 +26,13 @@ public class VolumeIdCache {
|
|||||||
return this.cache.getIfPresent(volumeId);
|
return this.cache.getIfPresent(volumeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearLocations(String volumeId) {
|
||||||
|
if (this.cache == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.cache.invalidate(volumeId);
|
||||||
|
}
|
||||||
|
|
||||||
public void setLocations(String volumeId, FilerProto.Locations locations) {
|
public void setLocations(String volumeId, FilerProto.Locations locations) {
|
||||||
if (this.cache == null) {
|
if (this.cache == null) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ service SeaweedFiler {
|
|||||||
rpc KvPut (KvPutRequest) returns (KvPutResponse) {
|
rpc KvPut (KvPutRequest) returns (KvPutResponse) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpc DownloadToLocal (DownloadToLocalRequest) returns (DownloadToLocalResponse) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////
|
//////////////////////////////////////////////////
|
||||||
@@ -92,6 +94,13 @@ message ListEntriesResponse {
|
|||||||
Entry entry = 1;
|
Entry entry = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message RemoteEntry {
|
||||||
|
string storage_name = 1;
|
||||||
|
int64 last_local_sync_ts_ns = 2;
|
||||||
|
string remote_e_tag = 3;
|
||||||
|
int64 remote_mtime = 4;
|
||||||
|
int64 remote_size = 5;
|
||||||
|
}
|
||||||
message Entry {
|
message Entry {
|
||||||
string name = 1;
|
string name = 1;
|
||||||
bool is_directory = 2;
|
bool is_directory = 2;
|
||||||
@@ -101,6 +110,8 @@ message Entry {
|
|||||||
bytes hard_link_id = 7;
|
bytes hard_link_id = 7;
|
||||||
int32 hard_link_counter = 8; // only exists in hard link meta data
|
int32 hard_link_counter = 8; // only exists in hard link meta data
|
||||||
bytes content = 9; // if not empty, the file content
|
bytes content = 9; // if not empty, the file content
|
||||||
|
|
||||||
|
RemoteEntry remote_entry = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
message FullEntry {
|
message FullEntry {
|
||||||
@@ -156,6 +167,7 @@ message FuseAttributes {
|
|||||||
repeated string group_name = 12; // for hdfs
|
repeated string group_name = 12; // for hdfs
|
||||||
string symlink_target = 13;
|
string symlink_target = 13;
|
||||||
bytes md5 = 14;
|
bytes md5 = 14;
|
||||||
|
string disk_type = 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CreateEntryRequest {
|
message CreateEntryRequest {
|
||||||
@@ -207,6 +219,7 @@ message AtomicRenameEntryRequest {
|
|||||||
string old_name = 2;
|
string old_name = 2;
|
||||||
string new_directory = 3;
|
string new_directory = 3;
|
||||||
string new_name = 4;
|
string new_name = 4;
|
||||||
|
repeated int32 signatures = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AtomicRenameEntryResponse {
|
message AtomicRenameEntryResponse {
|
||||||
@@ -220,17 +233,17 @@ message AssignVolumeRequest {
|
|||||||
string data_center = 5;
|
string data_center = 5;
|
||||||
string path = 6;
|
string path = 6;
|
||||||
string rack = 7;
|
string rack = 7;
|
||||||
|
string disk_type = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AssignVolumeResponse {
|
message AssignVolumeResponse {
|
||||||
string file_id = 1;
|
string file_id = 1;
|
||||||
string url = 2;
|
|
||||||
string public_url = 3;
|
|
||||||
int32 count = 4;
|
int32 count = 4;
|
||||||
string auth = 5;
|
string auth = 5;
|
||||||
string collection = 6;
|
string collection = 6;
|
||||||
string replication = 7;
|
string replication = 7;
|
||||||
string error = 8;
|
string error = 8;
|
||||||
|
Location location = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
message LookupVolumeRequest {
|
message LookupVolumeRequest {
|
||||||
@@ -244,6 +257,7 @@ message Locations {
|
|||||||
message Location {
|
message Location {
|
||||||
string url = 1;
|
string url = 1;
|
||||||
string public_url = 2;
|
string public_url = 2;
|
||||||
|
uint32 grpc_port = 3;
|
||||||
}
|
}
|
||||||
message LookupVolumeResponse {
|
message LookupVolumeResponse {
|
||||||
map<string, Locations> locations_map = 1;
|
map<string, Locations> locations_map = 1;
|
||||||
@@ -270,11 +284,9 @@ message StatisticsRequest {
|
|||||||
string replication = 1;
|
string replication = 1;
|
||||||
string collection = 2;
|
string collection = 2;
|
||||||
string ttl = 3;
|
string ttl = 3;
|
||||||
|
string disk_type = 4;
|
||||||
}
|
}
|
||||||
message StatisticsResponse {
|
message StatisticsResponse {
|
||||||
string replication = 1;
|
|
||||||
string collection = 2;
|
|
||||||
string ttl = 3;
|
|
||||||
uint64 total_size = 4;
|
uint64 total_size = 4;
|
||||||
uint64 used_size = 5;
|
uint64 used_size = 5;
|
||||||
uint64 file_count = 6;
|
uint64 file_count = 6;
|
||||||
@@ -292,6 +304,8 @@ message GetFilerConfigurationResponse {
|
|||||||
int32 signature = 8;
|
int32 signature = 8;
|
||||||
string metrics_address = 9;
|
string metrics_address = 9;
|
||||||
int32 metrics_interval_sec = 10;
|
int32 metrics_interval_sec = 10;
|
||||||
|
string version = 11;
|
||||||
|
string cluster_id = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SubscribeMetadataRequest {
|
message SubscribeMetadataRequest {
|
||||||
@@ -299,6 +313,7 @@ message SubscribeMetadataRequest {
|
|||||||
string path_prefix = 2;
|
string path_prefix = 2;
|
||||||
int64 since_ns = 3;
|
int64 since_ns = 3;
|
||||||
int32 signature = 4;
|
int32 signature = 4;
|
||||||
|
repeated string path_prefixes = 6;
|
||||||
}
|
}
|
||||||
message SubscribeMetadataResponse {
|
message SubscribeMetadataResponse {
|
||||||
string directory = 1;
|
string directory = 1;
|
||||||
@@ -323,6 +338,7 @@ message KeepConnectedResponse {
|
|||||||
message LocateBrokerRequest {
|
message LocateBrokerRequest {
|
||||||
string resource = 1;
|
string resource = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message LocateBrokerResponse {
|
message LocateBrokerResponse {
|
||||||
bool found = 1;
|
bool found = 1;
|
||||||
// if found, send the exact address
|
// if found, send the exact address
|
||||||
@@ -334,7 +350,9 @@ message LocateBrokerResponse {
|
|||||||
repeated Resource resources = 2;
|
repeated Resource resources = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////
|
||||||
// Key-Value operations
|
// Key-Value operations
|
||||||
|
/////////////////////////
|
||||||
message KvGetRequest {
|
message KvGetRequest {
|
||||||
bytes key = 1;
|
bytes key = 1;
|
||||||
}
|
}
|
||||||
@@ -350,7 +368,9 @@ message KvPutResponse {
|
|||||||
string error = 1;
|
string error = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////
|
||||||
// path-based configurations
|
// path-based configurations
|
||||||
|
/////////////////////////
|
||||||
message FilerConf {
|
message FilerConf {
|
||||||
int32 version = 1;
|
int32 version = 1;
|
||||||
message PathConf {
|
message PathConf {
|
||||||
@@ -358,14 +378,21 @@ message FilerConf {
|
|||||||
string collection = 2;
|
string collection = 2;
|
||||||
string replication = 3;
|
string replication = 3;
|
||||||
string ttl = 4;
|
string ttl = 4;
|
||||||
enum DiskType {
|
string disk_type = 5;
|
||||||
NONE = 0;
|
|
||||||
HDD = 1;
|
|
||||||
SSD = 2;
|
|
||||||
}
|
|
||||||
DiskType disk_type = 5;
|
|
||||||
bool fsync = 6;
|
bool fsync = 6;
|
||||||
uint32 volume_growth_count = 7;
|
uint32 volume_growth_count = 7;
|
||||||
|
bool read_only = 8;
|
||||||
}
|
}
|
||||||
repeated PathConf locations = 2;
|
repeated PathConf locations = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////
|
||||||
|
// Remote Storage related
|
||||||
|
/////////////////////////
|
||||||
|
message DownloadToLocalRequest {
|
||||||
|
string directory = 1;
|
||||||
|
string name = 2;
|
||||||
|
}
|
||||||
|
message DownloadToLocalResponse {
|
||||||
|
Entry entry = 1;
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,8 +16,17 @@ public class SeaweedFilerTest {
|
|||||||
filerClient.mkdirs("/new_folder", 0755);
|
filerClient.mkdirs("/new_folder", 0755);
|
||||||
filerClient.touch("/new_folder/new_empty_file", 0755);
|
filerClient.touch("/new_folder/new_empty_file", 0755);
|
||||||
filerClient.touch("/new_folder/new_empty_file2", 0755);
|
filerClient.touch("/new_folder/new_empty_file2", 0755);
|
||||||
|
if(!filerClient.exists("/new_folder/new_empty_file")){
|
||||||
|
System.out.println("/new_folder/new_empty_file should exists");
|
||||||
|
}
|
||||||
|
|
||||||
filerClient.rm("/new_folder/new_empty_file", false, true);
|
filerClient.rm("/new_folder/new_empty_file", false, true);
|
||||||
filerClient.rm("/new_folder", true, true);
|
filerClient.rm("/new_folder", true, true);
|
||||||
|
if(filerClient.exists("/new_folder/new_empty_file")){
|
||||||
|
System.out.println("/new_folder/new_empty_file should not exists");
|
||||||
|
}
|
||||||
|
if(!filerClient.exists("/")){
|
||||||
|
System.out.println("/ should exists");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,13 +11,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.chrislusf</groupId>
|
<groupId>com.github.chrislusf</groupId>
|
||||||
<artifactId>seaweedfs-client</artifactId>
|
<artifactId>seaweedfs-client</artifactId>
|
||||||
<version>1.5.7</version>
|
<version>1.6.8</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.chrislusf</groupId>
|
<groupId>com.github.chrislusf</groupId>
|
||||||
<artifactId>seaweedfs-hadoop2-client</artifactId>
|
<artifactId>seaweedfs-hadoop2-client</artifactId>
|
||||||
<version>1.5.7</version>
|
<version>1.6.8</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
+5
-11
@@ -1,8 +1,7 @@
|
|||||||
package com.seaweedfs.examples;
|
package com.seaweedfs.examples;
|
||||||
|
|
||||||
import seaweed.hdfs.SeaweedHadoopInputStream;
|
|
||||||
import seaweedfs.client.FilerClient;
|
import seaweedfs.client.FilerClient;
|
||||||
import seaweedfs.client.FilerGrpcClient;
|
import seaweedfs.client.SeaweedInputStream;
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -10,12 +9,11 @@ import java.io.InputStream;
|
|||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipInputStream;
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
public class UnzipFile {
|
public class ExampleReadFile {
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
|
|
||||||
FilerGrpcClient filerGrpcClient = new FilerGrpcClient("localhost", 18888);
|
FilerClient filerClient = new FilerClient("localhost", 18888);
|
||||||
FilerClient filerClient = new FilerClient(filerGrpcClient);
|
|
||||||
|
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
parseZip("/Users/chris/tmp/test.zip");
|
parseZip("/Users/chris/tmp/test.zip");
|
||||||
@@ -24,12 +22,8 @@ public class UnzipFile {
|
|||||||
|
|
||||||
long localProcessTime = startTime2 - startTime;
|
long localProcessTime = startTime2 - startTime;
|
||||||
|
|
||||||
SeaweedHadoopInputStream seaweedInputStream = new SeaweedHadoopInputStream(
|
SeaweedInputStream seaweedInputStream = new SeaweedInputStream(
|
||||||
filerGrpcClient,
|
filerClient, "/test.zip");
|
||||||
new org.apache.hadoop.fs.FileSystem.Statistics(""),
|
|
||||||
"/",
|
|
||||||
filerClient.lookupEntry("/", "test.zip")
|
|
||||||
);
|
|
||||||
parseZip(seaweedInputStream);
|
parseZip(seaweedInputStream);
|
||||||
|
|
||||||
long swProcessTime = System.currentTimeMillis() - startTime2;
|
long swProcessTime = System.currentTimeMillis() - startTime2;
|
||||||
+1
-1
@@ -7,7 +7,7 @@ import java.io.IOException;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
public class WatchFiles {
|
public class ExampleWatchFileChanges {
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package com.seaweedfs.examples;
|
||||||
|
|
||||||
|
import seaweedfs.client.FilerClient;
|
||||||
|
import seaweedfs.client.SeaweedInputStream;
|
||||||
|
import seaweedfs.client.SeaweedOutputStream;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
|
public class ExampleWriteFile {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
|
||||||
|
FilerClient filerClient = new FilerClient("localhost", 18888);
|
||||||
|
|
||||||
|
SeaweedInputStream seaweedInputStream = new SeaweedInputStream(filerClient, "/test.zip");
|
||||||
|
unZipFiles(filerClient, seaweedInputStream);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void unZipFiles(FilerClient filerClient, InputStream is) throws IOException {
|
||||||
|
ZipInputStream zin = new ZipInputStream(is);
|
||||||
|
ZipEntry ze;
|
||||||
|
while ((ze = zin.getNextEntry()) != null) {
|
||||||
|
|
||||||
|
String filename = ze.getName();
|
||||||
|
if (filename.indexOf("/") >= 0) {
|
||||||
|
filename = filename.substring(filename.lastIndexOf("/") + 1);
|
||||||
|
}
|
||||||
|
if (filename.length()==0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SeaweedOutputStream seaweedOutputStream = new SeaweedOutputStream(filerClient, "/test/"+filename);
|
||||||
|
byte[] bytesIn = new byte[16 * 1024];
|
||||||
|
int read = 0;
|
||||||
|
while ((read = zin.read(bytesIn))!=-1) {
|
||||||
|
seaweedOutputStream.write(bytesIn,0,read);
|
||||||
|
}
|
||||||
|
seaweedOutputStream.close();
|
||||||
|
|
||||||
|
System.out.println(ze.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user