diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.forgejo/ISSUE_TEMPLATE/bug_report.md similarity index 100% rename from .github/ISSUE_TEMPLATE/bug_report.md rename to .forgejo/ISSUE_TEMPLATE/bug_report.md diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.forgejo/ISSUE_TEMPLATE/config.yml similarity index 100% rename from .github/ISSUE_TEMPLATE/config.yml rename to .forgejo/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.forgejo/ISSUE_TEMPLATE/feature_request.md similarity index 100% rename from .github/ISSUE_TEMPLATE/feature_request.md rename to .forgejo/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/logo.svg b/.forgejo/logo.svg similarity index 100% rename from .github/logo.svg rename to .forgejo/logo.svg diff --git a/.github/markdown.tmpl b/.forgejo/markdown.tmpl similarity index 100% rename from .github/markdown.tmpl rename to .forgejo/markdown.tmpl diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 29c4211..0000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @alexvanin @realloc @fyrchik @anatoly-bogatyrev diff --git a/.github/workflows/buf.yml b/.github/workflows/buf.yml deleted file mode 100644 index 5d9d740..0000000 --- a/.github/workflows/buf.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Buf lint - -on: - pull_request: - branches: - - master - -jobs: - lint: - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v2 - - uses: wizhi/setup-buf@v1 - with: - version: 0.20.5 - - run: buf check lint - - breaking: - runs-on: ubuntu-20.04 - steps: - - name: Setup buf - uses: wizhi/setup-buf@v1 - with: - version: 0.20.5 - - name: Check out ref code - uses: actions/checkout@v2 - with: - ref: ${{ github.base_ref }} - path: baseref - - run: cd baseref && buf image build -o image.bin - - - name: Check out code - uses: actions/checkout@v2 - with: - path: prclone - - run: cd prclone && buf check breaking --against-input ../baseref/image.bin diff --git a/.github/workflows/dco.yml b/.github/workflows/dco.yml deleted file mode 100644 index 40ed8fc..0000000 --- a/.github/workflows/dco.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: DCO check - -on: - pull_request: - branches: - - master - -jobs: - commits_check_job: - runs-on: ubuntu-latest - name: Commits Check - steps: - - name: Get PR Commits - id: 'get-pr-commits' - uses: tim-actions/get-pr-commits@master - with: - token: ${{ secrets.GITHUB_TOKEN }} - - name: DCO Check - uses: tim-actions/dco@master - with: - commits: ${{ steps.get-pr-commits.outputs.commits }} diff --git a/CHANGELOG.md b/CHANGELOG.md index c934954..f08b065 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## [3.0] - 2024-10-08 - Potanin Glacier +## [3.0] - 2025-04-21 - Potanin Glacier ### Added - Version compatibility information diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..854e751 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,3 @@ +.* @alexvanin @realloc @fyrchik @a.bogatyrev @TrueCloudLab/storage-sdk-developers +.forgejo/.* @potyarkin +Makefile @potyarkin diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 578b067..c6c741f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -94,7 +94,7 @@ $ git push origin feature/123-something_awesome ``` ### Create a Pull Request -Pull requests can be created via GitHub. Refer to [this +Pull requests can be created via git.frostfs.info. Refer to [this document](https://help.github.com/articles/creating-a-pull-request/) for detailed steps on how to create a pull request. After a Pull Request gets peer reviewed and approved, it will be merged. diff --git a/Makefile b/Makefile index 88298c0..ce1170b 100755 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ doc: @for f in `find . -type f -name '*.proto' -exec dirname {} \; | sort -u `; do \ echo "⇒ Documentation for $$(basename $$f)"; \ protoc \ - --doc_opt=.github/markdown.tmpl,$${f}.md \ + --doc_opt=.forgejo/markdown.tmpl,$${f}.md \ --proto_path=.:/usr/local/include \ --doc_out=proto-docs/ $${f}/*.proto; \ done diff --git a/README.md b/README.md index 561995d..5447b7b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

-FrostFS +FrostFS

