Compare commits

...
78 Commits
Author SHA1 Message Date
chrislu 42766bccc8 3.48 2023-04-30 22:20:18 -07:00
e9fda774f4 [Filer] post add param:saveInside (#4434)
* fix:mount deadlock

* feat: filer http upload to metadata

* feat: /etc save inside

---------

Co-authored-by: zemul <zhouzemiao@ihuman.com>
2023-04-29 08:31:05 -07:00
4867aa03ab Fix: http rename move dir to subdir (#4432)
Co-authored-by: wang wusong <wangwusong@virtaitech.com>
2023-04-26 20:54:36 -07:00
Konstantin LebedevandGitHub d75a7b7f62 allow deleting only older empty dir without recursion (#4430) 2023-04-25 08:31:14 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
fafff5896e build(deps): bump go.etcd.io/etcd/client/v3 from 3.5.7 to 3.5.8 (#4428)
Bumps [go.etcd.io/etcd/client/v3](https://github.com/etcd-io/etcd) from 3.5.7 to 3.5.8.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Changelog](https://github.com/etcd-io/etcd/blob/main/Dockerfile-release.ppc64le)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.5.7...v3.5.8)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-24 10:37:32 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
a36967982d build(deps): bump github.com/aws/aws-sdk-go from 1.44.244 to 1.44.248 (#4424)
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.44.244 to 1.44.248.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.44.244...v1.44.248)

---
updated-dependencies:
- dependency-name: github.com/aws/aws-sdk-go
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-24 10:27:40 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
3e714a53cf build(deps): bump golang.org/x/image from 0.6.0 to 0.7.0 (#4427)
Bumps [golang.org/x/image](https://github.com/golang/image) from 0.6.0 to 0.7.0.
- [Release notes](https://github.com/golang/image/releases)
- [Commits](https://github.com/golang/image/compare/v0.6.0...v0.7.0)

---
updated-dependencies:
- dependency-name: golang.org/x/image
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-24 10:27:25 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
5a46005ddf build(deps): bump go.mongodb.org/mongo-driver from 1.11.3 to 1.11.4 (#4426)
Bumps [go.mongodb.org/mongo-driver](https://github.com/mongodb/mongo-go-driver) from 1.11.3 to 1.11.4.
- [Release notes](https://github.com/mongodb/mongo-go-driver/releases)
- [Commits](https://github.com/mongodb/mongo-go-driver/compare/v1.11.3...v1.11.4)

---
updated-dependencies:
- dependency-name: go.mongodb.org/mongo-driver
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-24 10:27:17 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
54440f0d63 build(deps): bump modernc.org/sqlite from 1.21.1 to 1.22.0 (#4425)
Bumps [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) from 1.21.1 to 1.22.0.
- [Release notes](https://gitlab.com/cznic/sqlite/tags)
- [Commits](https://gitlab.com/cznic/sqlite/compare/v1.21.1...v1.22.0)

---
updated-dependencies:
- dependency-name: modernc.org/sqlite
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-24 10:27:09 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
fab0ab5440 build(deps): bump docker/metadata-action from 4.3.0 to 4.4.0 (#4423)
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 4.3.0 to 4.4.0.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/507c2f2dc502c992ad446e3d7a5dfbe311567a96...c4ee3adeed93b1fa6a762f209fb01608c1a22f1e)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-24 10:26:49 -07:00
zemulandGitHub f352616b7d Volume range read use sync.pool (#4422) 2023-04-24 07:00:48 -07:00
chrislu 18686b7375 3.47 2023-04-23 22:45:41 -07:00
68f1cc34a5 [mount]Fix copy file range (#4407)
* fix:mount deadlock

* fix

---------

Co-authored-by: zemul <zhouzemiao@ihuman.com>
2023-04-23 22:34:38 -07:00
chrislu e1b92bc701 reset local file content if remote file is updated
fix https://github.com/seaweedfs/seaweedfs/issues/4289
2023-04-22 22:32:21 -07:00
chrislu ff7b6d779e avoid overwriting variables
fix https://github.com/seaweedfs/seaweedfs/issues/4365
2023-04-22 11:49:59 -07:00
2e240704ab Writables inconsistency (#4417)
fix: inconsistent read and write permissions between master and volume server

Signed-off-by: Wusong Wang <wangwusong@virtaitech.com>
Co-authored-by: Wusong Wang <wangwusong@virtaitech.com>
2023-04-21 00:14:41 -07:00
19245dde50 mount: add retry for read only case (#4416)
* mount: add retry for read only case

Signed-off-by: Wusong Wang <wangwusong@virtaitech.com>

* add new util retry function for mount

Signed-off-by: Wusong Wang <wangwusong@virtaitech.com>

* change error list param

Signed-off-by: Wusong Wang <wangwusong@virtaitech.com>

---------

Signed-off-by: Wusong Wang <wangwusong@virtaitech.com>
Co-authored-by: Wusong Wang <wangwusong@virtaitech.com>
2023-04-21 00:09:31 -07:00
SmsS4andGitHub 4131874fa8 use env for flags wtih dot in name (#4415) 2023-04-20 09:33:27 -07:00
Damiano AlbaniandGitHub 9f55c7c90e Rclone storage backend (#4402)
* Add Rclone storage backend

* Support templating the name of files stored via Rclone

* Enable Rclone accounting

* Remove redundant type conversion

* Provide progress information for Rclone download/upload operations

* Log error when Rclone can't instantiate filesystem

* Remove filename templating functionality for Rclone storage

To (maybe) be later reintroduced as a generic functionality for all
storage backends.

* Remove S3 specific check

* Move Rclone config initialisation to init() method
2023-04-18 14:12:12 -07:00
a408b46d95 compilation fail (#4414)
Signed-off-by: Wusong Wang <wangwusong@virtaitech.com>
Co-authored-by: Wusong Wang <wangwusong@virtaitech.com>
2023-04-18 00:36:55 -07:00
chrislu 0a22eea55d collect ec shard from multiple locations
fix https://github.com/seaweedfs/seaweedfs/issues/4365
2023-04-17 22:56:21 -07:00
chrislu d50d736e68 Merge branch 'master' of https://github.com/seaweedfs/seaweedfs 2023-04-17 22:01:43 -07:00
chrislu ae9388723f adjust error message 2023-04-17 22:01:39 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
31db90942b build(deps): bump github.com/aws/aws-sdk-go from 1.44.219 to 1.44.244 (#4412)
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.44.219 to 1.44.244.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.44.219...v1.44.244)

---
updated-dependencies:
- dependency-name: github.com/aws/aws-sdk-go
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-17 09:19:04 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
839dd438bc build(deps): bump github.com/cenkalti/backoff/v4 from 4.2.0 to 4.2.1 (#4413)
Bumps [github.com/cenkalti/backoff/v4](https://github.com/cenkalti/backoff) from 4.2.0 to 4.2.1.
- [Release notes](https://github.com/cenkalti/backoff/releases)
- [Commits](https://github.com/cenkalti/backoff/compare/v4.2.0...v4.2.1)

---
updated-dependencies:
- dependency-name: github.com/cenkalti/backoff/v4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-17 09:18:48 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
bf3d0c4850 build(deps): bump github.com/prometheus/client_golang from 1.14.0 to 1.15.0 (#4411)
build(deps): bump github.com/prometheus/client_golang

Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.14.0 to 1.15.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.14.0...v1.15.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-17 09:18:34 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
ea5bbf30bb build(deps): bump github.com/lib/pq from 1.10.7 to 1.10.8 (#4410)
Bumps [github.com/lib/pq](https://github.com/lib/pq) from 1.10.7 to 1.10.8.
- [Release notes](https://github.com/lib/pq/releases)
- [Commits](https://github.com/lib/pq/compare/v1.10.7...v1.10.8)

---
updated-dependencies:
- dependency-name: github.com/lib/pq
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-17 09:18:24 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
a9b4be50af build(deps): bump github.com/tikv/client-go/v2 from 2.0.6 to 2.0.7 (#4409)
Bumps [github.com/tikv/client-go/v2](https://github.com/tikv/client-go) from 2.0.6 to 2.0.7.
- [Release notes](https://github.com/tikv/client-go/releases)
- [Commits](https://github.com/tikv/client-go/compare/v2.0.6...v2.0.7)

---
updated-dependencies:
- dependency-name: github.com/tikv/client-go/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-17 09:18:13 -07:00
chrislu 8ecdf958ab 3.46 2023-04-16 21:57:43 -07:00
Chengyu LiuandGitHub 0f653d2153 update fuse client log which should output the fh of FileHandle. (#4404) 2023-04-15 22:15:16 -07:00
0122e022ea Mount concurrent read (#4400)
* fix:mount deadlock

* feat: concurrent read

* fix

* Remove useless code

* fix

---------

Co-authored-by: zemul <zhouzemiao@ihuman.com>
2023-04-13 22:32:45 -07:00
5614ad0000 fix s3test test_bucket_listv2_delimiter_prefix_ends_with_delimiter (#4399)
* fix s3test test_bucket_listv2_delimiter_prefix_ends_with_delimiter

* fix list with delimiter and start token

---------

Co-authored-by: Konstantin Lebedev <9497591+kmlebedev@users.noreply.github.co>
2023-04-12 16:53:49 -07:00
samcdayandGitHub e60a7af644 fix(chart): use filer data PVC correctly (#4398) 2023-04-12 09:48:44 -07:00
Konstantin LebedevandGitHub 88b2bbadd1 try fix s3test test_bucket_listv2_delimiter_prefix (#4396) 2023-04-12 08:47:20 -07:00
095cdb0c7f fix test prefix is a directory (#4393)
Co-authored-by: Konstantin Lebedev <9497591+kmlebedev@users.noreply.github.co>
2023-04-12 00:08:13 -07:00
44ad07276c s3 fix get list of dir object key with slash suffix (#4391)
* s3 fix get list of dir object key with slash suffix
https://github.com/seaweedfs/seaweedfs/issues/3086

* list only entry dir eq prefix

---------

Co-authored-by: Konstantin Lebedev <9497591+kmlebedev@users.noreply.github.co>
2023-04-11 23:52:35 -07:00
Kyle PetryszakandGitHub ccc030b245 Fixing a service deployment bug (#4392) 2023-04-11 20:05:09 -07:00
Konstantin LebedevandGitHub 130bc3e668 s3 fix get fake dir object key (#4390) 2023-04-11 07:36:22 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
d1ce89950e build(deps): bump github.com/rabbitmq/amqp091-go from 1.7.0 to 1.8.0 (#4387)
Bumps [github.com/rabbitmq/amqp091-go](https://github.com/rabbitmq/amqp091-go) from 1.7.0 to 1.8.0.
- [Release notes](https://github.com/rabbitmq/amqp091-go/releases)
- [Changelog](https://github.com/rabbitmq/amqp091-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rabbitmq/amqp091-go/compare/v1.7.0...v1.8.0)

---
updated-dependencies:
- dependency-name: github.com/rabbitmq/amqp091-go
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-10 12:25:30 -07:00
MattandGitHub da1d3b5a33 adjusted regex to be from 1 to 255 for the value (#4377)
* compatibility patch for csi driver

* added namespace to all component parameters

* added namespace to all component parameters

* dereference in range

* added namespace to values.yml defaults

* added namespace to s3 component

* added helm chart to github pages

* added helm chart to github pages

* added helm chart to github pages

* added helm chart to github pages

* added helm chart to github pages

* push on all tags

* push on all tags

* push on all tags

* push on all tags

* push on all tags

* changed helm directory structure

* update charts location

* fixed dereference

* updated permissions

* updated permissions

* match current action schema

* added helm chart liniting CI

* modified chart list changed

* fixed nodejs warning

* standardized a few defaults

* added chart dirs

* lowerd period seconds for volume startup to test chart lint changes

* lowerd period seconds for volume startup to test chart lint changes

* test

* changed back

* adjustment

* debug ls statment

* removed change detection

* remvoed change detection

* always lint the charts

* added missing )

* fixed typo

* added spaces in front of all comments

* pdated values.yaml

* pdated values.yaml

* don't validate maintainers for now

* update helm_ci.yml

* update helm_ci.yml

* update helm_ci.yml

* update helm_ci.yml

* update helm_ci.yml

* - adds helm chart lint on changes
- adds test helm chart install on k8s

* updated helm chart readme.md

* added artifact hub

* added artifact hub

* added ttl validation

* adjusted regex to be from 1 to 255 for the value

* added better error message

* fixed regex
2023-04-10 12:24:38 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
b5b5c67cf6 build(deps): bump gocloud.dev/pubsub/natspubsub from 0.28.0 to 0.29.0 (#4389)
Bumps [gocloud.dev/pubsub/natspubsub](https://github.com/google/go-cloud) from 0.28.0 to 0.29.0.
- [Release notes](https://github.com/google/go-cloud/releases)
- [Commits](https://github.com/google/go-cloud/compare/v0.28.0...v0.29.0)

---
updated-dependencies:
- dependency-name: gocloud.dev/pubsub/natspubsub
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-10 12:23:17 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1d6a348d55 build(deps): bump github.com/schollz/progressbar/v3 from 3.13.0 to 3.13.1 (#4386)
build(deps): bump github.com/schollz/progressbar/v3

Bumps [github.com/schollz/progressbar/v3](https://github.com/schollz/progressbar) from 3.13.0 to 3.13.1.
- [Release notes](https://github.com/schollz/progressbar/releases)
- [Commits](https://github.com/schollz/progressbar/compare/v3.13.0...v3.13.1)

---
updated-dependencies:
- dependency-name: github.com/schollz/progressbar/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-10 12:22:59 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
04a9dc898f build(deps): bump golang.org/x/tools from 0.7.0 to 0.8.0 (#4385)
Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.7.0 to 0.8.0.
- [Release notes](https://github.com/golang/tools/releases)
- [Commits](https://github.com/golang/tools/compare/v0.7.0...v0.8.0)

---
updated-dependencies:
- dependency-name: golang.org/x/tools
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-10 12:22:46 -07:00
samcdayandGitHub adf80dc3f6 fix(chart): use hostpath filer persistence when deprecated enablePVC is unset (#4384) 2023-04-10 06:32:31 -07:00
MattandGitHub 2d213d87e1 File Path Configuration TTL Validation (#4376)
* compatibility patch for csi driver

* added namespace to all component parameters

* added namespace to all component parameters

* dereference in range

* added namespace to values.yml defaults

* added namespace to s3 component

* added helm chart to github pages

* added helm chart to github pages

* added helm chart to github pages

* added helm chart to github pages

* added helm chart to github pages

* push on all tags

* push on all tags

* push on all tags

* push on all tags

* push on all tags

* changed helm directory structure

* update charts location

* fixed dereference

* updated permissions

* updated permissions

* match current action schema

* added helm chart liniting CI

* modified chart list changed

* fixed nodejs warning

* standardized a few defaults

* added chart dirs

* lowerd period seconds for volume startup to test chart lint changes

* lowerd period seconds for volume startup to test chart lint changes

* test

* changed back

* adjustment

* debug ls statment

* removed change detection

* remvoed change detection

* always lint the charts

* added missing )

* fixed typo

* added spaces in front of all comments

* pdated values.yaml

* pdated values.yaml

* don't validate maintainers for now

* update helm_ci.yml

* update helm_ci.yml

* update helm_ci.yml

* update helm_ci.yml

* update helm_ci.yml

* - adds helm chart lint on changes
- adds test helm chart install on k8s

* updated helm chart readme.md

* added artifact hub

* added artifact hub

* added ttl validation
2023-04-04 22:07:17 -07:00
chrislu efef6e94bf use UPSERT for postgres style databases 2023-04-04 11:52:36 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
d4dec6c730 build(deps): bump google.golang.org/grpc from 1.53.0 to 1.54.0 (#4366)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.53.0 to 1.54.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.53.0...v1.54.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-03 11:15:08 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
080bfa7052 build(deps): bump modernc.org/sqlite from 1.21.0 to 1.21.1 (#4370)
Bumps [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) from 1.21.0 to 1.21.1.
- [Release notes](https://gitlab.com/cznic/sqlite/tags)
- [Commits](https://gitlab.com/cznic/sqlite/compare/v1.21.0...v1.21.1)

---
updated-dependencies:
- dependency-name: modernc.org/sqlite
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-03 11:12:29 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
0f2a8b0af1 build(deps): bump cloud.google.com/go/pubsub from 1.28.0 to 1.30.0 (#4367)
Bumps [cloud.google.com/go/pubsub](https://github.com/googleapis/google-cloud-go) from 1.28.0 to 1.30.0.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/pubsub/v1.28.0...pubsub/v1.30.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/pubsub
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-03 11:12:22 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
5aa89844b1 build(deps): bump google.golang.org/protobuf from 1.29.1 to 1.30.0 (#4369)
Bumps google.golang.org/protobuf from 1.29.1 to 1.30.0.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-03 11:12:12 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
671ee6af6d build(deps): bump github.com/linxGnu/grocksdb from 1.7.15 to 1.7.16 (#4368)
Bumps [github.com/linxGnu/grocksdb](https://github.com/linxGnu/grocksdb) from 1.7.15 to 1.7.16.
- [Release notes](https://github.com/linxGnu/grocksdb/releases)
- [Commits](https://github.com/linxGnu/grocksdb/compare/v1.7.15...v1.7.16)

---
updated-dependencies:
- dependency-name: github.com/linxGnu/grocksdb
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-03 11:12:05 -07:00
chrislu 422bfaed69 Merge branch 'master' of https://github.com/seaweedfs/seaweedfs 2023-04-02 22:53:02 -07:00
chrislu b9ab65dba5 3.45 2023-04-02 22:52:58 -07:00
wusongandGitHub 2b82d0f871 style: clerical error (#4361) 2023-03-31 07:36:21 -07:00
LHHDZandGitHub 8e80ce9476 fix key corrupt when fs.configure copy path trie (#4353)
Signed-off-by: changlin.shi <changlin.shi@ly.com>
2023-03-29 11:29:44 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
ff649d615d build(deps): bump cloud.google.com/go/storage from 1.30.0 to 1.30.1 (#4342)
Bumps [cloud.google.com/go/storage](https://github.com/googleapis/google-cloud-go) from 1.30.0 to 1.30.1.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/pubsub/v1.30.0...spanner/v1.30.1)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/storage
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-27 10:46:30 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
3e69a3aac5 build(deps): bump github.com/golang/protobuf from 1.5.2 to 1.5.3 (#4344)
Bumps [github.com/golang/protobuf](https://github.com/golang/protobuf) from 1.5.2 to 1.5.3.
- [Release notes](https://github.com/golang/protobuf/releases)
- [Commits](https://github.com/golang/protobuf/compare/v1.5.2...v1.5.3)

---
updated-dependencies:
- dependency-name: github.com/golang/protobuf
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-27 10:32:27 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
04190f9951 build(deps): bump go.mongodb.org/mongo-driver from 1.11.1 to 1.11.3 (#4340)
Bumps [go.mongodb.org/mongo-driver](https://github.com/mongodb/mongo-go-driver) from 1.11.1 to 1.11.3.
- [Release notes](https://github.com/mongodb/mongo-go-driver/releases)
- [Commits](https://github.com/mongodb/mongo-go-driver/compare/v1.11.1...v1.11.3)

---
updated-dependencies:
- dependency-name: go.mongodb.org/mongo-driver
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-27 10:32:16 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
d6ecde8a96 build(deps): bump google.golang.org/api from 0.112.0 to 0.114.0 (#4343)
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.112.0 to 0.114.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.112.0...v0.114.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-27 10:32:03 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
ddc5234f85 build(deps): bump github.com/gocql/gocql from 0.0.0-20210707082121-9a3953d1826d to 1.3.2 (#4341)
build(deps): bump github.com/gocql/gocql

Bumps [github.com/gocql/gocql](https://github.com/gocql/gocql) from 0.0.0-20210707082121-9a3953d1826d to 1.3.2.
- [Release notes](https://github.com/gocql/gocql/releases)
- [Commits](https://github.com/gocql/gocql/commits/v1.3.2)

---
updated-dependencies:
- dependency-name: github.com/gocql/gocql
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-27 10:31:54 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
47c4227318 build(deps): bump helm/chart-testing-action from 2.3.1 to 2.4.0 (#4339)
Bumps [helm/chart-testing-action](https://github.com/helm/chart-testing-action) from 2.3.1 to 2.4.0.
- [Release notes](https://github.com/helm/chart-testing-action/releases)
- [Commits](https://github.com/helm/chart-testing-action/compare/v2.3.1...v2.4.0)

---
updated-dependencies:
- dependency-name: helm/chart-testing-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-27 10:31:39 -07:00
chrislu 3cc7b90414 print wait in progress 2023-03-26 12:22:48 -07:00
chrislu f1f14e28bc adjust name 2023-03-26 12:17:23 -07:00
chrislu d54798c3ae Merge branch 'master' of https://github.com/seaweedfs/seaweedfs 2023-03-25 22:03:00 -07:00
chrislu 6bfb91b539 update entry Attributes.Mtime = time.Now().Unix()
fix https://github.com/seaweedfs/seaweedfs/issues/4337
2023-03-25 22:02:57 -07:00
renweijunandGitHub bbd461b2c6 weed mount default EnableACL,Support chmod chown (#4335) 2023-03-25 04:47:53 -07:00
chrislu 5db9fcccd4 refactoring 2023-03-21 23:01:49 -07:00
Konstantin LebedevandGitHub de4545c28b add validate config for raft (#4332) 2023-03-21 06:36:13 -07:00
MattandGitHub 5c783c16a1 Update artifacthub-repo-stable.yml (#4330)
fix to get official status on artifact hub
https://artifacthub.io/docs/topics/repositories/#official-status
2023-03-20 10:49:35 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
fba05959ef build(deps): bump github.com/tikv/client-go/v2 from 2.0.5 to 2.0.6 (#4329)
Bumps [github.com/tikv/client-go/v2](https://github.com/tikv/client-go) from 2.0.5 to 2.0.6.
- [Release notes](https://github.com/tikv/client-go/releases)
- [Commits](https://github.com/tikv/client-go/compare/v2.0.5...v2.0.6)

---
updated-dependencies:
- dependency-name: github.com/tikv/client-go/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-20 09:15:01 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
8d8347d2f7 build(deps): bump cloud.google.com/go/storage from 1.29.0 to 1.30.0 (#4328)
Bumps [cloud.google.com/go/storage](https://github.com/googleapis/google-cloud-go) from 1.29.0 to 1.30.0.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/pubsub/v1.29.0...spanner/v1.30.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/storage
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-20 09:13:38 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
60c20dce99 build(deps): bump golang.org/x/tools from 0.6.0 to 0.7.0 (#4327)
Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.6.0 to 0.7.0.
- [Release notes](https://github.com/golang/tools/releases)
- [Commits](https://github.com/golang/tools/compare/v0.6.0...v0.7.0)

---
updated-dependencies:
- dependency-name: golang.org/x/tools
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-20 09:13:00 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
279c2627f9 build(deps): bump github.com/hashicorp/raft from 1.3.11 to 1.4.0 (#4325)
Bumps [github.com/hashicorp/raft](https://github.com/hashicorp/raft) from 1.3.11 to 1.4.0.
- [Release notes](https://github.com/hashicorp/raft/releases)
- [Changelog](https://github.com/hashicorp/raft/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/raft/compare/v1.3.11...v1.4.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/raft
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-20 09:12:11 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
f90d23916e build(deps): bump wangyoucao577/go-release-action from 1.36 to 1.37 (#4324)
Bumps [wangyoucao577/go-release-action](https://github.com/wangyoucao577/go-release-action) from 1.36 to 1.37.
- [Release notes](https://github.com/wangyoucao577/go-release-action/releases)
- [Commits](https://github.com/wangyoucao577/go-release-action/compare/efb9406897e4eff1aa2c7142223b096aec90f267...b98909985b9c1fd7b0aaa4c51257a7ba49995781)

---
updated-dependencies:
- dependency-name: wangyoucao577/go-release-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-20 09:12:00 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
b2134b78d4 build(deps): bump actions/setup-go from 3.5.0 to 4.0.0 (#4323)
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 3.5.0 to 4.0.0.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/6edd4406fa81c3da01a34fa6f6343087c207a568...4d34df0c2316fe8122ab82dc22947d607c0c91f9)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-20 09:11:47 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
fa00882e81 build(deps): bump actions/dependency-review-action from 3.0.3 to 3.0.4 (#4322)
Bumps [actions/dependency-review-action](https://github.com/actions/dependency-review-action) from 3.0.3 to 3.0.4.
- [Release notes](https://github.com/actions/dependency-review-action/releases)
- [Commits](https://github.com/actions/dependency-review-action/compare/c090f4e553673e6e505ea70d6a95362ee12adb94...f46c48ed6d4f1227fb2d9ea62bf6bcbed315589e)

---
updated-dependencies:
- dependency-name: actions/dependency-review-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-20 09:11:38 -07:00
chrislu f0b2650adb fix image 2023-03-19 23:09:59 -07:00
chrislu adb90bd252 avoid lower casing the command
fix https://github.com/seaweedfs/seaweedfs/pull/4321
2023-03-19 21:20:46 -07:00
81 changed files with 1185 additions and 491 deletions
+4 -4
View File
@@ -44,7 +44,7 @@ jobs:
run: echo BUILD_TIME=$(date -u +%Y%m%d-%H%M) >> ${GITHUB_ENV}
- name: Go Release Binaries Large Disk
uses: wangyoucao577/go-release-action@efb9406897e4eff1aa2c7142223b096aec90f267 # v1.22
uses: wangyoucao577/go-release-action@b98909985b9c1fd7b0aaa4c51257a7ba49995781 # v1.22
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
@@ -60,7 +60,7 @@ jobs:
asset_name: "weed-large-disk-${{ env.BUILD_TIME }}-${{ matrix.goos }}-${{ matrix.goarch }}"
- name: Go Release Binaries Normal Volume Size
uses: wangyoucao577/go-release-action@efb9406897e4eff1aa2c7142223b096aec90f267 # v1.22
uses: wangyoucao577/go-release-action@b98909985b9c1fd7b0aaa4c51257a7ba49995781 # v1.22
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
@@ -93,7 +93,7 @@ jobs:
run: echo BUILD_TIME=$(date -u +%Y%m%d-%H%M) >> ${GITHUB_ENV}
- name: Go Release Binaries Large Disk
uses: wangyoucao577/go-release-action@efb9406897e4eff1aa2c7142223b096aec90f267 # v1.22
uses: wangyoucao577/go-release-action@b98909985b9c1fd7b0aaa4c51257a7ba49995781 # v1.22
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
@@ -109,7 +109,7 @@ jobs:
asset_name: "weed-large-disk-${{ env.BUILD_TIME }}-${{ matrix.goos }}-${{ matrix.goarch }}"
- name: Go Release Binaries Normal Volume Size
uses: wangyoucao577/go-release-action@efb9406897e4eff1aa2c7142223b096aec90f267 # v1.22
uses: wangyoucao577/go-release-action@b98909985b9c1fd7b0aaa4c51257a7ba49995781 # v1.22
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
+2 -2
View File
@@ -30,7 +30,7 @@ jobs:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v2
- name: Go Release Binaries Normal Volume Size
uses: wangyoucao577/go-release-action@efb9406897e4eff1aa2c7142223b096aec90f267 # v1.22
uses: wangyoucao577/go-release-action@b98909985b9c1fd7b0aaa4c51257a7ba49995781 # v1.22
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
@@ -44,7 +44,7 @@ jobs:
binary_name: weed
asset_name: "${{ matrix.goos }}_${{ matrix.goarch }}"
- name: Go Release Large Disk Binaries
uses: wangyoucao577/go-release-action@efb9406897e4eff1aa2c7142223b096aec90f267 # v1.22
uses: wangyoucao577/go-release-action@b98909985b9c1fd7b0aaa4c51257a7ba49995781 # v1.22
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
+2 -2
View File
@@ -30,7 +30,7 @@ jobs:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v2
- name: Go Release Binaries Normal Volume Size
uses: wangyoucao577/go-release-action@efb9406897e4eff1aa2c7142223b096aec90f267 # v1.22
uses: wangyoucao577/go-release-action@b98909985b9c1fd7b0aaa4c51257a7ba49995781 # v1.22
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
@@ -44,7 +44,7 @@ jobs:
binary_name: weed
asset_name: "${{ matrix.goos }}_${{ matrix.goarch }}"
- name: Go Release Large Disk Binaries
uses: wangyoucao577/go-release-action@efb9406897e4eff1aa2c7142223b096aec90f267 # v1.22
uses: wangyoucao577/go-release-action@b98909985b9c1fd7b0aaa4c51257a7ba49995781 # v1.22
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
+2 -2
View File
@@ -30,7 +30,7 @@ jobs:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v2
- name: Go Release Binaries Normal Volume Size
uses: wangyoucao577/go-release-action@efb9406897e4eff1aa2c7142223b096aec90f267 # v1.22
uses: wangyoucao577/go-release-action@b98909985b9c1fd7b0aaa4c51257a7ba49995781 # v1.22
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
@@ -44,7 +44,7 @@ jobs:
binary_name: weed
asset_name: "${{ matrix.goos }}_${{ matrix.goarch }}"
- name: Go Release Large Disk Binaries
uses: wangyoucao577/go-release-action@efb9406897e4eff1aa2c7142223b096aec90f267 # v1.22
uses: wangyoucao577/go-release-action@b98909985b9c1fd7b0aaa4c51257a7ba49995781 # v1.22
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
+2 -2
View File
@@ -30,7 +30,7 @@ jobs:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v2
- name: Go Release Binaries Normal Volume Size
uses: wangyoucao577/go-release-action@efb9406897e4eff1aa2c7142223b096aec90f267 # v1.22
uses: wangyoucao577/go-release-action@b98909985b9c1fd7b0aaa4c51257a7ba49995781 # v1.22
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
@@ -44,7 +44,7 @@ jobs:
binary_name: weed
asset_name: "${{ matrix.goos }}_${{ matrix.goarch }}"
- name: Go Release Large Disk Binaries
uses: wangyoucao577/go-release-action@efb9406897e4eff1aa2c7142223b096aec90f267 # v1.22
uses: wangyoucao577/go-release-action@b98909985b9c1fd7b0aaa4c51257a7ba49995781 # v1.22
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
+2 -2
View File
@@ -30,7 +30,7 @@ jobs:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v2
- name: Go Release Binaries Normal Volume Size
uses: wangyoucao577/go-release-action@efb9406897e4eff1aa2c7142223b096aec90f267 # v1.22
uses: wangyoucao577/go-release-action@b98909985b9c1fd7b0aaa4c51257a7ba49995781 # v1.22
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
@@ -45,7 +45,7 @@ jobs:
binary_name: weed
asset_name: "${{ matrix.goos }}_${{ matrix.goarch }}_full"
- name: Go Release Large Disk Binaries
uses: wangyoucao577/go-release-action@efb9406897e4eff1aa2c7142223b096aec90f267 # v1.22
uses: wangyoucao577/go-release-action@b98909985b9c1fd7b0aaa4c51257a7ba49995781 # v1.22
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
-
name: Docker meta
id: docker_meta
uses: docker/metadata-action@507c2f2dc502c992ad446e3d7a5dfbe311567a96 # v3
uses: docker/metadata-action@c4ee3adeed93b1fa6a762f209fb01608c1a22f1e # v3
with:
images: |
chrislusf/seaweedfs
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
-
name: Docker meta
id: docker_meta
uses: docker/metadata-action@507c2f2dc502c992ad446e3d7a5dfbe311567a96 # v3
uses: docker/metadata-action@c4ee3adeed93b1fa6a762f209fb01608c1a22f1e # v3
with:
images: |
chrislusf/seaweedfs
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
-
name: Docker meta
id: docker_meta
uses: docker/metadata-action@507c2f2dc502c992ad446e3d7a5dfbe311567a96 # v3
uses: docker/metadata-action@c4ee3adeed93b1fa6a762f209fb01608c1a22f1e # v3
with:
images: |
chrislusf/seaweedfs
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
-
name: Docker meta
id: docker_meta
uses: docker/metadata-action@507c2f2dc502c992ad446e3d7a5dfbe311567a96 # v3
uses: docker/metadata-action@c4ee3adeed93b1fa6a762f209fb01608c1a22f1e # v3
with:
images: |
chrislusf/seaweedfs
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
-
name: Docker meta
id: docker_meta
uses: docker/metadata-action@507c2f2dc502c992ad446e3d7a5dfbe311567a96 # v3
uses: docker/metadata-action@c4ee3adeed93b1fa6a762f209fb01608c1a22f1e # v3
with:
images: |
chrislusf/seaweedfs
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
-
name: Docker meta
id: docker_meta
uses: docker/metadata-action@507c2f2dc502c992ad446e3d7a5dfbe311567a96 # v3
uses: docker/metadata-action@c4ee3adeed93b1fa6a762f209fb01608c1a22f1e # v3
with:
images: |
chrislusf/seaweedfs
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
-
name: Docker meta
id: docker_meta
uses: docker/metadata-action@507c2f2dc502c992ad446e3d7a5dfbe311567a96 # v3
uses: docker/metadata-action@c4ee3adeed93b1fa6a762f209fb01608c1a22f1e # v3
with:
images: |
chrislusf/seaweedfs
+1 -1
View File
@@ -11,4 +11,4 @@ jobs:
- name: 'Checkout Repository'
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- name: 'Dependency Review'
uses: actions/dependency-review-action@c090f4e553673e6e505ea70d6a95362ee12adb94
uses: actions/dependency-review-action@f46c48ed6d4f1227fb2d9ea62bf6bcbed315589e
+1 -1
View File
@@ -24,7 +24,7 @@ jobs:
timeout-minutes: 15
steps:
- name: Set up Go 1.x
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v2
uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v2
with:
go-version: ^1.13
id: go
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
steps:
- name: Set up Go 1.x
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v2
uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v2
with:
go-version: ^1.13
id: go
+1 -1
View File
@@ -31,7 +31,7 @@ jobs:
check-latest: true
- name: Set up chart-testing
uses: helm/chart-testing-action@v2.3.1
uses: helm/chart-testing-action@v2.4.0
- name: Run chart-testing (list-changed)
id: list-changed
+112 -53
View File
@@ -4,17 +4,17 @@ go 1.20
require (
cloud.google.com/go v0.110.0 // indirect
cloud.google.com/go/pubsub v1.28.0
cloud.google.com/go/storage v1.29.0
cloud.google.com/go/pubsub v1.30.0
cloud.google.com/go/storage v1.30.1
github.com/Azure/azure-pipeline-go v0.2.3
github.com/Azure/azure-storage-blob-go v0.15.0
github.com/Shopify/sarama v1.38.1
github.com/aws/aws-sdk-go v1.44.219
github.com/cenkalti/backoff/v4 v4.2.0
github.com/aws/aws-sdk-go v1.44.248
github.com/beorn7/perks v1.0.1 // indirect
github.com/bwmarrin/snowflake v0.3.0
github.com/cenkalti/backoff/v4 v4.2.1
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/coreos/go-semver v0.3.0 // indirect
github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
@@ -35,16 +35,16 @@ require (
github.com/go-redsync/redsync/v4 v4.8.1
github.com/go-sql-driver/mysql v1.7.0
github.com/go-zookeeper/zk v1.0.3 // indirect
github.com/gocql/gocql v0.0.0-20210707082121-9a3953d1826d
github.com/gocql/gocql v1.3.2
github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2
github.com/golang/protobuf v1.5.3
github.com/golang/snappy v0.0.4 // indirect
github.com/google/btree v1.1.2
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/uuid v1.3.0
github.com/google/wire v0.5.0 // indirect
github.com/googleapis/gax-go/v2 v2.7.0 // indirect
github.com/googleapis/gax-go/v2 v2.7.1 // indirect
github.com/gorilla/mux v1.8.0
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
@@ -52,17 +52,17 @@ require (
github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/jcmturner/gofork v1.7.6 // indirect
github.com/jcmturner/gokrb5/v8 v8.4.3 // indirect
github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect
github.com/jinzhu/copier v0.3.5
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/json-iterator/go v1.1.12
github.com/karlseguin/ccache/v2 v2.0.8
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/klauspost/compress v1.15.14 // indirect
github.com/klauspost/compress v1.16.0 // indirect
github.com/klauspost/reedsolomon v1.11.7
github.com/kurin/blazer v0.5.3
github.com/lib/pq v1.10.7
github.com/linxGnu/grocksdb v1.7.15
github.com/lib/pq v1.10.8
github.com/linxGnu/grocksdb v1.7.16
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-ieproxy v0.0.9 // indirect
@@ -77,9 +77,9 @@ require (
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.14.0
github.com/prometheus/client_golang v1.15.0
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.39.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.9.0
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
@@ -90,7 +90,7 @@ require (
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/viper v1.15.0
github.com/stretchr/testify v1.8.1
github.com/stretchr/testify v1.8.2
github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203
github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965
github.com/tidwall/gjson v1.14.4
@@ -105,36 +105,36 @@ require (
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
go.etcd.io/etcd/client/v3 v3.5.7
go.mongodb.org/mongo-driver v1.11.1
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
go.etcd.io/etcd/client/v3 v3.5.8
go.mongodb.org/mongo-driver v1.11.4
go.opencensus.io v0.24.0 // indirect
gocloud.dev v0.29.0
gocloud.dev/pubsub/natspubsub v0.28.0
gocloud.dev/pubsub/natspubsub v0.29.0
gocloud.dev/pubsub/rabbitpubsub v0.29.0
golang.org/x/crypto v0.6.0 // indirect
golang.org/x/crypto v0.7.0 // indirect
golang.org/x/exp v0.0.0-20230124195608-d38c7dcee874
golang.org/x/image v0.6.0
golang.org/x/net v0.8.0
golang.org/x/image v0.7.0
golang.org/x/net v0.9.0
golang.org/x/oauth2 v0.6.0 // indirect
golang.org/x/sys v0.6.0
golang.org/x/text v0.8.0 // indirect
golang.org/x/tools v0.6.0
golang.org/x/sys v0.7.0
golang.org/x/text v0.9.0 // indirect
golang.org/x/tools v0.8.0
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/api v0.112.0
google.golang.org/api v0.114.0
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488 // indirect
google.golang.org/grpc v1.53.0
google.golang.org/protobuf v1.28.1
google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633 // indirect
google.golang.org/grpc v1.54.0
google.golang.org/protobuf v1.30.0
gopkg.in/inf.v0 v0.9.1 // indirect
modernc.org/b v1.0.0 // indirect
modernc.org/cc/v3 v3.40.0 // indirect
modernc.org/ccgo/v3 v3.16.13 // indirect
modernc.org/libc v1.22.3 // indirect
modernc.org/libc v1.22.4 // indirect
modernc.org/mathutil v1.5.0 // indirect
modernc.org/memory v1.5.0 // indirect
modernc.org/opt v0.1.3 // indirect
modernc.org/sqlite v1.21.0
modernc.org/sqlite v1.22.0
modernc.org/strutil v1.1.3
modernc.org/token v1.0.1 // indirect
)
@@ -146,20 +146,31 @@ require (
github.com/fluent/fluent-logger-golang v1.9.0
github.com/google/flatbuffers/go v0.0.0-20230108230133-3b8644d32c50
github.com/hanwen/go-fuse/v2 v2.2.0
github.com/hashicorp/raft v1.3.11
github.com/hashicorp/raft v1.4.0
github.com/hashicorp/raft-boltdb/v2 v2.2.2
github.com/rabbitmq/amqp091-go v1.7.0
github.com/schollz/progressbar/v3 v3.13.0
github.com/tikv/client-go/v2 v2.0.5
github.com/rabbitmq/amqp091-go v1.8.0
github.com/rclone/rclone v1.62.2
github.com/schollz/progressbar/v3 v3.13.1
github.com/tikv/client-go/v2 v2.0.7
github.com/ydb-platform/ydb-go-sdk-auth-environ v0.1.2
github.com/ydb-platform/ydb-go-sdk/v3 v3.43.0
google.golang.org/grpc/security/advancedtls v0.0.0-20220622233350-5cdb09fa29c1
)
require (
cloud.google.com/go/compute v1.18.0 // indirect
cloud.google.com/go/compute v1.19.0 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v0.12.0 // indirect
cloud.google.com/go/iam v0.13.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.2.2 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.2.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0 // indirect
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v0.9.0 // indirect
github.com/Max-Sum/base32768 v0.0.0-20230304063302-18e6ce5945fd // indirect
github.com/Microsoft/go-winio v0.5.2 // indirect
github.com/Unknwon/goconfig v1.0.0 // indirect
github.com/abbot/go-http-auth v0.4.0 // indirect
github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e // indirect
github.com/aws/aws-sdk-go-v2 v1.17.4 // indirect
github.com/aws/aws-sdk-go-v2/config v1.18.12 // indirect
@@ -177,69 +188,117 @@ require (
github.com/aws/smithy-go v1.13.5 // indirect
github.com/benbjohnson/clock v1.3.0 // indirect
github.com/boltdb/bolt v1.3.1 // indirect
github.com/cenkalti/backoff/v4 v4.2.0
github.com/buengese/sgzip v0.1.1 // indirect
github.com/calebcase/tmpfile v1.0.3 // indirect
github.com/colinmarc/hdfs/v2 v2.3.0 // indirect
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 // indirect
github.com/d4l3k/messagediff v1.2.1 // indirect
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 // indirect
github.com/dropbox/dropbox-sdk-go-unofficial/v6 v6.0.5 // indirect
github.com/elastic/gosigar v0.14.2 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/fclairamb/go-log v0.4.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/geoffgarside/ber v1.1.0 // indirect
github.com/go-chi/chi/v5 v5.0.8 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.4.3 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
github.com/hashicorp/go-hclog v1.2.0 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-msgpack v1.1.5 // indirect
github.com/hashicorp/golang-lru v0.6.0 // indirect
github.com/hirochachacha/go-smb2 v1.1.0 // indirect
github.com/iguanesolutions/go-systemd/v5 v5.1.1 // 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.3 // indirect
github.com/jlaffaye/ftp v0.1.1-0.20230214004652-d84bf4be2b6e // indirect
github.com/jonboulle/clockwork v0.2.2 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/jtolio/eventkit v0.0.0-20221004135224-074cf276595b // indirect
github.com/jzelinskie/whirlpool v0.0.0-20201016144138-0675e54bb004 // indirect
github.com/klauspost/cpuid/v2 v2.2.3 // indirect
github.com/koofr/go-httpclient v0.0.0-20230225102643-5d51a2e9dea6 // indirect
github.com/koofr/go-koofrclient v0.0.0-20221207135200-cbd7fc9ad6a6 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mattn/go-sqlite3 v2.0.1+incompatible // indirect
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
github.com/montanaflynn/stats v0.6.6 // indirect
github.com/nats-io/nats.go v1.20.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/montanaflynn/stats v0.7.0 // indirect
github.com/nats-io/nats.go v1.23.0 // indirect
github.com/nats-io/nkeys v0.3.0 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/ncw/go-acd v0.0.0-20201019170801-fe55f33415b1 // indirect
github.com/ncw/swift/v2 v2.0.1 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/oracle/oci-go-sdk/v65 v65.32.0 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/pengsrc/go-shared v0.2.1-0.20190131101655-1999055a4a14 // indirect
github.com/philhofer/fwd v1.1.1 // indirect
github.com/pierrec/lz4/v4 v4.1.17 // indirect
github.com/pingcap/errors v0.11.5-0.20211224045212-9687c2b0f87c // indirect
github.com/pingcap/failpoint v0.0.0-20210918120811-547c13e3eb00 // indirect
github.com/pingcap/kvproto v0.0.0-20230201112839-2b853bed8125 // indirect
github.com/pingcap/failpoint v0.0.0-20220801062533-2eaa32854a6c // indirect
github.com/pingcap/kvproto v0.0.0-20230403051650-e166ae588106 // indirect
github.com/pingcap/log v1.1.1-0.20221110025148-ca232912c9f3 // indirect
github.com/rivo/uniseg v0.4.3 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pkg/sftp v1.13.6-0.20230213180117-971c283182b6 // indirect
github.com/pkg/xattr v0.4.9 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/putdotio/go-putio/putio v0.0.0-20200123120452-16d982cac2b8 // indirect
github.com/rfjakob/eme v1.1.2 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/shirou/gopsutil/v3 v3.23.2 // indirect
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
github.com/sony/gobreaker v0.5.0 // indirect
github.com/spacemonkeygo/monkit/v3 v3.0.19 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stathat/consistent v1.0.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
github.com/t3rm1n4l/go-mega v0.0.0-20230228171823-a01a2cda13ca // indirect
github.com/tiancaiamao/gp v0.0.0-20221230034425-4025bc8a4d4a // indirect
github.com/tikv/pd v1.1.0-beta.0.20230202094356-18df271ce57f // indirect
github.com/tikv/pd/client v0.0.0-20230202094356-18df271ce57f // indirect
github.com/tikv/pd/client v0.0.0-20230329114254-1948c247c2b1 // indirect
github.com/tinylib/msgp v1.1.6 // indirect
github.com/tklauser/go-sysconf v0.3.11 // indirect
github.com/tklauser/numcpus v0.6.0 // indirect
github.com/twmb/murmur3 v1.1.3 // indirect
github.com/vivint/infectious v0.0.0-20200605153912-25a574ae18a3 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/yandex-cloud/go-genproto v0.0.0-20211115083454-9ca41db5ed9e // indirect
github.com/ydb-platform/ydb-go-genproto v0.0.0-20221215182650-986f9d10542f // indirect
github.com/ydb-platform/ydb-go-yc v0.8.3 // indirect
github.com/ydb-platform/ydb-go-yc-metadata v0.5.2 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
go.etcd.io/etcd/api/v3 v3.5.7 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.7 // indirect
github.com/yunify/qingstor-sdk-go/v3 v3.2.0 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
github.com/zeebo/blake3 v0.2.3 // indirect
github.com/zeebo/errs v1.3.0 // indirect
go.etcd.io/bbolt v1.3.7 // indirect
go.etcd.io/etcd/api/v3 v3.5.8 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.8 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
go.uber.org/zap v1.24.0 // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/term v0.6.0 // indirect
golang.org/x/term v0.7.0 // indirect
golang.org/x/time v0.3.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/uint128 v1.2.0 // indirect
storj.io/common v0.0.0-20221123115229-fed3e6651b63 // indirect
storj.io/drpc v0.0.32 // indirect
storj.io/uplink v1.10.0 // indirect
)
// replace github.com/seaweedfs/raft => /Users/chrislu/go/src/github.com/seaweedfs/raft
+239 -249
View File
File diff suppressed because it is too large Load Diff
@@ -13,4 +13,4 @@
repositoryID: 5b2f1fe2-20e5-486e-9746-183484642aa2
# owners: # (optional, used to claim repository ownership)
# - name: username
# email: email
# email: email
+2 -2
View File
@@ -1,5 +1,5 @@
apiVersion: v1
description: SeaweedFS
name: seaweedfs
appVersion: "3.44"
version: "3.44"
appVersion: "3.48"
version: "3.48"
@@ -20,6 +20,12 @@ spec:
port: {{ .Values.filer.grpcPort }}
targetPort: {{ .Values.filer.grpcPort }}
protocol: TCP
{{- if .Values.filer.s3.enabled }}
- name: "swfs-s3"
port: {{ .Values.filer.s3.port }}
targetPort: {{ .Values.filer.s3.port }}
protocol: TCP
{{- end }}
{{- if .Values.filer.metricsPort }}
- name: "metrics"
port: {{ .Values.filer.metricsPort }}
@@ -175,7 +175,7 @@ spec:
- mountPath: /etc/sw
name: config-users
readOnly: true
{{- if .Values.filer.enablePVC }}
{{- if (or .Values.filer.enablePVC (or (eq .Values.filer.data.type "hostPath") (eq .Values.filer.data.type "persistentVolumeClaim"))) }}
- name: data-filer
mountPath: /data
{{- end }}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

@@ -79,7 +79,19 @@ func startGenerateMetadata() {
func startSubscribeMetadata(eachEntryFunc func(event *filer_pb.SubscribeMetadataResponse) error) {
tailErr := pb.FollowMetadata(pb.ServerAddress(*tailFiler), grpc.WithTransportCredentials(insecure.NewCredentials()), "tail", 0, 0, *dir, nil, 0, 0, 0, eachEntryFunc, pb.TrivialOnError)
metadataFollowOption := &pb.MetadataFollowOption{
ClientName: "tail",
ClientId: 0,
ClientEpoch: 0,
SelfSignature: 0,
PathPrefix: *dir,
AdditionalPathPrefixes: nil,
DirectoriesToWatch: nil,
StartTsNs: 0,
StopTsNs: 0,
EventErrorType: pb.TrivialOnError,
}
tailErr := pb.FollowMetadata(pb.ServerAddress(*tailFiler), grpc.WithTransportCredentials(insecure.NewCredentials()), metadataFollowOption, eachEntryFunc)
if tailErr != nil {
fmt.Printf("tail %s: %v\n", *tailFiler, tailErr)
+14 -1
View File
@@ -138,6 +138,19 @@ func doFilerBackup(grpcDialOption grpc.DialOption, backupOption *FilerBackupOpti
}()
}
return pb.FollowMetadata(sourceFiler, grpcDialOption, "backup_"+dataSink.GetName(), clientId, clientEpoch, sourcePath, nil, startFrom.UnixNano(), 0, 0, processEventFnWithOffset, pb.TrivialOnError)
metadataFollowOption := &pb.MetadataFollowOption{
ClientName: "backup_" + dataSink.GetName(),
ClientId: clientId,
ClientEpoch: clientEpoch,
SelfSignature: 0,
PathPrefix: sourcePath,
AdditionalPathPrefixes: nil,
DirectoriesToWatch: nil,
StartTsNs: startFrom.UnixNano(),
StopTsNs: 0,
EventErrorType: pb.TrivialOnError,
}
return pb.FollowMetadata(sourceFiler, grpcDialOption, metadataFollowOption, processEventFnWithOffset)
}
+15 -2
View File
@@ -196,8 +196,21 @@ func (metaBackup *FilerMetaBackupOptions) streamMetadataBackup() error {
})
metaBackup.clientEpoch++
return pb.FollowMetadata(pb.ServerAddress(*metaBackup.filerAddress), metaBackup.grpcDialOption, "meta_backup", metaBackup.clientId, metaBackup.clientEpoch,
*metaBackup.filerDirectory, nil, startTime.UnixNano(), 0, 0, processEventFnWithOffset, pb.TrivialOnError)
metadataFollowOption := &pb.MetadataFollowOption{
ClientName: "meta_backup",
ClientId: metaBackup.clientId,
ClientEpoch: metaBackup.clientEpoch,
SelfSignature: 0,
PathPrefix: *metaBackup.filerDirectory,
AdditionalPathPrefixes: nil,
DirectoriesToWatch: nil,
StartTsNs: startTime.UnixNano(),
StopTsNs: 0,
EventErrorType: pb.TrivialOnError,
}
return pb.FollowMetadata(pb.ServerAddress(*metaBackup.filerAddress), metaBackup.grpcDialOption, metadataFollowOption, processEventFnWithOffset)
}
+21 -9
View File
@@ -107,16 +107,28 @@ func runFilerMetaTail(cmd *Command, args []string) bool {
untilTsNs = time.Now().Add(-*tailStop).UnixNano()
}
tailErr := pb.FollowMetadata(pb.ServerAddress(*tailFiler), grpcDialOption, "tail", clientId, 0, *tailTarget, nil,
time.Now().Add(-*tailStart).UnixNano(), untilTsNs, 0, func(resp *filer_pb.SubscribeMetadataResponse) error {
if !shouldPrint(resp) {
return nil
}
if err := eachEntryFunc(resp); err != nil {
return err
}
metadataFollowOption := &pb.MetadataFollowOption{
ClientName: "tail",
ClientId: clientId,
ClientEpoch: 0,
SelfSignature: 0,
PathPrefix: *tailTarget,
AdditionalPathPrefixes: nil,
DirectoriesToWatch: nil,
StartTsNs: time.Now().Add(-*tailStart).UnixNano(),
StopTsNs: untilTsNs,
EventErrorType: pb.TrivialOnError,
}
tailErr := pb.FollowMetadata(pb.ServerAddress(*tailFiler), grpcDialOption, metadataFollowOption, func(resp *filer_pb.SubscribeMetadataResponse) error {
if !shouldPrint(resp) {
return nil
}, pb.TrivialOnError)
}
if err := eachEntryFunc(resp); err != nil {
return err
}
return nil
})
if tailErr != nil {
fmt.Printf("tail %s: %v\n", *tailFiler, tailErr)
+15 -2
View File
@@ -39,8 +39,21 @@ func (option *RemoteGatewayOptions) followBucketUpdatesAndUploadToRemote(filerSo
lastOffsetTs := collectLastSyncOffset(option, option.grpcDialOption, pb.ServerAddress(*option.filerAddress), option.bucketsDir, *option.timeAgo)
option.clientEpoch++
return pb.FollowMetadata(pb.ServerAddress(*option.filerAddress), option.grpcDialOption, "filer.remote.sync", option.clientId, option.clientEpoch,
option.bucketsDir, []string{filer.DirectoryEtcRemote}, lastOffsetTs.UnixNano(), 0, 0, processEventFnWithOffset, pb.TrivialOnError)
metadataFollowOption := &pb.MetadataFollowOption{
ClientName: "filer.remote.sync",
ClientId: option.clientId,
ClientEpoch: option.clientEpoch,
SelfSignature: 0,
PathPrefix: option.bucketsDir,
AdditionalPathPrefixes: []string{filer.DirectoryEtcRemote},
DirectoriesToWatch: nil,
StartTsNs: lastOffsetTs.UnixNano(),
StopTsNs: 0,
EventErrorType: pb.TrivialOnError,
}
return pb.FollowMetadata(pb.ServerAddress(*option.filerAddress), option.grpcDialOption, metadataFollowOption, processEventFnWithOffset)
}
func (option *RemoteGatewayOptions) makeBucketedEventProcessor(filerSource *source.FilerSource) (pb.ProcessMetadataFunc, error) {
+15 -2
View File
@@ -63,8 +63,21 @@ func followUpdatesAndUploadToRemote(option *RemoteSyncOptions, filerSource *sour
lastOffsetTs := collectLastSyncOffset(option, option.grpcDialOption, pb.ServerAddress(*option.filerAddress), mountedDir, *option.timeAgo)
option.clientEpoch++
return pb.FollowMetadata(pb.ServerAddress(*option.filerAddress), option.grpcDialOption, "filer.remote.sync", option.clientId, option.clientEpoch,
mountedDir, []string{filer.DirectoryEtcRemote}, lastOffsetTs.UnixNano(), 0, 0, processEventFnWithOffset, pb.TrivialOnError)
metadataFollowOption := &pb.MetadataFollowOption{
ClientName: "filer.remote.sync",
ClientId: option.clientId,
ClientEpoch: option.clientEpoch,
SelfSignature: 0,
PathPrefix: mountedDir,
AdditionalPathPrefixes: []string{filer.DirectoryEtcRemote},
DirectoriesToWatch: nil,
StartTsNs: lastOffsetTs.UnixNano(),
StopTsNs: 0,
EventErrorType: pb.TrivialOnError,
}
return pb.FollowMetadata(pb.ServerAddress(*option.filerAddress), option.grpcDialOption, metadataFollowOption, processEventFnWithOffset)
}
func makeEventProcessor(remoteStorage *remote_pb.RemoteConf, mountedDir string, remoteStorageMountLocation *remote_pb.RemoteStorageLocation, filerSource *source.FilerSource) (pb.ProcessMetadataFunc, error) {
+14 -2
View File
@@ -287,8 +287,20 @@ func doSubscribeFilerMetaChanges(clientId int32, clientEpoch int32, grpcDialOpti
return setOffset(grpcDialOption, targetFiler, getSignaturePrefixByPath(sourcePath), sourceFilerSignature, processor.processedTsWatermark)
})
return pb.FollowMetadata(sourceFiler, grpcDialOption, clientName, clientId, clientEpoch,
sourcePath, nil, sourceFilerOffsetTsNs, 0, targetFilerSignature, processEventFnWithOffset, pb.RetryForeverOnError)
metadataFollowOption := &pb.MetadataFollowOption{
ClientName: clientName,
ClientId: clientId,
ClientEpoch: clientEpoch,
SelfSignature: targetFilerSignature,
PathPrefix: sourcePath,
AdditionalPathPrefixes: nil,
DirectoriesToWatch: nil,
StartTsNs: sourceFilerOffsetTsNs,
StopTsNs: 0,
EventErrorType: pb.RetryForeverOnError,
}
return pb.FollowMetadata(sourceFiler, grpcDialOption, metadataFollowOption, processEventFnWithOffset)
}
+1 -1
View File
@@ -182,7 +182,7 @@ func RunMount(option *MountOptions, umask os.FileMode) bool {
DirectMount: true,
DirectMountFlags: 0,
//SyncRead: false, // set to false to enable the FUSE_CAP_ASYNC_READ capability
//EnableAcl: true,
EnableAcl: true,
}
if *option.nonempty {
fuseMountOptions.Options = append(fuseMountOptions.Options, "nonempty")
+3 -3
View File
@@ -108,7 +108,7 @@ connection_max_open = 100
connection_max_lifetime_seconds = 0
# if insert/upsert failing, you can disable upsert or update query syntax to match your RDBMS syntax:
enableUpsert = true
upsertQuery = """INSERT INTO "%[1]s" (dirhash,name,directory,meta) VALUES($1,$2,$3,$4) ON CONFLICT (dirhash,name) DO UPDATE SET meta = EXCLUDED.meta WHERE "%[1]s".meta != EXCLUDED.meta"""
upsertQuery = """UPSERT INTO "%[1]s" (dirhash,name,directory,meta) VALUES($1,$2,$3,$4)"""
[postgres2]
enabled = false
@@ -133,7 +133,7 @@ connection_max_open = 100
connection_max_lifetime_seconds = 0
# if insert/upsert failing, you can disable upsert or update query syntax to match your RDBMS syntax:
enableUpsert = true
upsertQuery = """INSERT INTO "%[1]s" (dirhash,name,directory,meta) VALUES($1,$2,$3,$4) ON CONFLICT (dirhash,name) DO UPDATE SET meta = EXCLUDED.meta WHERE "%[1]s".meta != EXCLUDED.meta"""
upsertQuery = """UPSERT INTO "%[1]s" (dirhash,name,directory,meta) VALUES($1,$2,$3,$4)"""
[cassandra]
# CREATE TABLE filemeta (
@@ -344,4 +344,4 @@ cert_path=""
# Set the private key path
key_path=""
# The name list used to verify the cn name
verify_cn=""
verify_cn=""
+23 -7
View File
@@ -13,7 +13,8 @@ type FileChunkSection struct {
visibleIntervals *IntervalList[*VisibleInterval]
chunkViews *IntervalList[*ChunkView]
reader *ChunkReadAt
lock sync.Mutex
lock sync.RWMutex
isPrepared bool
}
func NewFileChunkSection(si SectionIndex) *FileChunkSection {
@@ -61,6 +62,19 @@ func removeGarbageChunks(section *FileChunkSection, garbageFileIds map[string]st
}
func (section *FileChunkSection) setupForRead(group *ChunkGroup, fileSize int64) {
if section.isPrepared {
section.reader.fileSize = fileSize
return
}
section.lock.Lock()
defer section.lock.Unlock()
if section.isPrepared {
section.reader.fileSize = fileSize
return
}
if section.visibleIntervals == nil {
section.visibleIntervals = readResolvedChunks(section.chunks, int64(section.sectionIndex)*SectionSize, (int64(section.sectionIndex)+1)*SectionSize)
section.chunks, _ = SeparateGarbageChunks(section.visibleIntervals, section.chunks)
@@ -76,23 +90,25 @@ func (section *FileChunkSection) setupForRead(group *ChunkGroup, fileSize int64)
if section.reader == nil {
section.reader = NewChunkReaderAtFromClient(group.readerCache, section.chunkViews, min(int64(section.sectionIndex+1)*SectionSize, fileSize))
}
section.isPrepared = true
section.reader.fileSize = fileSize
}
func (section *FileChunkSection) readDataAt(group *ChunkGroup, fileSize int64, buff []byte, offset int64) (n int, tsNs int64, err error) {
section.lock.Lock()
defer section.lock.Unlock()
section.setupForRead(group, fileSize)
section.lock.RLock()
defer section.lock.RUnlock()
return section.reader.ReadAtWithTime(buff, offset)
}
func (section *FileChunkSection) DataStartOffset(group *ChunkGroup, offset int64, fileSize int64) int64 {
section.lock.Lock()
defer section.lock.Unlock()
section.setupForRead(group, fileSize)
section.lock.RLock()
defer section.lock.RUnlock()
for x := section.visibleIntervals.Front(); x != nil; x = x.Next {
visible := x.Value
@@ -108,10 +124,10 @@ func (section *FileChunkSection) DataStartOffset(group *ChunkGroup, offset int64
}
func (section *FileChunkSection) NextStopOffset(group *ChunkGroup, offset int64, fileSize int64) int64 {
section.lock.Lock()
defer section.lock.Unlock()
section.setupForRead(group, fileSize)
section.lock.RLock()
defer section.lock.RUnlock()
isAfterOffset := false
for x := section.visibleIntervals.Front(); x != nil; x = x.Next {
+17 -4
View File
@@ -87,10 +87,23 @@ func (f *Filer) MaybeBootstrapFromPeers(self pb.ServerAddress, existingNodes []*
glog.V(0).Infof("bootstrap from %v clientId:%d", earliestNode.Address, f.UniqueFilerId)
f.UniqueFilerEpoch++
err = pb.FollowMetadata(pb.ServerAddress(earliestNode.Address), f.GrpcDialOption, "bootstrap", f.UniqueFilerId, f.UniqueFilerEpoch, "/", nil,
0, snapshotTime.UnixNano(), f.Signature, func(resp *filer_pb.SubscribeMetadataResponse) error {
return Replay(f.Store, resp)
}, pb.FatalOnError)
metadataFollowOption := &pb.MetadataFollowOption{
ClientName: "bootstrap",
ClientId: f.UniqueFilerId,
ClientEpoch: f.UniqueFilerEpoch,
SelfSignature: f.Signature,
PathPrefix: "/",
AdditionalPathPrefixes: nil,
DirectoriesToWatch: nil,
StartTsNs: snapshotTime.UnixNano(),
StopTsNs: 0,
EventErrorType: pb.FatalOnError,
}
err = pb.FollowMetadata(pb.ServerAddress(earliestNode.Address), f.GrpcDialOption, metadataFollowOption, func(resp *filer_pb.SubscribeMetadataResponse) error {
return Replay(f.Store, resp)
})
return
}
+2 -1
View File
@@ -125,7 +125,8 @@ func (fc *FilerConf) DeleteLocationConf(locationPrefix string) {
if string(key) == locationPrefix {
return true
}
rules.Put(key, value)
key = bytes.Clone(key)
_ = rules.Put(key, value)
return true
})
fc.rules = rules
+9 -2
View File
@@ -2,16 +2,23 @@ package filer
import (
"fmt"
"github.com/seaweedfs/seaweedfs/weed/util"
"strings"
"github.com/seaweedfs/seaweedfs/weed/util"
)
func (f *Filer) CanRename(source, target util.FullPath) error {
func (f *Filer) CanRename(source, target util.FullPath, oldName string) error {
sourcePath := source.Child(oldName)
if strings.HasPrefix(string(target), string(sourcePath)) {
return fmt.Errorf("mv: can not move directory to a subdirectory of itself")
}
sourceBucket := f.DetectBucket(source)
targetBucket := f.DetectBucket(target)
if sourceBucket != targetBucket {
return fmt.Errorf("can not move across collection %s => %s", sourceBucket, targetBucket)
}
return nil
}
+3 -3
View File
@@ -27,7 +27,7 @@ func (interval *Interval[T]) Size() int64 {
type IntervalList[T IntervalValue] struct {
head *Interval[T]
tail *Interval[T]
Lock sync.Mutex
Lock sync.RWMutex
}
func NewIntervalList[T IntervalValue]() *IntervalList[T] {
@@ -248,8 +248,8 @@ func (list *IntervalList[T]) overlayInterval(interval *Interval[T]) {
}
func (list *IntervalList[T]) Len() int {
list.Lock.Lock()
defer list.Lock.Unlock()
list.Lock.RLock()
defer list.Lock.RUnlock()
var count int
for t := list.head; t != nil; t = t.Next {
+4 -4
View File
@@ -106,8 +106,8 @@ func (c *ChunkReadAt) ReadAt(p []byte, offset int64) (n int, err error) {
c.readerPattern.MonitorReadAt(offset, len(p))
c.chunkViews.Lock.Lock()
defer c.chunkViews.Lock.Unlock()
c.chunkViews.Lock.RLock()
defer c.chunkViews.Lock.RUnlock()
// glog.V(4).Infof("ReadAt [%d,%d) of total file size %d bytes %d chunk views", offset, offset+int64(len(p)), c.fileSize, len(c.chunkViews))
n, _, err = c.doReadAt(p, offset)
@@ -118,8 +118,8 @@ func (c *ChunkReadAt) ReadAtWithTime(p []byte, offset int64) (n int, ts int64, e
c.readerPattern.MonitorReadAt(offset, len(p))
c.chunkViews.Lock.Lock()
defer c.chunkViews.Lock.Unlock()
c.chunkViews.Lock.RLock()
defer c.chunkViews.Lock.RUnlock()
// glog.V(4).Infof("ReadAt [%d,%d) of total file size %d bytes %d chunk views", offset, offset+int64(len(p)), c.fileSize, len(c.chunkViews))
return c.doReadAt(p, offset)
+5 -3
View File
@@ -17,7 +17,7 @@ type FileHandle struct {
fh FileHandleId
counter int64
entry *LockedEntry
entryLock sync.Mutex
entryLock sync.RWMutex
entryChunkGroup *filer.ChunkGroup
inode uint64
wfs *WFS
@@ -27,8 +27,7 @@ type FileHandle struct {
dirtyPages *PageWriter
reader *filer.ChunkReadAt
contentType string
handle uint64
sync.Mutex
sync.RWMutex
isDeleted bool
@@ -103,6 +102,9 @@ func (fh *FileHandle) AddChunks(chunks []*filer_pb.FileChunk) {
}
func (fh *FileHandle) ReleaseHandle() {
fh.Lock()
defer fh.Unlock()
fh.entryLock.Lock()
defer fh.entryLock.Unlock()
+2 -2
View File
@@ -23,8 +23,8 @@ func (fh *FileHandle) readFromDirtyPages(buff []byte, startOffset int64, tsNs in
}
func (fh *FileHandle) readFromChunks(buff []byte, offset int64) (int64, int64, error) {
fh.entryLock.Lock()
defer fh.entryLock.Unlock()
fh.entryLock.RLock()
defer fh.entryLock.RUnlock()
fileFullPath := fh.FullPath()
+13 -1
View File
@@ -58,9 +58,21 @@ func SubscribeMetaEvents(mc *MetaCache, selfSignature int32, client filer_pb.Fil
}
var clientEpoch int32
metadataFollowOption := &pb.MetadataFollowOption{
ClientName: "mount",
ClientId: selfSignature,
ClientEpoch: clientEpoch,
SelfSignature: selfSignature,
PathPrefix: dir,
AdditionalPathPrefixes: nil,
DirectoriesToWatch: nil,
StartTsNs: lastTsNs,
StopTsNs: 0,
EventErrorType: pb.FatalOnError,
}
util.RetryForever("followMetaUpdates", func() error {
clientEpoch++
return pb.WithFilerClientFollowMetadata(client, "mount", selfSignature, clientEpoch, dir, nil, &lastTsNs, 0, selfSignature, processEventFn, pb.FatalOnError)
return pb.WithFilerClientFollowMetadata(client, metadataFollowOption, processEventFn)
}, func(err error) bool {
glog.Errorf("follow metadata updates: %v", err)
return true
+2 -2
View File
@@ -58,12 +58,12 @@ func (wfs *WFS) Lookup(cancel <-chan struct{}, header *fuse.InHeader, name strin
inode := wfs.inodeToPath.Lookup(fullFilePath, localEntry.Crtime.Unix(), localEntry.IsDirectory(), len(localEntry.HardLinkId) > 0, localEntry.Inode, true)
if fh, found := wfs.fhmap.FindFileHandle(inode); found {
fh.entryLock.Lock()
fh.entryLock.RLock()
if entry := fh.GetEntry(); entry != nil {
glog.V(4).Infof("lookup opened file %s size %d", dirPath.Child(localEntry.Name()), filer.FileSize(entry))
localEntry = filer.FromPbEntry(string(dirPath), entry)
}
fh.entryLock.Unlock()
fh.entryLock.RUnlock()
}
wfs.outputFilerEntry(out, inode, localEntry)
+2 -6
View File
@@ -46,18 +46,14 @@ func (wfs *WFS) CopyFileRange(cancel <-chan struct{}, in *fuse.CopyFileRangeIn)
// lock source and target file handles
fhOut.Lock()
defer fhOut.Unlock()
fhOut.entryLock.Lock()
defer fhOut.entryLock.Unlock()
if fhOut.entry == nil {
return 0, fuse.ENOENT
}
if fhIn.fh != fhOut.fh {
fhIn.Lock()
defer fhIn.Unlock()
fhIn.entryLock.Lock()
defer fhIn.entryLock.Unlock()
fhIn.RLock()
defer fhIn.RUnlock()
}
// directories are not supported
+4 -4
View File
@@ -35,10 +35,10 @@ func (wfs *WFS) Lseek(cancel <-chan struct{}, in *fuse.LseekIn, out *fuse.LseekO
}
// lock the file until the proper offset was calculated
fh.Lock()
defer fh.Unlock()
fh.entryLock.Lock()
defer fh.entryLock.Unlock()
fh.RLock()
defer fh.RUnlock()
fh.entryLock.RLock()
defer fh.entryLock.RUnlock()
fileSize := int64(filer.FileSize(fh.GetEntry()))
offset := max(int64(in.Offset), 0)
+2 -2
View File
@@ -41,8 +41,8 @@ func (wfs *WFS) Read(cancel <-chan struct{}, in *fuse.ReadIn, buff []byte) (fuse
return nil, fuse.ENOENT
}
fh.Lock()
defer fh.Unlock()
fh.RLock()
defer fh.RUnlock()
offset := int64(in.Offset)
totalRead, err := readDataByFileHandle(buff, fh, offset)
+2 -2
View File
@@ -96,7 +96,7 @@ func (wfs *WFS) doFlush(fh *FileHandle, uid, gid uint32) fuse.Status {
fileFullPath := fh.FullPath()
dir, name := fileFullPath.DirAndName()
// send the data to the OS
glog.V(4).Infof("doFlush %s fh %d", fileFullPath, fh.handle)
glog.V(4).Infof("doFlush %s fh %d", fileFullPath, fh.fh)
if !wfs.IsOverQuota {
if err := fh.dirtyPages.FlushData(); err != nil {
@@ -177,7 +177,7 @@ func (wfs *WFS) doFlush(fh *FileHandle, uid, gid uint32) fuse.Status {
}
if err != nil {
glog.Errorf("%v fh %d flush: %v", fileFullPath, fh.handle, err)
glog.Errorf("%v fh %d flush: %v", fileFullPath, fh.fh, err)
return fuse.EIO
}
+1
View File
@@ -137,6 +137,7 @@ type StorageOption struct {
TtlSeconds int32
Fsync bool
VolumeGrowthCount uint32
SaveInside bool
}
func (so *StorageOption) TtlString() string {
+8 -6
View File
@@ -5,11 +5,6 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
"github.com/seaweedfs/seaweedfs/weed/security"
"github.com/seaweedfs/seaweedfs/weed/stats"
"github.com/seaweedfs/seaweedfs/weed/util"
"io"
"mime"
"mime/multipart"
@@ -19,6 +14,12 @@ import (
"path/filepath"
"strings"
"time"
"github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
"github.com/seaweedfs/seaweedfs/weed/security"
"github.com/seaweedfs/seaweedfs/weed/stats"
"github.com/seaweedfs/seaweedfs/weed/util"
)
type UploadOption struct {
@@ -120,7 +121,8 @@ func UploadWithRetry(filerClient filer_pb.FilerClient, assignRequest *filer_pb.A
return true
})
} else {
err = util.Retry("uploadWithRetry", doUploadFunc)
uploadErrList := []string{"transport", "is read only"}
err = util.MultiRetry("uploadWithRetry", uploadErrList, doUploadFunc)
}
return
+11
View File
@@ -6,6 +6,7 @@ import (
"fmt"
"os"
"strings"
"time"
"github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/storage/needle"
@@ -13,6 +14,8 @@ import (
"google.golang.org/protobuf/proto"
)
const cutoffTimeNewEmptyDir = 3
func (entry *Entry) IsInRemoteOnly() bool {
return len(entry.GetChunks()) == 0 && entry.RemoteEntry != nil && entry.RemoteEntry.RemoteSize > 0
}
@@ -28,6 +31,10 @@ func (entry *Entry) FileMode() (fileMode os.FileMode) {
return
}
func (entry *Entry) IsOlderDir() bool {
return entry.IsDirectory && entry.Attributes != nil && entry.Attributes.Mime == "" && entry.Attributes.GetCrtime() <= time.Now().Unix()-cutoffTimeNewEmptyDir
}
func ToFileIdObject(fileIdStr string) (*FileId, error) {
t, err := needle.ParseFileIdFromString(fileIdStr)
if err != nil {
@@ -143,18 +150,22 @@ var ErrNotFound = errors.New("filer: no entry is found in filer store")
func IsEmpty(event *SubscribeMetadataResponse) bool {
return event.EventNotification.NewEntry == nil && event.EventNotification.OldEntry == nil
}
func IsCreate(event *SubscribeMetadataResponse) bool {
return event.EventNotification.NewEntry != nil && event.EventNotification.OldEntry == nil
}
func IsUpdate(event *SubscribeMetadataResponse) bool {
return event.EventNotification.NewEntry != nil &&
event.EventNotification.OldEntry != nil &&
event.Directory == event.EventNotification.NewParentPath &&
event.EventNotification.NewEntry.Name == event.EventNotification.OldEntry.Name
}
func IsDelete(event *SubscribeMetadataResponse) bool {
return event.EventNotification.NewEntry == nil && event.EventNotification.OldEntry != nil
}
func IsRename(event *SubscribeMetadataResponse) bool {
return event.EventNotification.NewEntry != nil &&
event.EventNotification.OldEntry != nil &&
+31 -18
View File
@@ -19,22 +19,35 @@ const (
RetryForeverOnError
)
// MetadataFollowOption is used to control the behavior of the metadata following
// process. Part of it is used as a cursor to resume the following process.
type MetadataFollowOption struct {
ClientName string
ClientId int32
ClientEpoch int32
SelfSignature int32
PathPrefix string
AdditionalPathPrefixes []string
DirectoriesToWatch []string
StartTsNs int64
StopTsNs int64
EventErrorType EventErrorType
}
type ProcessMetadataFunc func(resp *filer_pb.SubscribeMetadataResponse) error
func FollowMetadata(filerAddress ServerAddress, grpcDialOption grpc.DialOption, clientName string, clientId int32, clientEpoch int32,
pathPrefix string, additionalPathPrefixes []string, lastTsNs int64, untilTsNs int64, selfSignature int32,
processEventFn ProcessMetadataFunc, eventErrorType EventErrorType) error {
func FollowMetadata(filerAddress ServerAddress, grpcDialOption grpc.DialOption, option *MetadataFollowOption, processEventFn ProcessMetadataFunc) error {
err := WithFilerClient(true, clientId, filerAddress, grpcDialOption, makeSubscribeMetadataFunc(clientName, clientId, clientEpoch, pathPrefix, additionalPathPrefixes, nil, &lastTsNs, untilTsNs, selfSignature, processEventFn, eventErrorType))
err := WithFilerClient(true, option.SelfSignature, filerAddress, grpcDialOption, makeSubscribeMetadataFunc(option, processEventFn))
if err != nil {
return fmt.Errorf("subscribing filer meta change: %v", err)
}
return err
}
func WithFilerClientFollowMetadata(filerClient filer_pb.FilerClient, clientName string, clientId int32, clientEpoch int32, pathPrefix string, directoriesToWatch []string, lastTsNs *int64, untilTsNs int64, selfSignature int32, processEventFn ProcessMetadataFunc, eventErrorType EventErrorType) error {
func WithFilerClientFollowMetadata(filerClient filer_pb.FilerClient, option *MetadataFollowOption, processEventFn ProcessMetadataFunc) error {
err := filerClient.WithFilerClient(true, makeSubscribeMetadataFunc(clientName, clientId, clientEpoch, pathPrefix, nil, directoriesToWatch, lastTsNs, untilTsNs, selfSignature, processEventFn, eventErrorType))
err := filerClient.WithFilerClient(true, makeSubscribeMetadataFunc(option, processEventFn))
if err != nil {
return fmt.Errorf("subscribing filer meta change: %v", err)
}
@@ -42,20 +55,20 @@ func WithFilerClientFollowMetadata(filerClient filer_pb.FilerClient, clientName
return nil
}
func makeSubscribeMetadataFunc(clientName string, clientId int32, clientEpoch int32, pathPrefix string, additionalPathPrefixes []string, directoriesToWatch []string, lastTsNs *int64, untilTsNs int64, selfSignature int32, processEventFn ProcessMetadataFunc, eventErrorType EventErrorType) func(client filer_pb.SeaweedFilerClient) error {
func makeSubscribeMetadataFunc(option *MetadataFollowOption, processEventFn ProcessMetadataFunc) func(client filer_pb.SeaweedFilerClient) error {
return func(client filer_pb.SeaweedFilerClient) error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
stream, err := client.SubscribeMetadata(ctx, &filer_pb.SubscribeMetadataRequest{
ClientName: clientName,
PathPrefix: pathPrefix,
PathPrefixes: additionalPathPrefixes,
Directories: directoriesToWatch,
SinceNs: *lastTsNs,
Signature: selfSignature,
ClientId: clientId,
ClientEpoch: clientEpoch,
UntilNs: untilTsNs,
ClientName: option.ClientName,
PathPrefix: option.PathPrefix,
PathPrefixes: option.AdditionalPathPrefixes,
Directories: option.DirectoriesToWatch,
SinceNs: option.StartTsNs,
Signature: option.SelfSignature,
ClientId: option.ClientId,
ClientEpoch: option.ClientEpoch,
UntilNs: option.StopTsNs,
})
if err != nil {
return fmt.Errorf("subscribe: %v", err)
@@ -71,7 +84,7 @@ func makeSubscribeMetadataFunc(clientName string, clientId int32, clientEpoch in
}
if err := processEventFn(resp); err != nil {
switch eventErrorType {
switch option.EventErrorType {
case TrivialOnError:
glog.Errorf("process %v: %v", resp, err)
case FatalOnError:
@@ -87,7 +100,7 @@ func makeSubscribeMetadataFunc(clientName string, clientId int32, clientEpoch in
glog.Errorf("process %v: %v", resp, err)
}
}
*lastTsNs = resp.TsNs
option.StartTsNs = resp.TsNs
}
}
}
+14 -2
View File
@@ -34,9 +34,21 @@ func (s3a *S3ApiServer) subscribeMetaEvents(clientName string, lastTsNs int64, p
}
var clientEpoch int32
metadataFollowOption := &pb.MetadataFollowOption{
ClientName: clientName,
ClientId: s3a.randomClientId,
ClientEpoch: clientEpoch,
SelfSignature: 0,
PathPrefix: prefix,
AdditionalPathPrefixes: nil,
DirectoriesToWatch: directoriesToWatch,
StartTsNs: lastTsNs,
StopTsNs: 0,
EventErrorType: pb.FatalOnError,
}
util.RetryForever("followIamChanges", func() error {
clientEpoch++
return pb.WithFilerClientFollowMetadata(s3a, clientName, s3a.randomClientId, clientEpoch, prefix, directoriesToWatch, &lastTsNs, 0, 0, processEventFn, pb.FatalOnError)
return pb.WithFilerClientFollowMetadata(s3a, metadataFollowOption, processEventFn)
}, func(err error) bool {
glog.V(0).Infof("iam follow metadata changes: %v", err)
return true
@@ -65,7 +77,7 @@ func (s3a *S3ApiServer) onCircuitBreakerConfigUpdate(dir, filename string, conte
return nil
}
//reload bucket metadata
// reload bucket metadata
func (s3a *S3ApiServer) onBucketMetadataChange(dir string, oldEntry *filer_pb.Entry, newEntry *filer_pb.Entry) error {
if dir == s3a.option.BucketsPath {
if newEntry != nil {
+1
View File
@@ -9,4 +9,5 @@ const (
SeaweedStorageDestinationHeader = "x-seaweedfs-destination"
MultipartUploadsFolder = ".uploads"
FolderMimeType = "httpd/unix-directory"
)
+1
View File
@@ -46,6 +46,7 @@ func (s3a *S3ApiServer) CopyObjectHandler(w http.ResponseWriter, r *http.Request
return
}
entry.Extended, err = processMetadataBytes(r.Header, entry.Extended, replaceMeta, replaceTagging)
entry.Attributes.Mtime = time.Now().Unix()
if err != nil {
glog.Errorf("CopyObjectHandler ValidateTags error %s: %v", r.URL, err)
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidTag)
+5 -2
View File
@@ -94,12 +94,15 @@ func (s3a *S3ApiServer) PutObjectHandler(w http.ResponseWriter, r *http.Request)
defer dataReader.Close()
objectContentType := r.Header.Get("Content-Type")
if strings.HasSuffix(object, "/") && r.ContentLength == 0 {
if strings.HasSuffix(object, "/") && r.ContentLength <= 1024 {
if err := s3a.mkdir(
s3a.option.BucketsPath, bucket+strings.TrimSuffix(object, "/"),
func(entry *filer_pb.Entry) {
if objectContentType == "" {
objectContentType = "httpd/unix-directory"
objectContentType = s3_constants.FolderMimeType
}
if r.ContentLength > 0 {
entry.Content, _ = io.ReadAll(r.Body)
}
entry.Attributes.Mime = objectContentType
}); err != nil {
+52 -29
View File
@@ -18,8 +18,6 @@ import (
"github.com/seaweedfs/seaweedfs/weed/s3api/s3err"
)
const cutoffTimeNewEmptyDir = 3
type ListBucketResultV2 struct {
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListBucketResult"`
Name string `xml:"Name"`
@@ -141,7 +139,8 @@ func (s3a *S3ApiServer) listFilerEntries(bucket string, originalPrefix string, m
var doErr error
var nextMarker string
cursor := &ListingCursor{
maxKeys: maxKeys,
maxKeys: maxKeys,
prefixEndsOnDelimiter: strings.HasSuffix(originalPrefix, "/") && len(originalMarker) == 0,
}
// check filer
@@ -151,14 +150,7 @@ func (s3a *S3ApiServer) listFilerEntries(bucket string, originalPrefix string, m
nextMarker, doErr = s3a.doListFilerEntries(client, reqDir, prefix, cursor, marker, delimiter, false, func(dir string, entry *filer_pb.Entry) {
empty = false
if entry.IsDirectory {
// https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html
if delimiter == "/" { // A response can contain CommonPrefixes only if you specify a delimiter.
commonPrefixes = append(commonPrefixes, PrefixEntry{
Prefix: fmt.Sprintf("%s/%s/", dir, entry.Name)[len(bucketPrefix):],
})
//All of the keys (up to 1,000) rolled up into a common prefix count as a single return when calculating the number of returns.
cursor.maxKeys--
} else if entry.IsDirectoryKeyObject() {
if entry.IsDirectoryKeyObject() {
contents = append(contents, ListEntry{
Key: fmt.Sprintf("%s/%s/", dir, entry.Name)[len(bucketPrefix):],
LastModified: time.Unix(entry.Attributes.Mtime, 0).UTC(),
@@ -170,6 +162,13 @@ func (s3a *S3ApiServer) listFilerEntries(bucket string, originalPrefix string, m
StorageClass: "STANDARD",
})
cursor.maxKeys--
// https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html
} else if delimiter == "/" { // A response can contain CommonPrefixes only if you specify a delimiter.
commonPrefixes = append(commonPrefixes, PrefixEntry{
Prefix: fmt.Sprintf("%s/%s/", dir, entry.Name)[len(bucketPrefix):],
})
//All of the keys (up to 1,000) rolled up into a common prefix count as a single return when calculating the number of returns.
cursor.maxKeys--
}
} else {
storageClass := "STANDARD"
@@ -199,7 +198,7 @@ func (s3a *S3ApiServer) listFilerEntries(bucket string, originalPrefix string, m
nextMarker = requestDir + "/" + nextMarker
}
break
} else if empty {
} else if empty || strings.HasSuffix(originalPrefix, "/") {
nextMarker = ""
break
} else {
@@ -227,8 +226,9 @@ func (s3a *S3ApiServer) listFilerEntries(bucket string, originalPrefix string, m
}
type ListingCursor struct {
maxKeys int
isTruncated bool
maxKeys int
isTruncated bool
prefixEndsOnDelimiter bool
}
// the prefix and marker may be in different directories
@@ -236,7 +236,11 @@ type ListingCursor struct {
func normalizePrefixMarker(prefix, marker string) (alignedDir, alignedPrefix, alignedMarker string) {
// alignedDir should not end with "/"
// alignedDir, alignedPrefix, alignedMarker should only have "/" in middle
prefix = strings.TrimLeft(prefix, "/")
if len(marker) == 0 {
prefix = strings.Trim(prefix, "/")
} else {
prefix = strings.TrimLeft(prefix, "/")
}
marker = strings.TrimLeft(marker, "/")
if prefix == "" {
return "", "", marker
@@ -264,6 +268,7 @@ func normalizePrefixMarker(prefix, marker string) (alignedDir, alignedPrefix, al
}
return
}
func toDirAndName(dirAndName string) (dir, name string) {
sepIndex := strings.LastIndex(dirAndName, "/")
if sepIndex >= 0 {
@@ -273,6 +278,7 @@ func toDirAndName(dirAndName string) (dir, name string) {
}
return
}
func toParentAndDescendants(dirAndName string) (dir, name string) {
sepIndex := strings.Index(dirAndName, "/")
if sepIndex >= 0 {
@@ -287,7 +293,7 @@ func (s3a *S3ApiServer) doListFilerEntries(client filer_pb.SeaweedFilerClient, d
// invariants
// prefix and marker should be under dir, marker may contain "/"
// maxKeys should be updated for each recursion
// glog.V(4).Infof("doListFilerEntries dir: %s, prefix: %s, marker %s, maxKeys: %d, prefixEndsOnDelimiter: %+v", dir, prefix, marker, cursor.maxKeys, cursor.prefixEndsOnDelimiter)
if prefix == "/" && delimiter == "/" {
return
}
@@ -319,6 +325,9 @@ func (s3a *S3ApiServer) doListFilerEntries(client filer_pb.SeaweedFilerClient, d
StartFromFileName: marker,
InclusiveStartFrom: inclusiveStartFrom,
}
if cursor.prefixEndsOnDelimiter {
request.Limit = uint32(1)
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
@@ -344,13 +353,29 @@ func (s3a *S3ApiServer) doListFilerEntries(client filer_pb.SeaweedFilerClient, d
}
entry := resp.Entry
nextMarker = entry.Name
if cursor.prefixEndsOnDelimiter {
if entry.Name == prefix && entry.IsDirectory {
if delimiter != "/" {
cursor.prefixEndsOnDelimiter = false
}
} else {
continue
}
}
if entry.IsDirectory {
// println("ListEntries", dir, "dir:", entry.Name)
// glog.V(4).Infof("List Dir Entries %s, file: %s, maxKeys %d", dir, entry.Name, cursor.maxKeys)
if entry.Name == s3_constants.MultipartUploadsFolder { // FIXME no need to apply to all directories. this extra also affects maxKeys
continue
}
if delimiter != "/" {
eachEntryFn(dir, entry)
if delimiter != "/" || cursor.prefixEndsOnDelimiter {
if cursor.prefixEndsOnDelimiter {
cursor.prefixEndsOnDelimiter = false
if entry.IsDirectoryKeyObject() {
eachEntryFn(dir, entry)
}
} else {
eachEntryFn(dir, entry)
}
subNextMarker, subErr := s3a.doListFilerEntries(client, dir+"/"+entry.Name, "", cursor, "", delimiter, false, eachEntryFn)
if subErr != nil {
err = fmt.Errorf("doListFilerEntries2: %v", subErr)
@@ -364,7 +389,7 @@ func (s3a *S3ApiServer) doListFilerEntries(client filer_pb.SeaweedFilerClient, d
// println("doListFilerEntries2 nextMarker", nextMarker)
} else {
var isEmpty bool
if !s3a.option.AllowEmptyFolder && !entry.IsDirectoryKeyObject() {
if !s3a.option.AllowEmptyFolder && entry.IsOlderDir() {
if isEmpty, err = s3a.ensureDirectoryAllEmpty(client, dir, entry.Name); err != nil {
glog.Errorf("check empty folder %s: %v", dir, err)
}
@@ -375,7 +400,10 @@ func (s3a *S3ApiServer) doListFilerEntries(client filer_pb.SeaweedFilerClient, d
}
} else {
eachEntryFn(dir, entry)
// println("ListEntries", dir, "file:", entry.Name, "maxKeys", cursor.maxKeys)
// glog.V(4).Infof("List File Entries %s, file: %s, maxKeys %d", dir, entry.Name, cursor.maxKeys)
}
if cursor.prefixEndsOnDelimiter {
cursor.prefixEndsOnDelimiter = false
}
}
return
@@ -417,16 +445,11 @@ func (s3a *S3ApiServer) ensureDirectoryAllEmpty(filerClient filer_pb.SeaweedFile
var startFrom string
var isExhausted bool
var foundEntry bool
cutOffTimeAtSec := time.Now().Unix() + cutoffTimeNewEmptyDir
for fileCounter == 0 && !isExhausted && err == nil {
err = filer_pb.SeaweedList(filerClient, currentDir, "", func(entry *filer_pb.Entry, isLast bool) error {
foundEntry = true
if entry.IsDirectory {
if entry.Attributes != nil && cutOffTimeAtSec >= entry.Attributes.GetCrtime() {
fileCounter++
} else {
subDirs = append(subDirs, entry.Name)
}
if entry.IsOlderDir() {
subDirs = append(subDirs, entry.Name)
} else {
fileCounter++
}
@@ -459,7 +482,7 @@ func (s3a *S3ApiServer) ensureDirectoryAllEmpty(filerClient filer_pb.SeaweedFile
}
glog.V(1).Infof("deleting empty folder %s", currentDir)
if err = doDeleteEntry(filerClient, parentDir, name, true, true); err != nil {
if err = doDeleteEntry(filerClient, parentDir, name, true, false); err != nil {
return
}
@@ -54,8 +54,8 @@ func Test_normalizePrefixMarker(t *testing.T) {
{"prefix is a directory",
args{"/parentDir/data/",
""},
"parentDir/data",
"",
"parentDir",
"data",
"",
},
{"normal case",
+11 -2
View File
@@ -15,6 +15,7 @@ import (
"path/filepath"
"strconv"
"strings"
"sync"
"time"
"google.golang.org/grpc"
@@ -30,6 +31,10 @@ import (
var serverStats *stats.ServerStats
var startTime = time.Now()
var writePool = sync.Pool{New: func() interface{} {
return bufio.NewWriterSize(nil, 128*1024)
},
}
func init() {
serverStats = stats.NewServerStats()
@@ -279,8 +284,12 @@ func adjustHeaderContentDisposition(w http.ResponseWriter, r *http.Request, file
func processRangeRequest(r *http.Request, w http.ResponseWriter, totalSize int64, mimeType string, writeFn func(writer io.Writer, offset int64, size int64) error) error {
rangeReq := r.Header.Get("Range")
bufferedWriter := bufio.NewWriterSize(w, 128*1024)
defer bufferedWriter.Flush()
bufferedWriter := writePool.Get().(*bufio.Writer)
bufferedWriter.Reset(w)
defer func() {
bufferedWriter.Flush()
writePool.Put(bufferedWriter)
}()
if rangeReq == "" {
w.Header().Set("Content-Length", strconv.FormatInt(totalSize, 10))
+2 -2
View File
@@ -19,7 +19,7 @@ func (fs *FilerServer) AtomicRenameEntry(ctx context.Context, req *filer_pb.Atom
oldParent := util.FullPath(filepath.ToSlash(req.OldDirectory))
newParent := util.FullPath(filepath.ToSlash(req.NewDirectory))
if err := fs.filer.CanRename(oldParent, newParent); err != nil {
if err := fs.filer.CanRename(oldParent, newParent, req.OldName); err != nil {
return nil, err
}
@@ -55,7 +55,7 @@ func (fs *FilerServer) StreamRenameEntry(req *filer_pb.StreamRenameEntryRequest,
oldParent := util.FullPath(filepath.ToSlash(req.OldDirectory))
newParent := util.FullPath(filepath.ToSlash(req.NewDirectory))
if err := fs.filer.CanRename(oldParent, newParent); err != nil {
if err := fs.filer.CanRename(oldParent, newParent, req.OldName); err != nil {
return err
}
+3 -4
View File
@@ -15,8 +15,6 @@ import (
"strings"
"time"
"golang.org/x/exp/slices"
"github.com/seaweedfs/seaweedfs/weed/filer"
"github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/images"
@@ -120,7 +118,8 @@ func (fs *FilerServer) GetOrHeadHandler(w http.ResponseWriter, r *http.Request)
writeJsonQuiet(w, r, http.StatusOK, entry)
return
}
if slices.Contains([]string{"httpd/unix-directory", ""}, entry.Attr.Mime) {
if entry.Attr.Mime == "" || (entry.Attr.Mime == s3_constants.FolderMimeType && r.Header.Get(s3_constants.AmzIdentityId) == "") {
// return index of directory for non s3 gateway
fs.listDirectoryHandler(w, r)
return
}
@@ -128,7 +127,7 @@ func (fs *FilerServer) GetOrHeadHandler(w http.ResponseWriter, r *http.Request)
w.Header().Set(s3_constants.X_SeaweedFS_Header_Directory_Key, "true")
}
if isForDirectory {
if isForDirectory && entry.Attr.Mime != s3_constants.FolderMimeType {
w.WriteHeader(http.StatusNotFound)
return
}
+11 -1
View File
@@ -87,6 +87,7 @@ func (fs *FilerServer) PostHandler(w http.ResponseWriter, r *http.Request, conte
query.Get("dataCenter"),
query.Get("rack"),
query.Get("dataNode"),
query.Get("saveInside"),
)
if err != nil {
if err == ErrReadOnly {
@@ -103,6 +104,10 @@ func (fs *FilerServer) PostHandler(w http.ResponseWriter, r *http.Request, conte
so.DiskType = fs.option.DiskType
}
if strings.HasPrefix(r.URL.Path, "/etc") {
so.SaveInside = true
}
if query.Has("mv.from") {
fs.move(ctx, w, r, so)
} else {
@@ -246,7 +251,7 @@ func (fs *FilerServer) detectStorageOption(requestURI, qCollection, qReplication
}, nil
}
func (fs *FilerServer) detectStorageOption0(requestURI, qCollection, qReplication string, qTtl string, diskType string, fsync string, dataCenter, rack, dataNode string) (*operation.StorageOption, error) {
func (fs *FilerServer) detectStorageOption0(requestURI, qCollection, qReplication string, qTtl string, diskType string, fsync string, dataCenter, rack, dataNode, saveInside string) (*operation.StorageOption, error) {
ttl, err := needle.ReadTTL(qTtl)
if err != nil {
@@ -260,6 +265,11 @@ func (fs *FilerServer) detectStorageOption0(requestURI, qCollection, qReplicatio
} else if fsync == "true" {
so.Fsync = true
}
if saveInside == "true" {
so.SaveInside = true
} else {
so.SaveInside = false
}
}
return so, err
@@ -1,6 +1,7 @@
package weed_server
import (
"bytes"
"context"
"fmt"
//"github.com/seaweedfs/seaweedfs/weed/s3api"
@@ -64,7 +65,6 @@ func (fs *FilerServer) autoChunk(ctx context.Context, w http.ResponseWriter, r *
}
func (fs *FilerServer) doPostAutoChunk(ctx context.Context, w http.ResponseWriter, r *http.Request, chunkSize int32, contentLength int64, so *operation.StorageOption) (filerResult *FilerPostResult, md5bytes []byte, replyerr error) {
multipartReader, multipartReaderErr := r.MultipartReader()
if multipartReaderErr != nil {
return nil, nil, multipartReaderErr
@@ -84,6 +84,15 @@ func (fs *FilerServer) doPostAutoChunk(ctx context.Context, w http.ResponseWrite
contentType = ""
}
if so.SaveInside {
buf := bufPool.Get().(*bytes.Buffer)
buf.Reset()
buf.ReadFrom(part1)
filerResult, replyerr = fs.saveMetaData(ctx, r, fileName, contentType, so, nil, nil, 0, buf.Bytes())
bufPool.Put(buf)
return
}
fileChunks, md5Hash, chunkOffset, err, smallContent := fs.uploadReaderToChunks(w, r, part1, chunkSize, fileName, contentType, contentLength, so)
if err != nil {
return nil, nil, err
-6
View File
@@ -309,13 +309,7 @@ func (ms *MasterServer) VolumeMarkReadonly(ctx context.Context, req *master_pb.V
replicaPlacement, _ := super_block.NewReplicaPlacementFromByte(byte(req.ReplicaPlacement))
vl := ms.Topo.GetVolumeLayout(req.Collection, replicaPlacement, needle.LoadTTLFromUint32(req.Ttl), types.ToDiskType(req.DiskType))
dataNodes := ms.Topo.Lookup(req.Collection, needle.VolumeId(req.VolumeId))
if req.IsReadonly {
for _, dn := range dataNodes {
if dn.Ip == req.Ip && dn.Port == int(req.Port) {
}
}
}
for _, dn := range dataNodes {
if dn.Ip == req.Ip && dn.Port == int(req.Port) {
if req.IsReadonly {
+1 -1
View File
@@ -316,7 +316,7 @@ func processEachCmd(reg *regexp.Regexp, line string, commandEnv *shell.CommandEn
for i := range args {
args[i] = strings.Trim(string(cmds[1+i]), "\"'")
}
cmd := strings.ToLower(cmds[0])
cmd := cmds[0]
for _, c := range shell.Commands {
if c.Name() == cmd {
+4
View File
@@ -121,6 +121,10 @@ func NewHashicorpRaftServer(option *RaftServerOption) (*RaftServer, error) {
c.LogLevel = "Error"
}
if err := raft.ValidateConfig(c); err != nil {
return nil, fmt.Errorf(`raft.ValidateConfig: %v`, err)
}
if option.RaftBootstrap {
os.RemoveAll(path.Join(s.dataDir, ldbFile))
os.RemoveAll(path.Join(s.dataDir, sdbFile))
+12 -4
View File
@@ -72,7 +72,7 @@ func (vs *VolumeServer) VolumeEcShardsGenerate(ctx context.Context, req *volume_
// write .vif files
if err := volume_info.SaveVolumeInfo(baseFileName+".vif", &volume_server_pb.VolumeInfo{Version: uint32(v.Version())}); err != nil {
return nil, fmt.Errorf("WriteEcFiles %s: %v", baseFileName, err)
return nil, fmt.Errorf("SaveVolumeInfo %s: %v", baseFileName, err)
}
shouldCleanup = false
@@ -408,7 +408,9 @@ func (vs *VolumeServer) VolumeEcShardsToVolume(ctx context.Context, req *volume_
glog.V(0).Infof("VolumeEcShardsToVolume: %v", req)
v, found := vs.store.FindEcVolume(needle.VolumeId(req.VolumeId))
// collect .ec00 ~ .ec09 files
shardFileNames := make([]string, erasure_coding.DataShardsCount)
v, found := vs.store.CollectEcShards(needle.VolumeId(req.VolumeId), shardFileNames)
if !found {
return nil, fmt.Errorf("ec volume %d not found", req.VolumeId)
}
@@ -417,6 +419,12 @@ func (vs *VolumeServer) VolumeEcShardsToVolume(ctx context.Context, req *volume_
return nil, fmt.Errorf("existing collection:%v unexpected input: %v", v.Collection, req.Collection)
}
for shardId := 0; shardId < erasure_coding.DataShardsCount; shardId++ {
if shardFileNames[shardId] == "" {
return nil, fmt.Errorf("ec volume %d missing shard %d", req.VolumeId, shardId)
}
}
dataBaseFileName, indexBaseFileName := v.DataBaseFileName(), v.IndexBaseFileName()
// calculate .dat file size
datFileSize, err := erasure_coding.FindDatFileSize(dataBaseFileName, indexBaseFileName)
@@ -425,8 +433,8 @@ func (vs *VolumeServer) VolumeEcShardsToVolume(ctx context.Context, req *volume_
}
// write .dat file from .ec00 ~ .ec09 files
if err := erasure_coding.WriteDatFile(dataBaseFileName, datFileSize); err != nil {
return nil, fmt.Errorf("WriteEcFiles %s: %v", dataBaseFileName, err)
if err := erasure_coding.WriteDatFile(dataBaseFileName, datFileSize, shardFileNames); err != nil {
return nil, fmt.Errorf("WriteDatFile %s: %v", dataBaseFileName, err)
}
// write .idx file from .ecx and .ecj files
+12 -1
View File
@@ -5,6 +5,7 @@ import (
"flag"
"fmt"
"io"
"regexp"
"strings"
"github.com/seaweedfs/seaweedfs/weed/filer"
@@ -51,7 +52,7 @@ func (c *commandFsConfigure) Do(args []string, commandEnv *CommandEnv, writer io
locationPrefix := fsConfigureCommand.String("locationPrefix", "", "path prefix, required to update the path-specific configuration")
collection := fsConfigureCommand.String("collection", "", "assign writes to this collection")
replication := fsConfigureCommand.String("replication", "", "assign writes with this replication")
ttl := fsConfigureCommand.String("ttl", "", "assign writes with this ttl")
ttl := fsConfigureCommand.String("ttl", "", "assign writes with this ttl (e.g., 1m, 1h, 1d, 1w, 1y)")
diskType := fsConfigureCommand.String("disk", "", "[hdd|ssd|<tag>] hard drive or solid state drive or any tag")
fsync := fsConfigureCommand.Bool("fsync", false, "fsync for the writes")
isReadOnly := fsConfigureCommand.Bool("readOnly", false, "disable writes")
@@ -102,6 +103,16 @@ func (c *commandFsConfigure) Do(args []string, commandEnv *CommandEnv, writer io
}
}
// check ttl
if *ttl != "" {
regex := "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)[mhdwMy]$"
match, _ := regexp.MatchString(regex, *ttl)
if !match {
return fmt.Errorf("ttl should be of the following format [1 to 255][unit] (e.g., 5m, 2h, 180d, 1w, 2y)")
}
}
// save it
if *isDelete {
fc.DeleteLocationConf(*locationPrefix)
+3
View File
@@ -182,6 +182,9 @@ func doSaveRemoteEntry(client filer_pb.SeaweedFilerClient, localDir string, exis
existingEntry.RemoteEntry = remoteEntry
existingEntry.Attributes.FileSize = uint64(remoteEntry.RemoteSize)
existingEntry.Attributes.Mtime = remoteEntry.RemoteMtime
existingEntry.Attributes.Md5 = nil
existingEntry.Chunks = nil
existingEntry.Content = nil
_, updateErr := client.UpdateEntry(context.Background(), &filer_pb.UpdateEntryRequest{
Directory: localDir,
Entry: existingEntry,
+1 -1
View File
@@ -54,7 +54,7 @@ func NewCommandEnv(options *ShellOptions) *CommandEnv {
MasterClient: wdclient.NewMasterClient(options.GrpcDialOption, *options.FilerGroup, pb.AdminShellClient, "", "", "", pb.ServerAddresses(*options.Masters).ToAddressMap()),
option: options,
}
ce.locker = exclusive_locks.NewExclusiveLocker(ce.MasterClient, "admin")
ce.locker = exclusive_locks.NewExclusiveLocker(ce.MasterClient, "shell")
return ce
}
@@ -0,0 +1,270 @@
package rclone_backend
import (
"context"
"fmt"
"github.com/rclone/rclone/fs/config/configfile"
"github.com/seaweedfs/seaweedfs/weed/util"
"io"
"os"
"time"
"github.com/google/uuid"
_ "github.com/rclone/rclone/backend/all"
"github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/accounting"
"github.com/rclone/rclone/fs/object"
"github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/pb/volume_server_pb"
"github.com/seaweedfs/seaweedfs/weed/storage/backend"
)
func init() {
backend.BackendStorageFactories["rclone"] = &RcloneBackendFactory{}
configfile.Install()
}
type RcloneBackendFactory struct {
}
func (factory *RcloneBackendFactory) StorageType() backend.StorageType {
return "rclone"
}
func (factory *RcloneBackendFactory) BuildStorage(configuration backend.StringProperties, configPrefix string, id string) (backend.BackendStorage, error) {
return newRcloneBackendStorage(configuration, configPrefix, id)
}
type RcloneBackendStorage struct {
id string
remoteName string
fs fs.Fs
}
func newRcloneBackendStorage(configuration backend.StringProperties, configPrefix string, id string) (s *RcloneBackendStorage, err error) {
s = &RcloneBackendStorage{}
s.id = id
s.remoteName = configuration.GetString(configPrefix + "remote_name")
ctx := context.TODO()
accounting.Start(ctx)
fsPath := fmt.Sprintf("%s:", s.remoteName)
s.fs, err = fs.NewFs(ctx, fsPath)
if err != nil {
glog.Errorf("failed to instantiate Rclone filesystem: %s", err)
return
}
glog.V(0).Infof("created backend storage rclone.%s for remote name %s", s.id, s.remoteName)
return
}
func (s *RcloneBackendStorage) ToProperties() map[string]string {
m := make(map[string]string)
m["remote_name"] = s.remoteName
return m
}
func (s *RcloneBackendStorage) NewStorageFile(key string, tierInfo *volume_server_pb.VolumeInfo) backend.BackendStorageFile {
f := &RcloneBackendStorageFile{
backendStorage: s,
key: key,
tierInfo: tierInfo,
}
return f
}
func (s *RcloneBackendStorage) CopyFile(f *os.File, fn func(progressed int64, percentage float32) error) (key string, size int64, err error) {
randomUuid, err := uuid.NewRandom()
if err != nil {
return key, 0, err
}
key = randomUuid.String()
glog.V(1).Infof("copy dat file of %s to remote rclone.%s as %s", f.Name(), s.id, key)
util.Retry("upload via Rclone", func() error {
size, err = uploadViaRclone(s.fs, f.Name(), key, fn)
return err
})
return
}
func uploadViaRclone(rfs fs.Fs, filename string, key string, fn func(progressed int64, percentage float32) error) (fileSize int64, err error) {
ctx := context.TODO()
file, err := os.Open(filename)
defer func(file *os.File) {
err := file.Close()
if err != nil {
return
}
}(file)
if err != nil {
return 0, err
}
stat, err := file.Stat()
if err != nil {
return 0, err
}
info := object.NewStaticObjectInfo(key, stat.ModTime(), stat.Size(), true, nil, rfs)
tr := accounting.NewStats(ctx).NewTransfer(info)
defer tr.Done(ctx, err)
acc := tr.Account(ctx, file)
pr := ProgressReader{acc: acc, tr: tr, fn: fn}
obj, err := rfs.Put(ctx, &pr, info)
if err != nil {
return 0, err
}
return obj.Size(), err
}
func (s *RcloneBackendStorage) DownloadFile(filename string, key string, fn func(progressed int64, percentage float32) error) (size int64, err error) {
glog.V(1).Infof("download dat file of %s from remote rclone.%s as %s", filename, s.id, key)
util.Retry("download via Rclone", func() error {
size, err = downloadViaRclone(s.fs, filename, key, fn)
return err
})
return
}
func downloadViaRclone(fs fs.Fs, filename string, key string, fn func(progressed int64, percentage float32) error) (fileSize int64, err error) {
ctx := context.TODO()
obj, err := fs.NewObject(ctx, key)
if err != nil {
return 0, err
}
rc, err := obj.Open(ctx)
defer func(rc io.ReadCloser) {
err := rc.Close()
if err != nil {
return
}
}(rc)
if err != nil {
return 0, err
}
file, err := os.Create(filename)
defer func(file *os.File) {
err := file.Close()
if err != nil {
return
}
}(file)
tr := accounting.NewStats(ctx).NewTransfer(obj)
defer tr.Done(ctx, err)
acc := tr.Account(ctx, rc)
pr := ProgressReader{acc: acc, tr: tr, fn: fn}
written, err := io.Copy(file, &pr)
if err != nil {
return 0, err
}
return written, nil
}
func (s *RcloneBackendStorage) DeleteFile(key string) (err error) {
glog.V(1).Infof("delete dat file %s from remote", key)
util.Retry("delete via Rclone", func() error {
err = deleteViaRclone(s.fs, key)
return err
})
return
}
func deleteViaRclone(fs fs.Fs, key string) (err error) {
ctx := context.TODO()
obj, err := fs.NewObject(ctx, key)
if err != nil {
return err
}
return obj.Remove(ctx)
}
type RcloneBackendStorageFile struct {
backendStorage *RcloneBackendStorage
key string
tierInfo *volume_server_pb.VolumeInfo
}
func (rcloneBackendStorageFile RcloneBackendStorageFile) ReadAt(p []byte, off int64) (n int, err error) {
ctx := context.TODO()
obj, err := rcloneBackendStorageFile.backendStorage.fs.NewObject(ctx, rcloneBackendStorageFile.key)
if err != nil {
return 0, err
}
opt := fs.RangeOption{Start: off, End: off + int64(len(p)) - 1}
rc, err := obj.Open(ctx, &opt)
defer func(rc io.ReadCloser) {
err := rc.Close()
if err != nil {
return
}
}(rc)
if err != nil {
return 0, err
}
return io.ReadFull(rc, p)
}
func (rcloneBackendStorageFile RcloneBackendStorageFile) WriteAt(p []byte, off int64) (n int, err error) {
panic("not implemented")
}
func (rcloneBackendStorageFile RcloneBackendStorageFile) Truncate(off int64) error {
panic("not implemented")
}
func (rcloneBackendStorageFile RcloneBackendStorageFile) Close() error {
return nil
}
func (rcloneBackendStorageFile RcloneBackendStorageFile) GetStat() (datSize int64, modTime time.Time, err error) {
files := rcloneBackendStorageFile.tierInfo.GetFiles()
if len(files) == 0 {
err = fmt.Errorf("remote file info not found")
return
}
datSize = int64(files[0].FileSize)
modTime = time.Unix(int64(files[0].ModifiedTime), 0)
return
}
func (rcloneBackendStorageFile RcloneBackendStorageFile) Name() string {
return rcloneBackendStorageFile.key
}
func (rcloneBackendStorageFile RcloneBackendStorageFile) Sync() error {
return nil
}
@@ -0,0 +1,19 @@
package rclone_backend
import "github.com/rclone/rclone/fs/accounting"
type ProgressReader struct {
acc *accounting.Account
tr *accounting.Transfer
fn func(progressed int64, percentage float32) error
}
func (pr *ProgressReader) Read(p []byte) (n int, err error) {
n, err = pr.acc.Read(p)
if err != nil {
return
}
snap := pr.tr.Snapshot()
err = pr.fn(snap.Bytes, 100*float32(snap.Bytes)/float32(snap.Size))
return
}
+16
View File
@@ -38,6 +38,22 @@ func (l *DiskLocation) DestroyEcVolume(vid needle.VolumeId) {
}
}
func (l *DiskLocation) CollectEcShards(vid needle.VolumeId, shardFileNames []string) (ecVolume *erasure_coding.EcVolume, found bool) {
l.ecVolumesLock.RLock()
defer l.ecVolumesLock.RUnlock()
ecVolume, found = l.ecVolumes[vid]
if !found {
return
}
for _, ecShard := range ecVolume.Shards {
if ecShard.ShardId < erasure_coding.ShardId(len(shardFileNames)) {
shardFileNames[ecShard.ShardId] = erasure_coding.EcShardFileName(ecVolume.Collection, l.Directory, int(ecVolume.VolumeId)) + erasure_coding.ToExt(int(ecShard.ShardId))
}
}
return
}
func (l *DiskLocation) FindEcShard(vid needle.VolumeId, shardId erasure_coding.ShardId) (*erasure_coding.EcVolumeShard, bool) {
l.ecVolumesLock.RLock()
defer l.ecVolumesLock.RUnlock()
+10 -4
View File
@@ -151,7 +151,7 @@ func iterateEcjFile(baseFileName string, processNeedleFn func(key types.NeedleId
}
// WriteDatFile generates .dat from from .ec00 ~ .ec09 files
func WriteDatFile(baseFileName string, datFileSize int64) error {
func WriteDatFile(baseFileName string, datFileSize int64, shardFileNames []string) error {
datFile, openErr := os.OpenFile(baseFileName+".dat", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
if openErr != nil {
@@ -161,13 +161,19 @@ func WriteDatFile(baseFileName string, datFileSize int64) error {
inputFiles := make([]*os.File, DataShardsCount)
defer func() {
for shardId := 0; shardId < DataShardsCount; shardId++ {
if inputFiles[shardId] != nil {
inputFiles[shardId].Close()
}
}
}()
for shardId := 0; shardId < DataShardsCount; shardId++ {
shardFileName := baseFileName + ToExt(shardId)
inputFiles[shardId], openErr = os.OpenFile(shardFileName, os.O_RDONLY, 0)
inputFiles[shardId], openErr = os.OpenFile(shardFileNames[shardId], os.O_RDONLY, 0)
if openErr != nil {
return openErr
}
defer inputFiles[shardId].Close()
}
for datFileSize >= DataShardsCount*ErasureCodingLargeBlockSize {
+11
View File
@@ -116,6 +116,17 @@ func (s *Store) FindEcVolume(vid needle.VolumeId) (*erasure_coding.EcVolume, boo
return nil, false
}
// shardFiles is a list of shard files, which is used to return the shard locations
func (s *Store) CollectEcShards(vid needle.VolumeId, shardFileNames []string) (ecVolume *erasure_coding.EcVolume, found bool) {
for _, location := range s.Locations {
if s, foundShards := location.CollectEcShards(vid, shardFileNames); foundShards {
ecVolume = s
found = true
}
}
return
}
func (s *Store) DestroyEcVolume(vid needle.VolumeId) {
for _, location := range s.Locations {
location.DestroyEcVolume(vid)
+1
View File
@@ -8,6 +8,7 @@ import (
"github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/pb/volume_server_pb"
_ "github.com/seaweedfs/seaweedfs/weed/storage/backend/rclone_backend"
_ "github.com/seaweedfs/seaweedfs/weed/storage/backend/s3_backend"
"github.com/seaweedfs/seaweedfs/weed/util"
)
+1
View File
@@ -4,6 +4,7 @@ import (
"github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/pb/volume_server_pb"
"github.com/seaweedfs/seaweedfs/weed/storage/backend"
_ "github.com/seaweedfs/seaweedfs/weed/storage/backend/rclone_backend"
_ "github.com/seaweedfs/seaweedfs/weed/storage/backend/s3_backend"
"github.com/seaweedfs/seaweedfs/weed/storage/needle"
"github.com/seaweedfs/seaweedfs/weed/storage/types"
+37 -6
View File
@@ -2,11 +2,12 @@ package topology
import (
"context"
"github.com/seaweedfs/seaweedfs/weed/pb"
"io"
"sync/atomic"
"time"
"github.com/seaweedfs/seaweedfs/weed/pb"
"google.golang.org/grpc"
"github.com/seaweedfs/seaweedfs/weed/storage/needle"
@@ -119,10 +120,10 @@ func (t *Topology) batchVacuumVolumeCompact(grpcDialOption grpc.DialOption, vl *
return isVacuumSuccess
}
func (t *Topology) batchVacuumVolumeCommit(grpcDialOption grpc.DialOption, vl *VolumeLayout, vid needle.VolumeId, locationlist *VolumeLocationList) bool {
func (t *Topology) batchVacuumVolumeCommit(grpcDialOption grpc.DialOption, vl *VolumeLayout, vid needle.VolumeId, vacuumLocationList, locationList *VolumeLocationList) bool {
isCommitSuccess := true
isReadOnly := false
for _, dn := range locationlist.list {
for _, dn := range vacuumLocationList.list {
glog.V(0).Infoln("Start Committing vacuum", vid, "on", dn.Url())
err := operation.WithVolumeServerClient(false, dn.ServerAddress(), grpcDialOption, func(volumeServerClient volume_server_pb.VolumeServerClient) error {
resp, err := volumeServerClient.VacuumVolumeCommit(context.Background(), &volume_server_pb.VacuumVolumeCommitRequest{
@@ -140,8 +141,38 @@ func (t *Topology) batchVacuumVolumeCommit(grpcDialOption grpc.DialOption, vl *V
glog.V(0).Infof("Complete Committing vacuum %d on %s", vid, dn.Url())
}
}
//we should check the status of all replicas
if len(locationList.list) > len(vacuumLocationList.list) {
for _, dn := range locationList.list {
isFound := false
for _, dnVaccum := range vacuumLocationList.list {
if dn.id == dnVaccum.id {
isFound = true
break
}
}
if !isFound {
err := operation.WithVolumeServerClient(false, dn.ServerAddress(), grpcDialOption, func(volumeServerClient volume_server_pb.VolumeServerClient) error {
resp, err := volumeServerClient.VolumeStatus(context.Background(), &volume_server_pb.VolumeStatusRequest{
VolumeId: uint32(vid),
})
if resp != nil && resp.IsReadOnly {
isReadOnly = true
}
return err
})
if err != nil {
glog.Errorf("Error when checking volume %d status on %s: %v", vid, dn.Url(), err)
//we mark volume read-only, since the volume state is unknown
isReadOnly = true
}
}
}
}
if isCommitSuccess {
for _, dn := range locationlist.list {
for _, dn := range vacuumLocationList.list {
vl.SetVolumeAvailable(dn, vid, isReadOnly)
}
}
@@ -226,11 +257,11 @@ func (t *Topology) vacuumOneVolumeId(grpcDialOption grpc.DialOption, volumeLayou
return
}
glog.V(2).Infof("check vacuum on collection:%s volume:%d", c.Name, vid)
glog.V(1).Infof("check vacuum on collection:%s volume:%d", c.Name, vid)
if vacuumLocationList, needVacuum := t.batchVacuumVolumeCheck(
grpcDialOption, vid, locationList, garbageThreshold); needVacuum {
if t.batchVacuumVolumeCompact(grpcDialOption, volumeLayout, vid, vacuumLocationList, preallocate) {
t.batchVacuumVolumeCommit(grpcDialOption, volumeLayout, vid, vacuumLocationList)
t.batchVacuumVolumeCommit(grpcDialOption, volumeLayout, vid, vacuumLocationList, locationList)
} else {
t.batchVacuumVolumeCleanup(grpcDialOption, volumeLayout, vid, vacuumLocationList)
}
+1 -1
View File
@@ -5,7 +5,7 @@ import (
)
var (
VERSION_NUMBER = fmt.Sprintf("%.02f", 3.44)
VERSION_NUMBER = fmt.Sprintf("%.02f", 3.48)
VERSION = sizeLimit + " " + VERSION_NUMBER
COMMIT = ""
)
+3 -1
View File
@@ -1059,11 +1059,13 @@ func (f *FlagSet) ParseEnv(environ []string) error {
}
envKey := strings.ToUpper(flag.Name)
if f.envPrefix != "" {
envKey = f.envPrefix + "_" + envKey
}
envKey = strings.Replace(envKey, "-", "_", -1)
envKey = strings.Replace(envKey, ".", "_", -1)
value, isSet := env[envKey]
if !isSet {
continue
+32
View File
@@ -32,6 +32,29 @@ func Retry(name string, job func() error) (err error) {
return err
}
func MultiRetry(name string, errList []string, job func() error) (err error) {
waitTime := time.Second
hasErr := false
for waitTime < RetryWaitTime {
err = job()
if err == nil {
if hasErr {
glog.V(0).Infof("retry %s successfully", name)
}
break
}
if containErr(err.Error(), errList) {
hasErr = true
glog.V(0).Infof("retry %s: err: %v", name, err)
} else {
break
}
time.Sleep(waitTime)
waitTime += waitTime / 2
}
return err
}
func RetryForever(name string, job func() error, onErrFn func(err error) (shouldContinue bool)) {
waitTime := time.Second
for {
@@ -62,3 +85,12 @@ func Nvl(values ...string) string {
}
return ""
}
func containErr(err string, errList []string) bool {
for _, e := range errList {
if strings.Contains(err, e) {
return true
}
}
return false
}
+1
View File
@@ -119,6 +119,7 @@ func (mc *MasterClient) WaitUntilConnected() {
return
}
time.Sleep(time.Duration(rand.Int31n(200)) * time.Millisecond)
print(".")
}
}