FrostFS API language-agnostic protocol definitions diff --git a/accounting/service.proto b/accounting/service.proto index b5fc7e9..d090406 100644 --- a/accounting/service.proto +++ b/accounting/service.proto @@ -1,4 +1,4 @@ -syntax = "proto3"; +edition = "2023"; package frost.fs.accounting; diff --git a/accounting/types.proto b/accounting/types.proto index 8431070..a07f9ba 100644 --- a/accounting/types.proto +++ b/accounting/types.proto @@ -1,4 +1,4 @@ -syntax = "proto3"; +edition = "2023"; package frost.fs.accounting; diff --git a/acl/types.proto b/acl/types.proto index 2b50cf5..cab7af0 100644 --- a/acl/types.proto +++ b/acl/types.proto @@ -1,4 +1,4 @@ -syntax = "proto3"; +edition = "2023"; package frost.fs.acl; diff --git a/ape/types.proto b/ape/types.proto index c512d26..cc21530 100644 --- a/ape/types.proto +++ b/ape/types.proto @@ -1,4 +1,4 @@ -syntax = "proto3"; +edition = "2023"; package frost.fs.ape; diff --git a/apemanager/service.proto b/apemanager/service.proto index 70a3d05..141563b 100644 --- a/apemanager/service.proto +++ b/apemanager/service.proto @@ -1,4 +1,4 @@ -syntax = "proto3"; +edition = "2023"; package frost.fs.apemanager; diff --git a/compatibility/container.json b/compatibility/container.json index 85f3a2f..0591862 100644 --- a/compatibility/container.json +++ b/compatibility/container.json @@ -19,6 +19,11 @@ "v3.0": { "compatibility": "SUPPORTED" } + }, + "ListStream": { + "v3.0": { + "compatibility": "SUPPORTED" + } } } } diff --git a/container/service.proto b/container/service.proto index 336b209..9f84eaa 100644 --- a/container/service.proto +++ b/container/service.proto @@ -1,4 +1,4 @@ -syntax = "proto3"; +edition = "2023"; package frost.fs.container; @@ -49,7 +49,7 @@ service ContainerService { // access to container is denied. rpc Get(GetRequest) returns (GetResponse); - // Returns all owner's containers from 'Container` smart contract' storage. + // Returns all owner's containers from `Container` smart contract storage. // // Statuses: // - **OK** (0, SECTION_SUCCESS): \ @@ -58,6 +58,17 @@ service ContainerService { // - **CONTAINER_ACCESS_DENIED** (3074, SECTION_CONTAINER): \ // container list access denied. rpc List(ListRequest) returns (ListResponse); + + // Returns all owner's containers from `Container` smart contract storage + // via stream. + // + // Statuses: + // - **OK** (0, SECTION_SUCCESS): \ + // container list has been successfully read; + // - Common failures (SECTION_FAILURE_COMMON); + // - **CONTAINER_ACCESS_DENIED** (3074, SECTION_CONTAINER): \ + // container list access denied. + rpc ListStream(ListStreamRequest) returns (stream ListStreamResponse); } // New FrostFS Container creation request @@ -242,3 +253,44 @@ message ListResponse { // transmission. frost.fs.session.ResponseVerificationHeader verify_header = 3; } + +// List containers stream +message ListStreamRequest { + // List containers stream request body. + message Body { + // Identifier of the container owner. + frost.fs.refs.OwnerID owner_id = 1; + } + // Body of list containers stream request message. + Body body = 1; + + // Carries request meta information. Header data is used only to regulate + // message transport and does not affect request execution. + frost.fs.session.RequestMetaHeader meta_header = 2; + + // Carries request verification information. This header is used to + // authenticate the nodes of the message route and check the correctness of + // transmission. + frost.fs.session.RequestVerificationHeader verify_header = 3; +} + +// List containers stream +message ListStreamResponse { + // List containers stream response body. + message Body { + // List of `ContainerID`s belonging to the requested `OwnerID` + repeated refs.ContainerID container_ids = 1; + } + + // Body of list containers stream response message. + Body body = 1; + + // Carries response meta information. Header data is used only to regulate + // message transport and does not affect request execution. + frost.fs.session.ResponseMetaHeader meta_header = 2; + + // Carries response verification information. This header is used to + // authenticate the nodes of the message route and check the correctness of + // transmission. + frost.fs.session.ResponseVerificationHeader verify_header = 3; +} diff --git a/container/types.proto b/container/types.proto index 038ebb6..8d80cd8 100644 --- a/container/types.proto +++ b/container/types.proto @@ -1,4 +1,4 @@ -syntax = "proto3"; +edition = "2023"; package frost.fs.container; diff --git a/doc/release_instructions.md b/doc/release_instructions.md index c3fee48..ec229ca 100644 --- a/doc/release_instructions.md +++ b/doc/release_instructions.md @@ -22,7 +22,7 @@ Add an entry to the CHANGELOG.md following the style established there. Add a codename for releases with the new major version, version and release date in the heading. Write a paragraph describing the most significant changes done in this release. Then add sections with what has been added, changed and removed, -describing each change briefly with a reference to GitHub issues, where +describing each change briefly with a reference to issues, where available. ## Release commit @@ -40,7 +40,7 @@ Release v3.0 - Anmyeondo (안면도, 安眠島) Use `vX.Y` tag (milestone version with patch). For pre-release versions use `vX.Y-rc.N` scheme. -## Push changes and release tag to Github +## Push changes and release tag to repository This step should bypass the default PR mechanism to get a correct result (so that releasing requires admin privileges for the project), both the `master` @@ -50,9 +50,9 @@ branch update and tag must be pushed simultaneously like this: $ git push origin master v2.7 ``` -## Make a proper Github release +## Make a proper release -Edit an automatically-created release on Github. +Edit an automatically-created release on git.frostfs.info Release title has to follow ` ( )` scheme for major releases and just `` for regular point @@ -60,5 +60,5 @@ releases. ## Post-release actions -* Close corresponding X.Y Github milestone +* Close corresponding X.Y milestone * Make announcements in Matrix and Discord channels diff --git a/lock/types.proto b/lock/types.proto index 307c199..6eb1175 100644 --- a/lock/types.proto +++ b/lock/types.proto @@ -1,4 +1,4 @@ -syntax = "proto3"; +edition = "2023"; package frost.fs.lock; diff --git a/netmap/service.proto b/netmap/service.proto index 889e1ff..a0642d9 100644 --- a/netmap/service.proto +++ b/netmap/service.proto @@ -1,4 +1,4 @@ -syntax = "proto3"; +edition = "2023"; package frost.fs.netmap; diff --git a/netmap/types.proto b/netmap/types.proto index 5964090..5576979 100644 --- a/netmap/types.proto +++ b/netmap/types.proto @@ -1,4 +1,4 @@ -syntax = "proto3"; +edition = "2023"; package frost.fs.netmap; diff --git a/object/service.proto b/object/service.proto index b0529bb..7e7331e 100644 --- a/object/service.proto +++ b/object/service.proto @@ -1,4 +1,4 @@ -syntax = "proto3"; +edition = "2023"; package frost.fs.object; @@ -116,6 +116,9 @@ service ObjectService { // returned. If `main_only` request field is set, the short header with only // the very minimal information will be returned instead. // + // Max header size is currently not limited by this API, but may be restricted + // on the service level. By default, gRPC uses a message size of 4 MiB. + // // Extended headers can change `Head` behaviour: // * [ __SYSTEM__NETMAP_EPOCH ] \ // Will use the requested version of Network Map for object placement @@ -554,6 +557,7 @@ message HeadResponse { ShortHeader short_header = 2; // Meta information of split hierarchy. + // Indicates that the object is virtual, manual assembly is required. SplitInfo split_info = 3; // Meta information for EC object assembly. @@ -871,6 +875,10 @@ message PatchRequest { // key, then it just replaces it while merging the lists. bool replace_attributes = 3; + // New split header for the object. This defines how the object will relate + // to other objects in a split operation. + frost.fs.object.Header.Split new_split_header = 5; + // The patch for the object's payload. message Patch { // The range of the source object for which the payload is replaced by the diff --git a/object/types.proto b/object/types.proto index 0d11a49..3fbb862 100644 --- a/object/types.proto +++ b/object/types.proto @@ -1,4 +1,4 @@ -syntax = "proto3"; +edition = "2023"; package frost.fs.object; @@ -132,7 +132,8 @@ message Header { // * Name \ // Human-friendly name // * FileName \ - // File name to be associated with the object on saving + // File name to be associated with the object on saving. FileName must not + // contain the delimiting symbol '/'. // * FilePath \ // Full path to be associated with the object on saving. Should start with a // '/' and use '/' as a delimiting symbol. Trailing '/' should be diff --git a/proto-docs/container.md b/proto-docs/container.md index 81bcd42..acc6ca9 100644 --- a/proto-docs/container.md +++ b/proto-docs/container.md @@ -20,6 +20,10 @@ - [ListRequest.Body](#frost.fs.container.ListRequest.Body) - [ListResponse](#frost.fs.container.ListResponse) - [ListResponse.Body](#frost.fs.container.ListResponse.Body) + - [ListStreamRequest](#frost.fs.container.ListStreamRequest) + - [ListStreamRequest.Body](#frost.fs.container.ListStreamRequest.Body) + - [ListStreamResponse](#frost.fs.container.ListStreamResponse) + - [ListStreamResponse.Body](#frost.fs.container.ListStreamResponse.Body) - [PutRequest](#frost.fs.container.PutRequest) - [PutRequest.Body](#frost.fs.container.PutRequest.Body) - [PutResponse](#frost.fs.container.PutResponse) @@ -58,6 +62,7 @@ rpc Put(PutRequest) returns (PutResponse); rpc Delete(DeleteRequest) returns (DeleteResponse); rpc Get(GetRequest) returns (GetResponse); rpc List(ListRequest) returns (ListResponse); +rpc ListStream(ListStreamRequest) returns (stream ListStreamResponse); ``` @@ -113,7 +118,7 @@ Statuses: | Get | [GetRequest](#frost.fs.container.GetRequest) | [GetResponse](#frost.fs.container.GetResponse) | #### Method List -Returns all owner's containers from 'Container` smart contract' storage. +Returns all owner's containers from `Container` smart contract storage. Statuses: - **OK** (0, SECTION_SUCCESS): \ @@ -125,6 +130,21 @@ Statuses: | Name | Input | Output | | ---- | ----- | ------ | | List | [ListRequest](#frost.fs.container.ListRequest) | [ListResponse](#frost.fs.container.ListResponse) | +#### Method ListStream + +Returns all owner's containers from `Container` smart contract storage +via stream. + +Statuses: +- **OK** (0, SECTION_SUCCESS): \ + container list has been successfully read; +- Common failures (SECTION_FAILURE_COMMON); +- **CONTAINER_ACCESS_DENIED** (3074, SECTION_CONTAINER): \ + container list access denied. + +| Name | Input | Output | +| ---- | ----- | ------ | +| ListStream | [ListStreamRequest](#frost.fs.container.ListStreamRequest) | [ListStreamResponse](#frost.fs.container.ListStreamResponse) | @@ -276,6 +296,54 @@ List containers response body. | container_ids | [frost.fs.refs.ContainerID](#frost.fs.refs.ContainerID) | repeated | List of `ContainerID`s belonging to the requested `OwnerID` | + + +### Message ListStreamRequest +List containers stream + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| body | [ListStreamRequest.Body](#frost.fs.container.ListStreamRequest.Body) | | Body of list containers stream request message. | +| meta_header | [frost.fs.session.RequestMetaHeader](#frost.fs.session.RequestMetaHeader) | | Carries request meta information. Header data is used only to regulate message transport and does not affect request execution. | +| verify_header | [frost.fs.session.RequestVerificationHeader](#frost.fs.session.RequestVerificationHeader) | | Carries request verification information. This header is used to authenticate the nodes of the message route and check the correctness of transmission. | + + + + +### Message ListStreamRequest.Body +List containers stream request body. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| owner_id | [frost.fs.refs.OwnerID](#frost.fs.refs.OwnerID) | | Identifier of the container owner. | + + + + +### Message ListStreamResponse +List containers stream + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| body | [ListStreamResponse.Body](#frost.fs.container.ListStreamResponse.Body) | | Body of list containers stream response message. | +| meta_header | [frost.fs.session.ResponseMetaHeader](#frost.fs.session.ResponseMetaHeader) | | Carries response meta information. Header data is used only to regulate message transport and does not affect request execution. | +| verify_header | [frost.fs.session.ResponseVerificationHeader](#frost.fs.session.ResponseVerificationHeader) | | Carries response verification information. This header is used to authenticate the nodes of the message route and check the correctness of transmission. | + + + + +### Message ListStreamResponse.Body +List containers stream response body. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| container_ids | [frost.fs.refs.ContainerID](#frost.fs.refs.ContainerID) | repeated | List of `ContainerID`s belonging to the requested `OwnerID` | + + ### Message PutRequest diff --git a/proto-docs/object.md b/proto-docs/object.md index 830de94..439159f 100644 --- a/proto-docs/object.md +++ b/proto-docs/object.md @@ -218,6 +218,9 @@ Returns the object Headers without data payload. By default full header is returned. If `main_only` request field is set, the short header with only the very minimal information will be returned instead. +Max header size is currently not limited by this API, but may be restricted +on the service level. By default, gRPC uses a message size of 4 MiB. + Extended headers can change `Head` behaviour: * [ __SYSTEM__NETMAP_EPOCH ] \ Will use the requested version of Network Map for object placement @@ -715,7 +718,7 @@ Object HEAD response body | ----- | ---- | ----- | ----------- | | header | [HeaderWithSignature](#frost.fs.object.HeaderWithSignature) | | Full object's `Header` with `ObjectID` signature | | short_header | [ShortHeader](#frost.fs.object.ShortHeader) | | Short object header | -| split_info | [SplitInfo](#frost.fs.object.SplitInfo) | | Meta information of split hierarchy. | +| split_info | [SplitInfo](#frost.fs.object.SplitInfo) | | Meta information of split hierarchy. Indicates that the object is virtual, manual assembly is required. | | ec_info | [ECInfo](#frost.fs.object.ECInfo) | | Meta information for EC object assembly. | @@ -763,6 +766,7 @@ PATCH request body | replace_attributes | [bool](#bool) | | If this flag is set, then the object's attributes will be entirely replaced by `new_attributes` list. The empty `new_attributes` list with `replace_attributes = true` just resets attributes list for the object. Default `false` value for this flag means the attributes will be just merged. If the incoming `new_attributes` list contains already existing key, then it just replaces it while merging the lists. | +| new_split_header | [Header.Split](#frost.fs.object.Header.Split) | | New split header for the object. This defines how the object will relate to other objects in a split operation. | | patch | [PatchRequest.Body.Patch](#frost.fs.object.PatchRequest.Body.Patch) | | The patch that is applied for the object. | @@ -1133,7 +1137,8 @@ And some well-known attributes used by applications only: * Name \ Human-friendly name * FileName \ - File name to be associated with the object on saving + File name to be associated with the object on saving. FileName must not + contain the delimiting symbol '/'. * FilePath \ Full path to be associated with the object on saving. Should start with a '/' and use '/' as a delimiting symbol. Trailing '/' should be diff --git a/proto-docs/status.md b/proto-docs/status.md index dc94d48..95c0cfc 100644 --- a/proto-docs/status.md +++ b/proto-docs/status.md @@ -102,6 +102,7 @@ Section of failed statuses independent of the operation. | SIGNATURE_VERIFICATION_FAIL | 2 | [**1026**] Signature verification failure. | | NODE_UNDER_MAINTENANCE | 3 | [**1027**] Node is under maintenance. | | INVALID_ARGUMENT | 4 | [**1028**] Invalid argument error. If the server fails on validation of a request parameter as the client sent it incorrectly, then this code should be used. | +| RESOURCE_EXHAUSTED | 5 | [**1029**] Resource exhausted failure. This code should be used if the operation cannot be performed due to a lack of resources. | diff --git a/refs/types.proto b/refs/types.proto index edac5ff..62e56c7 100644 --- a/refs/types.proto +++ b/refs/types.proto @@ -1,4 +1,4 @@ -syntax = "proto3"; +edition = "2023"; package frost.fs.refs; diff --git a/session/service.proto b/session/service.proto index 7874444..df7fa5f 100644 --- a/session/service.proto +++ b/session/service.proto @@ -1,4 +1,4 @@ -syntax = "proto3"; +edition = "2023"; package frost.fs.session; diff --git a/session/types.proto b/session/types.proto index 50b91d5..0075841 100644 --- a/session/types.proto +++ b/session/types.proto @@ -1,4 +1,4 @@ -syntax = "proto3"; +edition = "2023"; package frost.fs.session; diff --git a/status/types.proto b/status/types.proto index 29e4e6e..dfbadea 100644 --- a/status/types.proto +++ b/status/types.proto @@ -1,4 +1,4 @@ -syntax = "proto3"; +edition = "2023"; package frost.fs.status; @@ -106,6 +106,10 @@ enum CommonFail { // request parameter as the client sent it incorrectly, then this code should // be used. INVALID_ARGUMENT = 4; + + // [**1029**] Resource exhausted failure. This code should be used + // if the operation cannot be performed due to a lack of resources. + RESOURCE_EXHAUSTED = 5; } // Section of statuses for object-related operations. diff --git a/tombstone/types.proto b/tombstone/types.proto index 70ffac3..4d8402a 100644 --- a/tombstone/types.proto +++ b/tombstone/types.proto @@ -1,4 +1,4 @@ -syntax = "proto3"; +edition = "2023"; package frost.fs.tombstone; diff --git a/version.json b/version.json index 118bee4..dc3d1af 100644 --- a/version.json +++ b/version.json @@ -1,5 +1,5 @@ { "milestone": 3, "patch": 0, - "date": "2024-10-08" + "date": "2025-04-21" }