Compare commits
214 commits
master
...
fix/panic-
Author | SHA1 | Date | |
---|---|---|---|
|
c60029d3b0 | ||
|
0beb7ccf5c | ||
0fe5e34fb0 | |||
bcf3f0f517 | |||
79d59e4ed2 | |||
364b4ac572 | |||
f7679a8168 | |||
2dc2fe8780 | |||
21412ef24a | |||
7d39fecc6a | |||
04727ce1d6 | |||
08769f413f | |||
5d2affa5cd | |||
5778980252 | |||
b2ca730547 | |||
0920d848d0 | |||
5af9f58469 | |||
72565a91ef | |||
c4865783fc | |||
6ad5c38225 | |||
c85a0bc866 | |||
6bf11f7cca | |||
2c07f831c7 | |||
93eba19a8e | |||
2ed9fd3f94 | |||
ccf8463e69 | |||
ae86cda58c | |||
6016d78a45 | |||
02831d427b | |||
38ae71cc7d | |||
b689027d57 | |||
0b9622c418 | |||
dbc3811ff4 | |||
cb172e73a6 | |||
c236b54a65 | |||
7ebbfa3358 | |||
469e8a6e59 | |||
e2f13d03d7 | |||
e8d340287f | |||
3dbff0a478 | |||
fe87735073 | |||
d07e40d6fe | |||
775179f823 | |||
e815b19101 | |||
56282edf02 | |||
9027695371 | |||
4ec69cbbf8 | |||
f32f61df87 | |||
8908798f59 | |||
bab11492ad | |||
e21c5bea21 | |||
68a2f36636 | |||
9e2df4b7c7 | |||
ab891517de | |||
c58ab0c369 | |||
89924071cd | |||
6c7b708a98 | |||
b0786d2e5c | |||
f889893216 | |||
91ead04fa4 | |||
1bf21dbb47 | |||
206458c841 | |||
279261ace3 | |||
6f7b6a8813 | |||
d6486d172e | |||
080be5cfcd | |||
23575e1ac0 | |||
9098d0eec0 | |||
760af6b912 | |||
d85703a963 | |||
0b38419fbf | |||
5f2a1531fe | |||
4941926c9d | |||
585415fa92 | |||
9ef790f782 | |||
cd33a57f44 | |||
1f1aed87be | |||
5a66db80c5 | |||
456bc097f7 | |||
3010ca2649 | |||
0739c36a3b | |||
8273a3dfb2 | |||
594b5821ed | |||
ee7468daa7 | |||
49cc23e03c | |||
e85e5382e4 | |||
8e5a0dcf27 | |||
0948a280fa | |||
ece6c820e7 | |||
27bdddc48f | |||
cecea8053a | |||
14d894178e | |||
|
a69c6d1ec9 | ||
|
2bdf7126b8 | ||
|
aa92f977ef | ||
|
f09ee27af9 | ||
|
db5321309d | ||
|
44d5412e10 | ||
ed28ce24cd | |||
1f929fdd57 | |||
dd572825c7 | |||
56161d39b4 | |||
28dc9e2190 | |||
dcd39f8fdd | |||
c94372e6f9 | |||
3bbb516528 | |||
a7c79c773a | |||
8426d25f4b | |||
c1cbe6ff2d | |||
aeb4bbc51e | |||
30c18d46cc | |||
6be2688fb4 | |||
4d160bd4ab | |||
c8a6978563 | |||
85fb9e77c4 | |||
7be5a0fd79 | |||
ab32067152 | |||
9f0bce5c15 | |||
341fe1688f | |||
|
e843e7f090 | ||
|
ba58a77f8c | ||
|
3646723ae3 | ||
|
97e201993b | ||
221203beeb | |||
91717d4b98 | |||
382ecae96a | |||
9e54646248 | |||
bf7d80f44b | |||
5bf1ec348f | |||
93cb9e3a94 | |||
512b72591a | |||
e1b99dacad | |||
92f8810970 | |||
b0fefcb21f | |||
d62b11f5e7 | |||
ecbc211016 | |||
5f7d70c59c | |||
9534ade716 | |||
f2e880465e | |||
04b3d9d068 | |||
1d5f2dd681 | |||
c2cf708e0e | |||
c78e9cc857 | |||
|
3c7ed21f74 | ||
a5ece7889d | |||
|
f3ff9fd251 | ||
|
533e9f8b75 | ||
9ffa0d8fea | |||
d857ffeb2e | |||
|
34329d67ff | ||
9808dec591 | |||
342e571d89 | |||
f111704ceb | |||
|
da8da1c63a | ||
49234b915e | |||
1637a3edce | |||
cbc2efb1d6 | |||
484ac502ca | |||
8014fdb21a | |||
fb13902db9 | |||
3f6b962349 | |||
5368c4207a | |||
47e8c5bf23 | |||
ec2c5d45b4 | |||
7eb9e88f8f | |||
9aeea0b974 | |||
|
9a4f40626c | ||
7a31988a36 | |||
5059dcc19d | |||
6c4a1699ef | |||
|
9cd8f7cea0 | ||
44b86bac5a | |||
481a1ca6f3 | |||
97c36ed3ec | |||
cc8ff015b4 | |||
2dc86058c3 | |||
573d920821 | |||
d64fb887ff | |||
392be818e5 | |||
db3ccd2762 | |||
|
abd21f8099 | ||
|
10c419adf0 | ||
b70caa216b | |||
|
64bde68fb9 | ||
|
f006f3b342 | ||
22be532cbd | |||
724debfdcd | |||
b1c165a93b | |||
ac0a278a05 | |||
b8e93d4c08 | |||
07de839f18 | |||
2886b1581b | |||
8b9e40a848 | |||
b4582239bf | |||
4e244686cf | |||
6cd806f998 | |||
3e6fd4c611 | |||
5ae4446280 | |||
5890cd4d7d | |||
365adb4ebd | |||
bce5827f64 | |||
05471d3827 | |||
8226d49376 | |||
0893689c6a | |||
a4931ea4c7 | |||
861e9ab59a | |||
|
24a540caa8 | ||
6226c3ba86 | |||
f2250a316f | |||
9929dcf50b | |||
7486c02bbc | |||
|
f1f3c80dbf | ||
|
381e363a8b | ||
20de74a505 |
930 changed files with 15482 additions and 11609 deletions
25
.docker/Dockerfile.ci
Normal file
25
.docker/Dockerfile.ci
Normal file
|
@ -0,0 +1,25 @@
|
|||
FROM golang:1.19
|
||||
|
||||
WORKDIR /tmp
|
||||
|
||||
# Install apt packages
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||
pip \
|
||||
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Dash → Bash
|
||||
RUN echo "dash dash/sh boolean false" | debconf-set-selections
|
||||
RUN DEBIAN_FRONTEND=noninteractive dpkg-reconfigure dash
|
||||
|
||||
RUN useradd -u 1234 -d /home/ci -m ci
|
||||
USER ci
|
||||
|
||||
ENV PATH="$PATH:/home/ci/.local/bin"
|
||||
|
||||
COPY .pre-commit-config.yaml .
|
||||
|
||||
RUN pip install "pre-commit==3.1.1" \
|
||||
&& git init . \
|
||||
&& pre-commit install-hooks \
|
||||
&& rm -rf /tmp/*
|
|
@ -5,4 +5,5 @@ docker-compose.yml
|
|||
Dockerfile
|
||||
temp
|
||||
.dockerignore
|
||||
docker
|
||||
docker
|
||||
.cache
|
||||
|
|
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
|
@ -1 +0,0 @@
|
|||
* @TrueCloudLab/storage-core @TrueCloudLab/committers
|
16
.github/ISSUE_TEMPLATE/bug_report.md
vendored
16
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
@ -2,7 +2,7 @@
|
|||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: community, triage
|
||||
labels: community, triage, bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
@ -18,8 +18,11 @@ assignees: ''
|
|||
If suggesting a change/improvement, explain the difference from current behavior -->
|
||||
|
||||
## Possible Solution
|
||||
<!-- Not obligatory, but suggest a fix/reason for the bug,
|
||||
or ideas how to implement the addition or change -->
|
||||
<!-- Not obligatory
|
||||
If no reason/fix/additions for the bug can be suggested,
|
||||
uncomment the following phrase:
|
||||
|
||||
No fix can be suggested by a QA engineer. Further solutions shall be up to developers. -->
|
||||
|
||||
## Steps to Reproduce (for bugs)
|
||||
<!-- Provide a link to a live example, or an unambiguous set of steps
|
||||
|
@ -41,10 +44,3 @@ assignees: ''
|
|||
* Version used:
|
||||
* Server setup and configuration:
|
||||
* Operating System and version (`uname -a`):
|
||||
|
||||
## Don't forget to add labels!
|
||||
- component label (`frostfs-adm`, `frostfs-storage`, ...)
|
||||
- `goodfirstissue`, `helpwanted` if needed
|
||||
- does this issue belong to an epic?
|
||||
- priority (`P0`-`P4`) if already triaged
|
||||
- quarter label (`202XQY`) if possible
|
||||
|
|
29
.github/workflows/changelog.yml
vendored
29
.github/workflows/changelog.yml
vendored
|
@ -1,29 +0,0 @@
|
|||
name: CHANGELOG check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- support/**
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
name: Check for updates
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get changed CHANGELOG
|
||||
id: changelog-diff
|
||||
uses: tj-actions/changed-files@v29
|
||||
with:
|
||||
files: CHANGELOG.md
|
||||
|
||||
- name: Fail if changelog not updated
|
||||
if: steps.changelog-diff.outputs.any_changed == 'false'
|
||||
uses: actions/github-script@v3
|
||||
with:
|
||||
script: |
|
||||
core.setFailed('CHANGELOG.md has not been updated')
|
37
.github/workflows/config-update.yml
vendored
37
.github/workflows/config-update.yml
vendored
|
@ -1,37 +0,0 @@
|
|||
name: Configuration check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- support/**
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
name: config-check
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get changed config-related files
|
||||
id: config-diff
|
||||
uses: tj-actions/changed-files@v29
|
||||
with:
|
||||
files: |
|
||||
config/**
|
||||
cmd/neofs-node/config/**
|
||||
|
||||
- name: Get changed doc files
|
||||
id: docs-diff
|
||||
uses: tj-actions/changed-files@v29
|
||||
with:
|
||||
files: docs/**
|
||||
|
||||
- name: Fail if config files are changed but the documentation is not updated
|
||||
if: steps.config-diff.outputs.any_changed == 'true' && steps.docs-diff.outputs.any_changed == 'false'
|
||||
uses: actions/github-script@v3
|
||||
with:
|
||||
script: |
|
||||
core.setFailed('Documentation has not been updated')
|
22
.github/workflows/dco.yml
vendored
22
.github/workflows/dco.yml
vendored
|
@ -1,22 +0,0 @@
|
|||
name: DCO check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- support/**
|
||||
|
||||
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 }}
|
60
.github/workflows/go.yml
vendored
60
.github/workflows/go.yml
vendored
|
@ -1,60 +0,0 @@
|
|||
name: frostfs-node tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- support/**
|
||||
paths-ignore:
|
||||
- '*.md'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- support/**
|
||||
paths-ignore:
|
||||
- '*.md'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
go: [ '1.18.x', '1.19.x' ]
|
||||
steps:
|
||||
- name: Setup go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: ${{ matrix.go }}
|
||||
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Cache go mod
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ matrix.go }}-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-${{ matrix.go }}-
|
||||
|
||||
- name: Run go test
|
||||
run: go test -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
|
||||
- name: Codecov
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
run: bash <(curl -s https://codecov.io/bash)
|
||||
|
||||
lint:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19
|
||||
- uses: actions/checkout@v3
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
with:
|
||||
version: v1.50.0
|
||||
args: --timeout=5m
|
||||
only-new-issues: true
|
11
.gitlint
Normal file
11
.gitlint
Normal file
|
@ -0,0 +1,11 @@
|
|||
[general]
|
||||
fail-without-commits=True
|
||||
regex-style-search=True
|
||||
contrib=CC1
|
||||
|
||||
[title-match-regex]
|
||||
regex=^\[\#[0-9Xx]+\]\s
|
||||
|
||||
[ignore-by-title]
|
||||
regex=^Release(.*)
|
||||
ignore=title-match-regex
|
|
@ -4,7 +4,7 @@
|
|||
# options for analysis running
|
||||
run:
|
||||
# timeout for analysis, e.g. 30s, 5m, default is 1m
|
||||
timeout: 5m
|
||||
timeout: 10m
|
||||
|
||||
# include test files or not, default is true
|
||||
tests: false
|
||||
|
@ -24,6 +24,13 @@ linters-settings:
|
|||
govet:
|
||||
# report about shadowed variables
|
||||
check-shadowing: false
|
||||
staticcheck:
|
||||
checks: ["all", "-SA1019"] # TODO Enable SA1019 after deprecated warning are fixed.
|
||||
funlen:
|
||||
lines: 80 # default 60
|
||||
statements: 60 # default 40
|
||||
gocognit:
|
||||
min-complexity: 40 # default 30
|
||||
|
||||
linters:
|
||||
enable:
|
||||
|
@ -51,6 +58,9 @@ linters:
|
|||
- predeclared
|
||||
- reassign
|
||||
- whitespace
|
||||
- containedctx
|
||||
- funlen
|
||||
- gocognit
|
||||
- contextcheck
|
||||
disable-all: true
|
||||
fast: false
|
||||
|
||||
|
|
50
.pre-commit-config.yaml
Normal file
50
.pre-commit-config.yaml
Normal file
|
@ -0,0 +1,50 @@
|
|||
ci:
|
||||
autofix_prs: false
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/jorisroovers/gitlint
|
||||
rev: v0.19.1
|
||||
hooks:
|
||||
- id: gitlint
|
||||
stages: [commit-msg]
|
||||
- id: gitlint-ci
|
||||
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.4.0
|
||||
hooks:
|
||||
- id: check-added-large-files
|
||||
- id: check-case-conflict
|
||||
- id: check-executables-have-shebangs
|
||||
- id: check-shebang-scripts-are-executable
|
||||
- id: check-merge-conflict
|
||||
- id: check-json
|
||||
- id: check-xml
|
||||
- id: check-yaml
|
||||
- id: trailing-whitespace
|
||||
args: [--markdown-linebreak-ext=md]
|
||||
- id: end-of-file-fixer
|
||||
exclude: ".key$"
|
||||
|
||||
- repo: https://github.com/shellcheck-py/shellcheck-py
|
||||
rev: v0.9.0.2
|
||||
hooks:
|
||||
- id: shellcheck
|
||||
|
||||
- repo: https://github.com/golangci/golangci-lint
|
||||
rev: v1.51.2
|
||||
hooks:
|
||||
- id: golangci-lint
|
||||
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: go-unit-tests
|
||||
name: go unit tests
|
||||
entry: make test
|
||||
pass_filenames: false
|
||||
types: [go]
|
||||
language: system
|
||||
|
||||
- repo: https://github.com/TekWizely/pre-commit-golang
|
||||
rev: v1.0.0-rc.1
|
||||
hooks:
|
||||
- id: go-staticcheck-repo-mod
|
11
.woodpecker/pre-commit.yml
Normal file
11
.woodpecker/pre-commit.yml
Normal file
|
@ -0,0 +1,11 @@
|
|||
pipeline:
|
||||
# Kludge for non-root containers under WoodPecker
|
||||
fix-ownership:
|
||||
image: alpine:latest
|
||||
commands: chown -R 1234:1234 .
|
||||
|
||||
pre-commit:
|
||||
image: git.frostfs.info/truecloudlab/frostfs-ci:v0.36
|
||||
commands:
|
||||
- export HOME="$(getent passwd $(id -u) | cut '-d:' -f6)"
|
||||
- pre-commit run --hook-stage manual
|
1593
CHANGELOG.md
1593
CHANGELOG.md
File diff suppressed because it is too large
Load diff
|
@ -10,7 +10,7 @@ In alphabetical order:
|
|||
- Alexey Vanin
|
||||
- Anastasia Prasolova
|
||||
- Anatoly Bogatyrev
|
||||
- Evgeny Kulikov
|
||||
- Evgeny Kulikov
|
||||
- Evgeny Stratonikov
|
||||
- Leonard Liubich
|
||||
- Sergei Liubich
|
||||
|
|
20
Makefile
Normal file → Executable file
20
Makefile
Normal file → Executable file
|
@ -26,7 +26,7 @@ PKG_VERSION ?= $(shell echo $(VERSION) | sed "s/^v//" | \
|
|||
sed "s/-/~/")-${OS_RELEASE}
|
||||
|
||||
.PHONY: help all images dep clean fmts fmt imports test lint docker/lint
|
||||
prepare-release debpackage
|
||||
prepare-release debpackage pre-commit unpre-commit
|
||||
|
||||
# To build a specific binary, use it's name prefix with bin/ as a target
|
||||
# For example `make bin/frostfs-node` will build only storage node binary
|
||||
|
@ -70,7 +70,7 @@ protoc:
|
|||
@GOPRIVATE=github.com/TrueCloudLab go mod vendor
|
||||
# Install specific version for protobuf lib
|
||||
@go list -f '{{.Path}}/...@{{.Version}}' -m github.com/golang/protobuf | xargs go install -v
|
||||
@GOBIN=$(abspath $(BIN)) go install -mod=mod -v github.com/TrueCloudLab/frostfs-api-go/v2/util/protogen
|
||||
@GOBIN=$(abspath $(BIN)) go install -mod=mod -v git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/protogen
|
||||
# Protoc generate
|
||||
@for f in `find . -type f -name '*.proto' -not -path './vendor/*'`; do \
|
||||
echo "⇒ Processing $$f "; \
|
||||
|
@ -128,10 +128,17 @@ test:
|
|||
@echo "⇒ Running go test"
|
||||
@go test ./...
|
||||
|
||||
pre-commit-run:
|
||||
@pre-commit run -a --hook-stage manual
|
||||
|
||||
# Run linters
|
||||
lint:
|
||||
@golangci-lint --timeout=5m run
|
||||
|
||||
# Run staticcheck
|
||||
staticcheck:
|
||||
@staticcheck ./...
|
||||
|
||||
# Run linters in Docker
|
||||
docker/lint:
|
||||
docker run --rm -t \
|
||||
|
@ -140,10 +147,19 @@ docker/lint:
|
|||
--env HOME=/src \
|
||||
golangci/golangci-lint:v$(LINT_VERSION) bash -c 'cd /src/ && make lint'
|
||||
|
||||
# Activate pre-commit hooks
|
||||
pre-commit:
|
||||
pre-commit install -t pre-commit -t commit-msg
|
||||
|
||||
# Deactivate pre-commit hooks
|
||||
unpre-commit:
|
||||
pre-commit uninstall -t pre-commit -t commit-msg
|
||||
|
||||
# Print version
|
||||
version:
|
||||
@echo $(VERSION)
|
||||
|
||||
# Delete built artifacts
|
||||
clean:
|
||||
rm -rf vendor
|
||||
rm -rf .cache
|
||||
|
|
|
@ -31,7 +31,7 @@ dApps directly from
|
|||
code level. This way dApps are not limited to on-chain storage and can
|
||||
manipulate large amounts of data without paying a prohibitive price.
|
||||
|
||||
FrostFS has a native [gRPC API](https://github.com/TrueCloudLab/frostfs-api) and has
|
||||
FrostFS has a native [gRPC API](https://git.frostfs.info/TrueCloudLab/frostfs-api) and has
|
||||
protocol gateways for popular protocols such as [AWS
|
||||
S3](https://github.com/TrueCloudLab/frostfs-s3-gw),
|
||||
[HTTP](https://github.com/TrueCloudLab/frostfs-http-gw),
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
v0.35.0
|
||||
v0.36.0
|
||||
|
|
|
@ -3,23 +3,22 @@
|
|||
## Overview
|
||||
|
||||
Admin tool provides an easier way to deploy and maintain private installation
|
||||
of FrostFS. Private installation provides a set of N3 consensus nodes, FrostFS
|
||||
Alphabet, and Storage nodes. Admin tool generates consensus keys, initializes
|
||||
of FrostFS. Private installation provides a set of N3 consensus nodes, FrostFS
|
||||
Alphabet, and Storage nodes. Admin tool generates consensus keys, initializes
|
||||
the sidechain, and provides functions to update the network and register new
|
||||
Storage nodes.
|
||||
|
||||
## Build
|
||||
|
||||
To build binary locally, use `make bin/frostfs-adm` command.
|
||||
To build binary locally, use `make bin/frostfs-adm` command.
|
||||
|
||||
For clean build inside a docker container, use `make docker/bin/frostfs-adm`.
|
||||
For clean build inside a docker container, use `make docker/bin/frostfs-adm`.
|
||||
|
||||
Build docker image with `make image-adm`.
|
||||
|
||||
At FrostFS private install deployment, frostfs-adm requires compiled FrostFS
|
||||
contracts. Find them in the latest release of
|
||||
[frostfs-contract repository](https://github.com/TrueCloudLab/frostfs-contract/releases).
|
||||
|
||||
At FrostFS private install deployment, frostfs-adm requires compiled FrostFS
|
||||
contracts. Find them in the latest release of
|
||||
[frostfs-contract repository](https://git.frostfs.info/TrueCloudLab/frostfs-contract/releases).
|
||||
|
||||
## Commands
|
||||
|
||||
|
@ -27,7 +26,7 @@ contracts. Find them in the latest release of
|
|||
|
||||
Config section provides `init` command that creates a configuration file for
|
||||
private installation deployment and updates. Config file is optional, all
|
||||
parameters can be passed by arguments or read from standard input (wallet
|
||||
parameters can be passed by arguments or read from standard input (wallet
|
||||
passwords).
|
||||
|
||||
Config example:
|
||||
|
@ -58,14 +57,14 @@ credentials: # passwords for consensus node / alphabet wallets
|
|||
|
||||
#### Network deployment
|
||||
|
||||
- `generate-alphabet` generates a set of wallets for consensus and
|
||||
Alphabet nodes.
|
||||
- `generate-alphabet` generates a set of wallets for consensus and
|
||||
Alphabet nodes.
|
||||
|
||||
- `init` initializes the sidechain by deploying smart contracts and
|
||||
setting provided FrostFS network configuration.
|
||||
|
||||
- `generate-storage-wallet` generates a wallet for the Storage node that
|
||||
is ready for deployment. It also transfers a bit of sidechain GAS, so this
|
||||
- `generate-storage-wallet` generates a wallet for the Storage node that
|
||||
is ready for deployment. It also transfers a bit of sidechain GAS, so this
|
||||
wallet can be used for FrostFS bootstrap.
|
||||
|
||||
#### Network maintenance
|
||||
|
@ -75,7 +74,7 @@ credentials: # passwords for consensus node / alphabet wallets
|
|||
- `force-new-epoch` increments FrostFS epoch number and executes new epoch
|
||||
handlers in FrostFS nodes.
|
||||
|
||||
- `refill-gas` transfers sidechain GAS to the specified wallet.
|
||||
- `refill-gas` transfers sidechain GAS to the specified wallet.
|
||||
|
||||
- `update-contracts` updates contracts to a new version.
|
||||
|
||||
|
@ -87,7 +86,7 @@ info. These commands **do not migrate actual objects**.
|
|||
- `dump-containers` saves all containers and metadata registered in the container
|
||||
contract to a file.
|
||||
|
||||
- `restore-containers` restores previously saved containers by their repeated registration in
|
||||
- `restore-containers` restores previously saved containers by their repeated registration in
|
||||
the container contract.
|
||||
|
||||
- `list-containers` output all containers ids.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
This is a short guide on how to deploy a private FrostFS storage network on bare
|
||||
metal without docker images. This guide does not cover details on how to start
|
||||
consensus, Alphabet, or Storage nodes. This guide covers only `frostfs-adm`
|
||||
consensus, Alphabet, or Storage nodes. This guide covers only `frostfs-adm`
|
||||
related configuration details.
|
||||
|
||||
## Prerequisites
|
||||
|
@ -12,11 +12,11 @@ To follow this guide you need:
|
|||
- latest released version of [frostfs-adm](https://github.com/TrueCloudLab/frostfs-node/releases) utility (v0.25.1 at the moment),
|
||||
- latest released version of compiled [frostfs-contract](https://github.com/TrueCloudLab/frostfs-contract/releases) (v0.11.0 at the moment).
|
||||
|
||||
## Step 1: Prepare network configuration
|
||||
## Step 1: Prepare network configuration
|
||||
|
||||
To start a network, you need a set of consensus nodes, the same number of
|
||||
Alphabet nodes and any number of Storage nodes. While the number of Storage
|
||||
nodes can be scaled almost infinitely, the number of consensus and Alphabet
|
||||
To start a network, you need a set of consensus nodes, the same number of
|
||||
Alphabet nodes and any number of Storage nodes. While the number of Storage
|
||||
nodes can be scaled almost infinitely, the number of consensus and Alphabet
|
||||
nodes can't be changed so easily right now. Consider this before going any further.
|
||||
|
||||
It is easier to use`frostfs-adm` with a predefined configuration. First, create
|
||||
|
@ -27,7 +27,7 @@ consensus / Alphabet node in the network.
|
|||
$ frostfs-adm config init --path foo.network.yml
|
||||
Initial config file saved to foo.network.yml
|
||||
|
||||
$ cat foo.network.yml
|
||||
$ cat foo.network.yml
|
||||
rpc-endpoint: https://neo.rpc.node:30333
|
||||
alphabet-wallets: /home/user/deploy/alphabet-wallets
|
||||
network:
|
||||
|
@ -43,17 +43,17 @@ credentials:
|
|||
az: hunter2
|
||||
```
|
||||
|
||||
For private installation, it is recommended to set all **fees** and **basic
|
||||
income rate** to 0.
|
||||
For private installation, it is recommended to set all **fees** and **basic
|
||||
income rate** to 0.
|
||||
|
||||
As for **epoch duration**, consider consensus node block generation frequency.
|
||||
With default 15 seconds per block, 240 blocks are going to be a 1-hour epoch.
|
||||
As for **epoch duration**, consider consensus node block generation frequency.
|
||||
With default 15 seconds per block, 240 blocks are going to be a 1-hour epoch.
|
||||
|
||||
For **max object size**, 67108864 (64 MiB) or 134217728 (128 MiB) should provide
|
||||
For **max object size**, 67108864 (64 MiB) or 134217728 (128 MiB) should provide
|
||||
good chunk distribution in most cases.
|
||||
|
||||
With this config, generate wallets (private keys) of consensus nodes. The same
|
||||
wallets will be used for Alphabet nodes. Make sure, that dir for alphabet
|
||||
wallets will be used for Alphabet nodes. Make sure, that dir for alphabet
|
||||
wallets already exists.
|
||||
|
||||
```
|
||||
|
@ -69,14 +69,14 @@ storage.
|
|||
## Step 2: Launch consensus nodes
|
||||
|
||||
Configure blockchain nodes with the generated wallets from the previous step.
|
||||
Config examples can be found in
|
||||
Config examples can be found in
|
||||
[neo-go repository](https://github.com/nspcc-dev/neo-go/tree/master/config).
|
||||
|
||||
Gather public keys from **all** generated wallets. We are interested in the first
|
||||
`simple signature contract` public key.
|
||||
|
||||
```
|
||||
$ neo-go wallet dump-keys -w alphabet-wallets/az.json
|
||||
$ neo-go wallet dump-keys -w alphabet-wallets/az.json
|
||||
NitdS4k4f1Hh5mbLJhAswBK3WC2gQgPN1o (simple signature contract):
|
||||
02c1cc85f9c856dbe2d02017349bcb7b4e5defa78b8056a09b3240ba2a8c078869
|
||||
|
||||
|
@ -87,10 +87,10 @@ NiMKabp3ddi3xShmLAXhTfbnuWb4cSJT6E (1 out of 1 multisig contract):
|
|||
02c1cc85f9c856dbe2d02017349bcb7b4e5defa78b8056a09b3240ba2a8c078869
|
||||
```
|
||||
|
||||
Put the list of public keys into `ProtocolConfiguration.StandbyCommittee`
|
||||
Put the list of public keys into `ProtocolConfiguration.StandbyCommittee`
|
||||
section. Specify the wallet path and the password in `ApplicationConfiguration.P2PNotary`
|
||||
and `ApplicationConfiguration.UnlockWallet` sections. If config includes
|
||||
`ProtocolConfiguration.NativeActivations` section, add notary
|
||||
`ProtocolConfiguration.NativeActivations` section, add notary
|
||||
contract `Notary: [0]`.
|
||||
|
||||
```yaml
|
||||
|
@ -121,7 +121,7 @@ and possible overload issues.
|
|||
Use archive with compiled FrostFS contracts to initialize the sidechain.
|
||||
|
||||
```
|
||||
$ tar -xzvf frostfs-contract-v0.11.0.tar.gz
|
||||
$ tar -xzvf frostfs-contract-v0.11.0.tar.gz
|
||||
|
||||
$ ./frostfs-adm -c foo.network.yml morph init --contracts ./frostfs-contract-v0.11.0
|
||||
Stage 1: transfer GAS to alphabet nodes.
|
||||
|
@ -153,8 +153,8 @@ Waiting for transactions to persist...
|
|||
|
||||
## Step 4: Launch Alphabet nodes
|
||||
|
||||
Configure Alphabet nodes with the wallets generated in step 1. For
|
||||
`morph.validators` use a list of public keys from
|
||||
Configure Alphabet nodes with the wallets generated in step 1. For
|
||||
`morph.validators` use a list of public keys from
|
||||
`ProtocolConfiguration.StandbyCommittee`.
|
||||
|
||||
```yaml
|
||||
|
@ -178,10 +178,10 @@ Generate a new wallet for a Storage node.
|
|||
|
||||
```
|
||||
$ frostfs-adm -c foo.network.yml morph generate-storage-wallet --storage-wallet ./sn01.json --initial-gas 10.0
|
||||
New password >
|
||||
New password >
|
||||
Waiting for transactions to persist...
|
||||
|
||||
$ neo-go wallet dump-keys -w sn01.json
|
||||
$ neo-go wallet dump-keys -w sn01.json
|
||||
Ngr7p8Z9S22XDH6VkUG9oXobv8zZRAWwwv (simple signature contract):
|
||||
0355eccb72cd46f09a3e5237eaa0f4949cceb5ecfa5a225bd3bb9fd021c4d75b85
|
||||
```
|
||||
|
@ -205,7 +205,7 @@ Current epoch: 8, increase to 9.
|
|||
Waiting for transactions to persist...
|
||||
```
|
||||
|
||||
---
|
||||
---
|
||||
|
||||
After that, FrostFS Storage is ready to work. You can access it directly or
|
||||
with protocol gates.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# FrostFS subnetwork creation
|
||||
|
||||
This is a short guide on how to create FrostFS subnetworks. This guide
|
||||
considers that the sidechain and the inner ring (alphabet nodes) have already been
|
||||
This is a short guide on how to create FrostFS subnetworks. This guide
|
||||
considers that the sidechain and the inner ring (alphabet nodes) have already been
|
||||
deployed and the sidechain contains a deployed `subnet` contract.
|
||||
|
||||
## Prerequisites
|
||||
|
|
|
@ -88,11 +88,11 @@ has been added by the subnet owner).
|
|||
|
||||
# Bootstrapping Storage Node
|
||||
|
||||
After a subnetwork [is created](subnetwork-creation.md) and a node is included into it, the
|
||||
After a subnetwork [is created](subnetwork-creation.md) and a node is included into it, the
|
||||
node could be bootstrapped and service subnetwork containers.
|
||||
|
||||
For bootstrapping, you need to specify the ID of the subnetwork in the node's
|
||||
configuration:
|
||||
For bootstrapping, you need to specify the ID of the subnetwork in the node's
|
||||
configuration:
|
||||
|
||||
```yaml
|
||||
...
|
||||
|
@ -106,7 +106,7 @@ node:
|
|||
```
|
||||
|
||||
**NOTE:** specifying subnetwork that is denied for the node is not an error:
|
||||
that configuration value would be ignored. You do not need to specify zero
|
||||
that configuration value would be ignored. You do not need to specify zero
|
||||
(with 0 ID) subnetwork: its inclusion is implicit. On the contrary, to exclude
|
||||
a node from the default zero subnetwork, you need to specify it explicitly:
|
||||
|
||||
|
@ -122,7 +122,7 @@ node:
|
|||
|
||||
# Creating container in non-zero subnetwork
|
||||
|
||||
Creating containers without using `--subnet` flag is equivalent to
|
||||
Creating containers without using `--subnet` flag is equivalent to
|
||||
creating container in the zero subnetwork.
|
||||
|
||||
To create a container in a private network, your wallet must be added to
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"path/filepath"
|
||||
"text/template"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||
"github.com/nspcc-dev/neo-go/cli/input"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-contract/nns"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/native/noderoles"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
|
@ -83,86 +83,110 @@ func dumpBalances(cmd *cobra.Command, _ []string) error {
|
|||
printBalances(cmd, "Inner ring nodes balances:", irList)
|
||||
|
||||
if dumpStorage {
|
||||
arr, err := unwrap.Array(inv.Call(nmHash, "netmap"))
|
||||
if err != nil {
|
||||
return errors.New("can't fetch the list of storage nodes")
|
||||
}
|
||||
|
||||
snList := make([]accBalancePair, len(arr))
|
||||
for i := range arr {
|
||||
node, ok := arr[i].Value().([]stackitem.Item)
|
||||
if !ok || len(node) == 0 {
|
||||
return errors.New("can't parse the list of storage nodes")
|
||||
}
|
||||
bs, err := node[0].TryBytes()
|
||||
if err != nil {
|
||||
return errors.New("can't parse the list of storage nodes")
|
||||
}
|
||||
var ni netmap.NodeInfo
|
||||
if err := ni.Unmarshal(bs); err != nil {
|
||||
return fmt.Errorf("can't parse the list of storage nodes: %w", err)
|
||||
}
|
||||
pub, err := keys.NewPublicKeyFromBytes(ni.PublicKey(), elliptic.P256())
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't parse storage node public key: %w", err)
|
||||
}
|
||||
snList[i].scriptHash = pub.GetScriptHash()
|
||||
}
|
||||
|
||||
if err := fetchBalances(inv, gas.Hash, snList); err != nil {
|
||||
if err := printStorageNodeBalances(cmd, inv, nmHash); err != nil {
|
||||
return err
|
||||
}
|
||||
printBalances(cmd, "\nStorage node balances:", snList)
|
||||
}
|
||||
|
||||
if dumpProxy {
|
||||
h, err := nnsResolveHash(inv, nnsCs.Hash, proxyContract+".frostfs")
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't get hash of the proxy contract: %w", err)
|
||||
}
|
||||
|
||||
proxyList := []accBalancePair{{scriptHash: h}}
|
||||
if err := fetchBalances(inv, gas.Hash, proxyList); err != nil {
|
||||
if err := printProxyContractBalance(cmd, inv, nnsCs.Hash); err != nil {
|
||||
return err
|
||||
}
|
||||
printBalances(cmd, "\nProxy contract balance:", proxyList)
|
||||
}
|
||||
|
||||
if dumpAlphabet {
|
||||
alphaList := make([]accBalancePair, len(irList))
|
||||
|
||||
w := io.NewBufBinWriter()
|
||||
for i := range alphaList {
|
||||
emit.AppCall(w.BinWriter, nnsCs.Hash, "resolve", callflag.ReadOnly,
|
||||
getAlphabetNNSDomain(i),
|
||||
int64(nns.TXT))
|
||||
}
|
||||
if w.Err != nil {
|
||||
panic(w.Err)
|
||||
}
|
||||
|
||||
alphaRes, err := c.InvokeScript(w.Bytes(), nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't fetch info from NNS: %w", err)
|
||||
}
|
||||
|
||||
for i := range alphaList {
|
||||
h, err := parseNNSResolveResult(alphaRes.Stack[i])
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't fetch the alphabet contract #%d hash: %w", i, err)
|
||||
}
|
||||
alphaList[i].scriptHash = h
|
||||
}
|
||||
|
||||
if err := fetchBalances(inv, gas.Hash, alphaList); err != nil {
|
||||
if err := printAlphabetContractBalances(cmd, c, inv, len(irList), nnsCs.Hash); err != nil {
|
||||
return err
|
||||
}
|
||||
printBalances(cmd, "\nAlphabet contracts balances:", alphaList)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func printStorageNodeBalances(cmd *cobra.Command, inv *invoker.Invoker, nmHash util.Uint160) error {
|
||||
arr, err := unwrap.Array(inv.Call(nmHash, "netmap"))
|
||||
if err != nil {
|
||||
return errors.New("can't fetch the list of storage nodes")
|
||||
}
|
||||
|
||||
snList := make([]accBalancePair, len(arr))
|
||||
for i := range arr {
|
||||
node, ok := arr[i].Value().([]stackitem.Item)
|
||||
if !ok || len(node) == 0 {
|
||||
return errors.New("can't parse the list of storage nodes")
|
||||
}
|
||||
bs, err := node[0].TryBytes()
|
||||
if err != nil {
|
||||
return errors.New("can't parse the list of storage nodes")
|
||||
}
|
||||
var ni netmap.NodeInfo
|
||||
if err := ni.Unmarshal(bs); err != nil {
|
||||
return fmt.Errorf("can't parse the list of storage nodes: %w", err)
|
||||
}
|
||||
pub, err := keys.NewPublicKeyFromBytes(ni.PublicKey(), elliptic.P256())
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't parse storage node public key: %w", err)
|
||||
}
|
||||
snList[i].scriptHash = pub.GetScriptHash()
|
||||
}
|
||||
|
||||
if err := fetchBalances(inv, gas.Hash, snList); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printBalances(cmd, "\nStorage node balances:", snList)
|
||||
return nil
|
||||
}
|
||||
|
||||
func printProxyContractBalance(cmd *cobra.Command, inv *invoker.Invoker, nnsHash util.Uint160) error {
|
||||
h, err := nnsResolveHash(inv, nnsHash, proxyContract+".frostfs")
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't get hash of the proxy contract: %w", err)
|
||||
}
|
||||
|
||||
proxyList := []accBalancePair{{scriptHash: h}}
|
||||
if err := fetchBalances(inv, gas.Hash, proxyList); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printBalances(cmd, "\nProxy contract balance:", proxyList)
|
||||
return nil
|
||||
}
|
||||
|
||||
func printAlphabetContractBalances(cmd *cobra.Command, c Client, inv *invoker.Invoker, count int, nnsHash util.Uint160) error {
|
||||
alphaList := make([]accBalancePair, count)
|
||||
|
||||
w := io.NewBufBinWriter()
|
||||
for i := range alphaList {
|
||||
emit.AppCall(w.BinWriter, nnsHash, "resolve", callflag.ReadOnly,
|
||||
getAlphabetNNSDomain(i),
|
||||
int64(nns.TXT))
|
||||
}
|
||||
if w.Err != nil {
|
||||
panic(w.Err)
|
||||
}
|
||||
|
||||
alphaRes, err := c.InvokeScript(w.Bytes(), nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't fetch info from NNS: %w", err)
|
||||
}
|
||||
|
||||
for i := range alphaList {
|
||||
h, err := parseNNSResolveResult(alphaRes.Stack[i])
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't fetch the alphabet contract #%d hash: %w", i, err)
|
||||
}
|
||||
alphaList[i].scriptHash = h
|
||||
}
|
||||
|
||||
if err := fetchBalances(inv, gas.Hash, alphaList); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printBalances(cmd, "\nAlphabet contracts balances:", alphaList)
|
||||
return nil
|
||||
}
|
||||
|
||||
func fetchIRNodes(c Client, nmHash, desigHash util.Uint160) ([]accBalancePair, error) {
|
||||
var irList []accBalancePair
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"os"
|
||||
"sort"
|
||||
|
||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
||||
|
@ -41,16 +41,28 @@ func getContainerContractHash(cmd *cobra.Command, inv *invoker.Invoker, c Client
|
|||
return ch, nil
|
||||
}
|
||||
|
||||
func getContainersList(inv *invoker.Invoker, ch util.Uint160) ([][]byte, error) {
|
||||
res, err := inv.Call(ch, "list", "")
|
||||
func iterateContainerList(inv *invoker.Invoker, ch util.Uint160, f func([]byte) error) error {
|
||||
sid, r, err := unwrap.SessionIterator(inv.Call(ch, "containersOf", ""))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
|
||||
return fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
|
||||
}
|
||||
itm, err := unwrap.Item(res, err)
|
||||
if _, ok := itm.(stackitem.Null); !ok {
|
||||
return unwrap.ArrayOfBytes(res, err)
|
||||
// Nothing bad, except live session on the server, do not report to the user.
|
||||
defer func() { _ = inv.TerminateSession(sid) }()
|
||||
|
||||
items, err := inv.TraverseIterator(sid, &r, 0)
|
||||
for err == nil && len(items) != 0 {
|
||||
for j := range items {
|
||||
b, err := items[j].TryBytes()
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
|
||||
}
|
||||
if err := f(b); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
items, err = inv.TraverseIterator(sid, &r, 0)
|
||||
}
|
||||
return nil, nil
|
||||
return err
|
||||
}
|
||||
|
||||
func dumpContainers(cmd *cobra.Command, _ []string) error {
|
||||
|
@ -71,56 +83,81 @@ func dumpContainers(cmd *cobra.Command, _ []string) error {
|
|||
return fmt.Errorf("unable to get contaract hash: %w", err)
|
||||
}
|
||||
|
||||
cids, err := getContainersList(inv, ch)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
|
||||
}
|
||||
|
||||
isOK, err := getCIDFilterFunc(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var containers []*Container
|
||||
bw := io.NewBufBinWriter()
|
||||
for _, id := range cids {
|
||||
if !isOK(id) {
|
||||
continue
|
||||
}
|
||||
bw.Reset()
|
||||
emit.AppCall(bw.BinWriter, ch, "get", callflag.All, id)
|
||||
emit.AppCall(bw.BinWriter, ch, "eACL", callflag.All, id)
|
||||
res, err := inv.Run(bw.Bytes())
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't get container info: %w", err)
|
||||
}
|
||||
if len(res.Stack) != 2 {
|
||||
return fmt.Errorf("%w: expected 2 items on stack", errInvalidContainerResponse)
|
||||
}
|
||||
|
||||
cnt := new(Container)
|
||||
err = cnt.FromStackItem(res.Stack[0])
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
|
||||
}
|
||||
|
||||
ea := new(EACL)
|
||||
err = ea.FromStackItem(res.Stack[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
|
||||
}
|
||||
if len(ea.Value) != 0 {
|
||||
cnt.EACL = ea
|
||||
}
|
||||
|
||||
containers = append(containers, cnt)
|
||||
}
|
||||
|
||||
out, err := json.Marshal(containers)
|
||||
f, err := os.OpenFile(filename, os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0o660)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(filename, out, 0o660)
|
||||
defer f.Close()
|
||||
|
||||
_, err = f.Write([]byte{'['})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
written := 0
|
||||
enc := json.NewEncoder(f)
|
||||
bw := io.NewBufBinWriter()
|
||||
iterErr := iterateContainerList(inv, ch, func(id []byte) error {
|
||||
if !isOK(id) {
|
||||
return nil
|
||||
}
|
||||
|
||||
cnt, err := dumpSingleContainer(bw, ch, inv, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Writing directly to the file is ok, because json.Encoder does no internal buffering.
|
||||
if written != 0 {
|
||||
_, err = f.Write([]byte{','})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
written++
|
||||
return enc.Encode(cnt)
|
||||
})
|
||||
if iterErr != nil {
|
||||
return iterErr
|
||||
}
|
||||
|
||||
_, err = f.Write([]byte{']'})
|
||||
return err
|
||||
}
|
||||
|
||||
func dumpSingleContainer(bw *io.BufBinWriter, ch util.Uint160, inv *invoker.Invoker, id []byte) (*Container, error) {
|
||||
bw.Reset()
|
||||
emit.AppCall(bw.BinWriter, ch, "get", callflag.All, id)
|
||||
emit.AppCall(bw.BinWriter, ch, "eACL", callflag.All, id)
|
||||
res, err := inv.Run(bw.Bytes())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't get container info: %w", err)
|
||||
}
|
||||
if len(res.Stack) != 2 {
|
||||
return nil, fmt.Errorf("%w: expected 2 items on stack", errInvalidContainerResponse)
|
||||
}
|
||||
|
||||
cnt := new(Container)
|
||||
err = cnt.FromStackItem(res.Stack[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
|
||||
}
|
||||
|
||||
ea := new(EACL)
|
||||
err = ea.FromStackItem(res.Stack[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
|
||||
}
|
||||
if len(ea.Value) != 0 {
|
||||
cnt.EACL = ea
|
||||
}
|
||||
return cnt, nil
|
||||
}
|
||||
|
||||
func listContainers(cmd *cobra.Command, _ []string) error {
|
||||
|
@ -136,20 +173,15 @@ func listContainers(cmd *cobra.Command, _ []string) error {
|
|||
return fmt.Errorf("unable to get contaract hash: %w", err)
|
||||
}
|
||||
|
||||
cids, err := getContainersList(inv, ch)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
|
||||
}
|
||||
|
||||
for _, id := range cids {
|
||||
return iterateContainerList(inv, ch, func(id []byte) error {
|
||||
var idCnr cid.ID
|
||||
err = idCnr.Decode(id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to decode container id: %w", err)
|
||||
}
|
||||
cmd.Println(idCnr)
|
||||
}
|
||||
return nil
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func restoreContainers(cmd *cobra.Command, _ []string) error {
|
||||
|
@ -164,25 +196,14 @@ func restoreContainers(cmd *cobra.Command, _ []string) error {
|
|||
}
|
||||
defer wCtx.close()
|
||||
|
||||
nnsCs, err := wCtx.Client.GetContractStateByID(1)
|
||||
containers, err := parseContainers(filename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't get NNS contract state: %w", err)
|
||||
return err
|
||||
}
|
||||
|
||||
ch, err := nnsResolveHash(wCtx.ReadOnlyInvoker, nnsCs.Hash, containerContract+".frostfs")
|
||||
ch, err := fetchContainerContractHash(wCtx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't fetch container contract hash: %w", err)
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't read dump file: %w", err)
|
||||
}
|
||||
|
||||
var containers []Container
|
||||
err = json.Unmarshal(data, &containers)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't parse dump file: %w", err)
|
||||
return err
|
||||
}
|
||||
|
||||
isOK, err := getCIDFilterFunc(cmd)
|
||||
|
@ -190,6 +211,15 @@ func restoreContainers(cmd *cobra.Command, _ []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
err = restoreOrPutContainers(containers, isOK, cmd, wCtx, ch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return wCtx.awaitTx()
|
||||
}
|
||||
|
||||
func restoreOrPutContainers(containers []Container, isOK func([]byte) bool, cmd *cobra.Command, wCtx *initializeContext, ch util.Uint160) error {
|
||||
bw := io.NewBufBinWriter()
|
||||
for _, cnt := range containers {
|
||||
hv := hash.Sha256(cnt.Value)
|
||||
|
@ -197,33 +227,18 @@ func restoreContainers(cmd *cobra.Command, _ []string) error {
|
|||
continue
|
||||
}
|
||||
bw.Reset()
|
||||
emit.AppCall(bw.BinWriter, ch, "get", callflag.All, hv.BytesBE())
|
||||
res, err := wCtx.Client.InvokeScript(bw.Bytes(), nil)
|
||||
restored, err := isContainerRestored(cmd, wCtx, ch, bw, hv)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't check if container is already restored: %w", err)
|
||||
return err
|
||||
}
|
||||
if len(res.Stack) == 0 {
|
||||
return errors.New("empty stack")
|
||||
}
|
||||
|
||||
old := new(Container)
|
||||
if err := old.FromStackItem(res.Stack[0]); err != nil {
|
||||
return fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
|
||||
}
|
||||
if len(old.Value) != 0 {
|
||||
var id cid.ID
|
||||
id.SetSHA256(hv)
|
||||
cmd.Printf("Container %s is already deployed.\n", id)
|
||||
if restored {
|
||||
continue
|
||||
}
|
||||
|
||||
bw.Reset()
|
||||
emit.AppCall(bw.BinWriter, ch, "put", callflag.All,
|
||||
cnt.Value, cnt.Signature, cnt.PublicKey, cnt.Token)
|
||||
if ea := cnt.EACL; ea != nil {
|
||||
emit.AppCall(bw.BinWriter, ch, "setEACL", callflag.All,
|
||||
ea.Value, ea.Signature, ea.PublicKey, ea.Token)
|
||||
}
|
||||
|
||||
putContainer(bw, ch, cnt)
|
||||
|
||||
if bw.Err != nil {
|
||||
panic(bw.Err)
|
||||
}
|
||||
|
@ -232,8 +247,67 @@ func restoreContainers(cmd *cobra.Command, _ []string) error {
|
|||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return wCtx.awaitTx()
|
||||
func putContainer(bw *io.BufBinWriter, ch util.Uint160, cnt Container) {
|
||||
emit.AppCall(bw.BinWriter, ch, "put", callflag.All,
|
||||
cnt.Value, cnt.Signature, cnt.PublicKey, cnt.Token)
|
||||
if ea := cnt.EACL; ea != nil {
|
||||
emit.AppCall(bw.BinWriter, ch, "setEACL", callflag.All,
|
||||
ea.Value, ea.Signature, ea.PublicKey, ea.Token)
|
||||
}
|
||||
}
|
||||
|
||||
func isContainerRestored(cmd *cobra.Command, wCtx *initializeContext, containerHash util.Uint160, bw *io.BufBinWriter, hashValue util.Uint256) (bool, error) {
|
||||
emit.AppCall(bw.BinWriter, containerHash, "get", callflag.All, hashValue.BytesBE())
|
||||
res, err := wCtx.Client.InvokeScript(bw.Bytes(), nil)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("can't check if container is already restored: %w", err)
|
||||
}
|
||||
if len(res.Stack) == 0 {
|
||||
return false, errors.New("empty stack")
|
||||
}
|
||||
|
||||
old := new(Container)
|
||||
if err := old.FromStackItem(res.Stack[0]); err != nil {
|
||||
return false, fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
|
||||
}
|
||||
if len(old.Value) != 0 {
|
||||
var id cid.ID
|
||||
id.SetSHA256(hashValue)
|
||||
cmd.Printf("Container %s is already deployed.\n", id)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func parseContainers(filename string) ([]Container, error) {
|
||||
data, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't read dump file: %w", err)
|
||||
}
|
||||
|
||||
var containers []Container
|
||||
err = json.Unmarshal(data, &containers)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't parse dump file: %w", err)
|
||||
}
|
||||
return containers, nil
|
||||
}
|
||||
|
||||
func fetchContainerContractHash(wCtx *initializeContext) (util.Uint160, error) {
|
||||
nnsCs, err := wCtx.Client.GetContractStateByID(1)
|
||||
if err != nil {
|
||||
return util.Uint160{}, fmt.Errorf("can't get NNS contract state: %w", err)
|
||||
}
|
||||
|
||||
ch, err := nnsResolveHash(wCtx.ReadOnlyInvoker, nnsCs.Hash, containerContract+".frostfs")
|
||||
if err != nil {
|
||||
return util.Uint160{}, fmt.Errorf("can't fetch container contract hash: %w", err)
|
||||
}
|
||||
return ch, nil
|
||||
}
|
||||
|
||||
// Container represents container struct in contract storage.
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-contract/nns"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
|
||||
"github.com/nspcc-dev/neo-go/cli/cmdargs"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
|
@ -100,80 +100,88 @@ func deployContractCmd(cmd *cobra.Command, args []string) error {
|
|||
cs.Manifest.Name)
|
||||
}
|
||||
|
||||
w := io.NewBufBinWriter()
|
||||
if err := emitDeploymentArguments(w.BinWriter, args); err != nil {
|
||||
writer := io.NewBufBinWriter()
|
||||
if err := emitDeploymentArguments(writer.BinWriter, args); err != nil {
|
||||
return err
|
||||
}
|
||||
emit.Bytes(w.BinWriter, cs.RawManifest)
|
||||
emit.Bytes(w.BinWriter, cs.RawNEF)
|
||||
emit.Int(w.BinWriter, 3)
|
||||
emit.Opcodes(w.BinWriter, opcode.PACK)
|
||||
emit.AppCallNoArgs(w.BinWriter, callHash, method, callflag.All)
|
||||
emit.Opcodes(w.BinWriter, opcode.DROP) // contract state on stack
|
||||
emit.Bytes(writer.BinWriter, cs.RawManifest)
|
||||
emit.Bytes(writer.BinWriter, cs.RawNEF)
|
||||
emit.Int(writer.BinWriter, 3)
|
||||
emit.Opcodes(writer.BinWriter, opcode.PACK)
|
||||
emit.AppCallNoArgs(writer.BinWriter, callHash, method, callflag.All)
|
||||
emit.Opcodes(writer.BinWriter, opcode.DROP) // contract state on stack
|
||||
if !isUpdate {
|
||||
bw := io.NewBufBinWriter()
|
||||
emit.Instruction(bw.BinWriter, opcode.INITSSLOT, []byte{1})
|
||||
emit.AppCall(bw.BinWriter, nnsCs.Hash, "getPrice", callflag.All)
|
||||
emit.Opcodes(bw.BinWriter, opcode.STSFLD0)
|
||||
emit.AppCall(bw.BinWriter, nnsCs.Hash, "setPrice", callflag.All, 1)
|
||||
|
||||
start := bw.Len()
|
||||
needRecord := false
|
||||
|
||||
ok, err := c.nnsRootRegistered(nnsCs.Hash, zone)
|
||||
err := registerNNS(nnsCs, c, zone, domain, cs, writer)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !ok {
|
||||
needRecord = true
|
||||
|
||||
emit.AppCall(bw.BinWriter, nnsCs.Hash, "register", callflag.All,
|
||||
zone, c.CommitteeAcc.Contract.ScriptHash(),
|
||||
"ops@nspcc.ru", int64(3600), int64(600), int64(defaultExpirationTime), int64(3600))
|
||||
emit.Opcodes(bw.BinWriter, opcode.ASSERT)
|
||||
|
||||
emit.AppCall(bw.BinWriter, nnsCs.Hash, "register", callflag.All,
|
||||
domain, c.CommitteeAcc.Contract.ScriptHash(),
|
||||
"ops@nspcc.ru", int64(3600), int64(600), int64(defaultExpirationTime), int64(3600))
|
||||
emit.Opcodes(bw.BinWriter, opcode.ASSERT)
|
||||
} else {
|
||||
s, ok, err := c.nnsRegisterDomainScript(nnsCs.Hash, cs.Hash, domain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
needRecord = !ok
|
||||
if len(s) != 0 {
|
||||
bw.WriteBytes(s)
|
||||
}
|
||||
}
|
||||
if needRecord {
|
||||
emit.AppCall(bw.BinWriter, nnsCs.Hash, "deleteRecords", callflag.All, domain, int64(nns.TXT))
|
||||
emit.AppCall(bw.BinWriter, nnsCs.Hash, "addRecord", callflag.All,
|
||||
domain, int64(nns.TXT), address.Uint160ToString(cs.Hash))
|
||||
}
|
||||
|
||||
if bw.Err != nil {
|
||||
panic(fmt.Errorf("BUG: can't create deployment script: %w", w.Err))
|
||||
} else if bw.Len() != start {
|
||||
w.WriteBytes(bw.Bytes())
|
||||
emit.Opcodes(w.BinWriter, opcode.LDSFLD0, opcode.PUSH1, opcode.PACK)
|
||||
emit.AppCallNoArgs(w.BinWriter, nnsCs.Hash, "setPrice", callflag.All)
|
||||
|
||||
if needRecord {
|
||||
c.Command.Printf("NNS: Set %s -> %s\n", domain, cs.Hash.StringLE())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if w.Err != nil {
|
||||
panic(fmt.Errorf("BUG: can't create deployment script: %w", w.Err))
|
||||
if writer.Err != nil {
|
||||
panic(fmt.Errorf("BUG: can't create deployment script: %w", writer.Err))
|
||||
}
|
||||
|
||||
if err := c.sendCommitteeTx(w.Bytes(), false); err != nil {
|
||||
if err := c.sendCommitteeTx(writer.Bytes(), false); err != nil {
|
||||
return err
|
||||
}
|
||||
return c.awaitTx()
|
||||
}
|
||||
|
||||
func registerNNS(nnsCs *state.Contract, c *initializeContext, zone string, domain string, cs *contractState, writer *io.BufBinWriter) error {
|
||||
bw := io.NewBufBinWriter()
|
||||
emit.Instruction(bw.BinWriter, opcode.INITSSLOT, []byte{1})
|
||||
emit.AppCall(bw.BinWriter, nnsCs.Hash, "getPrice", callflag.All)
|
||||
emit.Opcodes(bw.BinWriter, opcode.STSFLD0)
|
||||
emit.AppCall(bw.BinWriter, nnsCs.Hash, "setPrice", callflag.All, 1)
|
||||
|
||||
start := bw.Len()
|
||||
needRecord := false
|
||||
|
||||
ok, err := c.nnsRootRegistered(nnsCs.Hash, zone)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !ok {
|
||||
needRecord = true
|
||||
|
||||
emit.AppCall(bw.BinWriter, nnsCs.Hash, "register", callflag.All,
|
||||
zone, c.CommitteeAcc.Contract.ScriptHash(),
|
||||
"ops@nspcc.ru", int64(3600), int64(600), int64(defaultExpirationTime), int64(3600))
|
||||
emit.Opcodes(bw.BinWriter, opcode.ASSERT)
|
||||
|
||||
emit.AppCall(bw.BinWriter, nnsCs.Hash, "register", callflag.All,
|
||||
domain, c.CommitteeAcc.Contract.ScriptHash(),
|
||||
"ops@nspcc.ru", int64(3600), int64(600), int64(defaultExpirationTime), int64(3600))
|
||||
emit.Opcodes(bw.BinWriter, opcode.ASSERT)
|
||||
} else {
|
||||
s, ok, err := c.nnsRegisterDomainScript(nnsCs.Hash, cs.Hash, domain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
needRecord = !ok
|
||||
if len(s) != 0 {
|
||||
bw.WriteBytes(s)
|
||||
}
|
||||
}
|
||||
if needRecord {
|
||||
emit.AppCall(bw.BinWriter, nnsCs.Hash, "deleteRecords", callflag.All, domain, int64(nns.TXT))
|
||||
emit.AppCall(bw.BinWriter, nnsCs.Hash, "addRecord", callflag.All,
|
||||
domain, int64(nns.TXT), address.Uint160ToString(cs.Hash))
|
||||
}
|
||||
|
||||
if bw.Err != nil {
|
||||
panic(fmt.Errorf("BUG: can't create deployment script: %w", writer.Err))
|
||||
} else if bw.Len() != start {
|
||||
writer.WriteBytes(bw.Bytes())
|
||||
emit.Opcodes(writer.BinWriter, opcode.LDSFLD0, opcode.PUSH1, opcode.PACK)
|
||||
emit.AppCallNoArgs(writer.BinWriter, nnsCs.Hash, "setPrice", callflag.All)
|
||||
|
||||
if needRecord {
|
||||
c.Command.Printf("NNS: Set %s -> %s\n", domain, cs.Hash.StringLE())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func emitDeploymentArguments(w *io.BinWriter, args []string) error {
|
||||
_, ps, err := cmdargs.ParseParams(args, true)
|
||||
if err != nil {
|
||||
|
|
|
@ -7,7 +7,8 @@ import (
|
|||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-contract/nns"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
|
||||
morphClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
|
||||
|
@ -123,7 +124,7 @@ func dumpCustomZoneHashes(cmd *cobra.Command, nnsHash util.Uint160, zone string,
|
|||
return
|
||||
}
|
||||
|
||||
if !bytes.HasSuffix(bs, []byte(zone)) {
|
||||
if !bytes.HasSuffix(bs, []byte(zone)) || bytes.HasPrefix(bs, []byte(morphClient.NNSGroupKeyName)) {
|
||||
// Related https://github.com/nspcc-dev/neofs-contract/issues/316.
|
||||
return
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||
"github.com/nspcc-dev/neo-go/cli/input"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
|
|
|
@ -7,9 +7,9 @@ import (
|
|||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||
morphClient "github.com/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||
morphClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
|
@ -118,24 +118,14 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex
|
|||
needContracts := cmd.Name() == "update-contracts" || cmd.Name() == "init"
|
||||
|
||||
var w *wallet.Wallet
|
||||
if needContracts {
|
||||
w, err = openContractWallet(v, cmd, walletDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
w, err = getWallet(cmd, v, needContracts, walletDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var c Client
|
||||
if v.GetString(localDumpFlag) != "" {
|
||||
if v.GetString(endpointFlag) != "" {
|
||||
return nil, fmt.Errorf("`%s` and `%s` flags are mutually exclusive", endpointFlag, localDumpFlag)
|
||||
}
|
||||
c, err = newLocalClient(cmd, v, wallets)
|
||||
} else {
|
||||
c, err = getN3Client(v)
|
||||
}
|
||||
c, err := createClient(cmd, v, wallets)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't create N3 client: %w", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
committeeAcc, err := getWalletAccount(wallets[0], committeeAccountName)
|
||||
|
@ -148,35 +138,22 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex
|
|||
return nil, fmt.Errorf("can't find consensus account: %w", err)
|
||||
}
|
||||
|
||||
var ctrPath string
|
||||
if cmd.Name() == "init" {
|
||||
if viper.GetInt64(epochDurationInitFlag) <= 0 {
|
||||
return nil, fmt.Errorf("epoch duration must be positive")
|
||||
}
|
||||
|
||||
if viper.GetInt64(maxObjectSizeInitFlag) <= 0 {
|
||||
return nil, fmt.Errorf("max object size must be positive")
|
||||
}
|
||||
if err := validateInit(cmd); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if needContracts {
|
||||
ctrPath, err = cmd.Flags().GetString(contractsInitFlag)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid contracts path: %w", err)
|
||||
}
|
||||
ctrPath, err := getContractsPath(cmd, v, needContracts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := checkNotaryEnabled(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
accounts := make([]*wallet.Account, len(wallets))
|
||||
for i, w := range wallets {
|
||||
acc, err := getWalletAccount(w, singleAccountName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("wallet %s is invalid (no single account): %w", w.Path(), err)
|
||||
}
|
||||
accounts[i] = acc
|
||||
accounts, err := createWalletAccounts(wallets)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cliCtx, err := defaultClientContext(c, committeeAcc)
|
||||
|
@ -206,6 +183,69 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex
|
|||
return initCtx, nil
|
||||
}
|
||||
|
||||
func validateInit(cmd *cobra.Command) error {
|
||||
if cmd.Name() != "init" {
|
||||
return nil
|
||||
}
|
||||
if viper.GetInt64(epochDurationInitFlag) <= 0 {
|
||||
return fmt.Errorf("epoch duration must be positive")
|
||||
}
|
||||
|
||||
if viper.GetInt64(maxObjectSizeInitFlag) <= 0 {
|
||||
return fmt.Errorf("max object size must be positive")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func createClient(cmd *cobra.Command, v *viper.Viper, wallets []*wallet.Wallet) (Client, error) {
|
||||
var c Client
|
||||
var err error
|
||||
if v.GetString(localDumpFlag) != "" {
|
||||
if v.GetString(endpointFlag) != "" {
|
||||
return nil, fmt.Errorf("`%s` and `%s` flags are mutually exclusive", endpointFlag, localDumpFlag)
|
||||
}
|
||||
c, err = newLocalClient(cmd, v, wallets)
|
||||
} else {
|
||||
c, err = getN3Client(v)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't create N3 client: %w", err)
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func getWallet(cmd *cobra.Command, v *viper.Viper, needContracts bool, walletDir string) (*wallet.Wallet, error) {
|
||||
if !needContracts {
|
||||
return nil, nil
|
||||
}
|
||||
return openContractWallet(v, cmd, walletDir)
|
||||
}
|
||||
|
||||
func getContractsPath(cmd *cobra.Command, v *viper.Viper, needContracts bool) (string, error) {
|
||||
if !needContracts {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
ctrPath, err := cmd.Flags().GetString(contractsInitFlag)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("invalid contracts path: %w", err)
|
||||
}
|
||||
return ctrPath, nil
|
||||
}
|
||||
|
||||
func createWalletAccounts(wallets []*wallet.Wallet) ([]*wallet.Account, error) {
|
||||
accounts := make([]*wallet.Account, len(wallets))
|
||||
for i, w := range wallets {
|
||||
acc, err := getWalletAccount(w, singleAccountName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("wallet %s is invalid (no single account): %w", w.Path(), err)
|
||||
}
|
||||
accounts[i] = acc
|
||||
}
|
||||
return accounts, nil
|
||||
}
|
||||
|
||||
func openAlphabetWallets(v *viper.Viper, walletDir string) ([]*wallet.Wallet, error) {
|
||||
walletFiles, err := os.ReadDir(walletDir)
|
||||
if err != nil {
|
||||
|
|
|
@ -12,10 +12,10 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-contract/common"
|
||||
"github.com/TrueCloudLab/frostfs-contract/nns"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||
morphClient "github.com/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-contract/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||
morphClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
|
@ -167,8 +167,6 @@ func (c *initializeContext) updateContracts() error {
|
|||
|
||||
w := io2.NewBufBinWriter()
|
||||
|
||||
var keysParam []any
|
||||
|
||||
// Update script size for a single-node committee is close to the maximum allowed size of 65535.
|
||||
// Because of this we want to reuse alphabet contract NEF and manifest for different updates.
|
||||
// The generated script is as following.
|
||||
|
@ -182,42 +180,36 @@ func (c *initializeContext) updateContracts() error {
|
|||
emit.Bytes(w.BinWriter, alphaCs.RawNEF)
|
||||
emit.Opcodes(w.BinWriter, opcode.STSFLD0)
|
||||
|
||||
baseGroups := alphaCs.Manifest.Groups
|
||||
|
||||
// alphabet contracts should be deployed by individual nodes to get different hashes.
|
||||
for i, acc := range c.Accounts {
|
||||
ctrHash, err := nnsResolveHash(c.ReadOnlyInvoker, nnsHash, getAlphabetNNSDomain(i))
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't resolve hash for contract update: %w", err)
|
||||
}
|
||||
|
||||
keysParam = append(keysParam, acc.PrivateKey().PublicKey().Bytes())
|
||||
|
||||
params := c.getAlphabetDeployItems(i, len(c.Wallets))
|
||||
emit.Array(w.BinWriter, params...)
|
||||
|
||||
alphaCs.Manifest.Groups = baseGroups
|
||||
err = c.addManifestGroup(ctrHash, alphaCs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't sign manifest group: %v", err)
|
||||
}
|
||||
|
||||
emit.Bytes(w.BinWriter, alphaCs.RawManifest)
|
||||
emit.Opcodes(w.BinWriter, opcode.LDSFLD0)
|
||||
emit.Int(w.BinWriter, 3)
|
||||
emit.Opcodes(w.BinWriter, opcode.PACK)
|
||||
emit.AppCallNoArgs(w.BinWriter, ctrHash, updateMethodName, callflag.All)
|
||||
}
|
||||
|
||||
if err := c.sendCommitteeTx(w.Bytes(), false); err != nil {
|
||||
if !strings.Contains(err.Error(), common.ErrAlreadyUpdated) {
|
||||
return err
|
||||
}
|
||||
c.Command.Println("Alphabet contracts are already updated.")
|
||||
keysParam, err := c.deployAlphabetAccounts(nnsHash, w, alphaCs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.Reset()
|
||||
|
||||
if err = c.deployOrUpdateContracts(w, nnsHash, keysParam); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
groupKey := c.ContractWallet.Accounts[0].PrivateKey().PublicKey()
|
||||
_, _, err = c.emitUpdateNNSGroupScript(w, nnsHash, groupKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Command.Printf("NNS: Set %s -> %s\n", morphClient.NNSGroupKeyName, hex.EncodeToString(groupKey.Bytes()))
|
||||
|
||||
emit.Opcodes(w.BinWriter, opcode.LDSFLD0)
|
||||
emit.Int(w.BinWriter, 1)
|
||||
emit.Opcodes(w.BinWriter, opcode.PACK)
|
||||
emit.AppCallNoArgs(w.BinWriter, nnsHash, "setPrice", callflag.All)
|
||||
|
||||
if err := c.sendCommitteeTx(w.Bytes(), false); err != nil {
|
||||
return err
|
||||
}
|
||||
return c.awaitTx()
|
||||
}
|
||||
|
||||
func (c *initializeContext) deployOrUpdateContracts(w *io2.BufBinWriter, nnsHash util.Uint160, keysParam []any) error {
|
||||
emit.Instruction(w.BinWriter, opcode.INITSSLOT, []byte{1})
|
||||
emit.AppCall(w.BinWriter, nnsHash, "getPrice", callflag.All)
|
||||
emit.Opcodes(w.BinWriter, opcode.STSFLD0)
|
||||
|
@ -277,23 +269,46 @@ func (c *initializeContext) updateContracts() error {
|
|||
c.Command.Printf("NNS: Set %s -> %s\n", domain, cs.Hash.StringLE())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
groupKey := c.ContractWallet.Accounts[0].PrivateKey().PublicKey()
|
||||
_, _, err = c.emitUpdateNNSGroupScript(w, nnsHash, groupKey)
|
||||
if err != nil {
|
||||
return err
|
||||
func (c *initializeContext) deployAlphabetAccounts(nnsHash util.Uint160, w *io2.BufBinWriter, alphaCs *contractState) ([]any, error) {
|
||||
var keysParam []any
|
||||
|
||||
baseGroups := alphaCs.Manifest.Groups
|
||||
|
||||
// alphabet contracts should be deployed by individual nodes to get different hashes.
|
||||
for i, acc := range c.Accounts {
|
||||
ctrHash, err := nnsResolveHash(c.ReadOnlyInvoker, nnsHash, getAlphabetNNSDomain(i))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't resolve hash for contract update: %w", err)
|
||||
}
|
||||
|
||||
keysParam = append(keysParam, acc.PrivateKey().PublicKey().Bytes())
|
||||
|
||||
params := c.getAlphabetDeployItems(i, len(c.Wallets))
|
||||
emit.Array(w.BinWriter, params...)
|
||||
|
||||
alphaCs.Manifest.Groups = baseGroups
|
||||
err = c.addManifestGroup(ctrHash, alphaCs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't sign manifest group: %v", err)
|
||||
}
|
||||
|
||||
emit.Bytes(w.BinWriter, alphaCs.RawManifest)
|
||||
emit.Opcodes(w.BinWriter, opcode.LDSFLD0)
|
||||
emit.Int(w.BinWriter, 3)
|
||||
emit.Opcodes(w.BinWriter, opcode.PACK)
|
||||
emit.AppCallNoArgs(w.BinWriter, ctrHash, updateMethodName, callflag.All)
|
||||
}
|
||||
c.Command.Printf("NNS: Set %s -> %s\n", morphClient.NNSGroupKeyName, hex.EncodeToString(groupKey.Bytes()))
|
||||
|
||||
emit.Opcodes(w.BinWriter, opcode.LDSFLD0)
|
||||
emit.Int(w.BinWriter, 1)
|
||||
emit.Opcodes(w.BinWriter, opcode.PACK)
|
||||
emit.AppCallNoArgs(w.BinWriter, nnsHash, "setPrice", callflag.All)
|
||||
|
||||
if err := c.sendCommitteeTx(w.Bytes(), false); err != nil {
|
||||
return err
|
||||
if !strings.Contains(err.Error(), common.ErrAlreadyUpdated) {
|
||||
return nil, err
|
||||
}
|
||||
c.Command.Println("Alphabet contracts are already updated.")
|
||||
}
|
||||
return c.awaitTx()
|
||||
|
||||
return keysParam, nil
|
||||
}
|
||||
|
||||
func (c *initializeContext) deployContracts() error {
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-contract/nns"
|
||||
morphClient "github.com/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
|
||||
morphClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
|
@ -82,13 +82,13 @@ func (c *initializeContext) setNNS() error {
|
|||
|
||||
func (c *initializeContext) updateNNSGroup(nnsHash util.Uint160, pub *keys.PublicKey) error {
|
||||
bw := io.NewBufBinWriter()
|
||||
needUpdate, needRegister, err := c.emitUpdateNNSGroupScript(bw, nnsHash, pub)
|
||||
if !needUpdate || err != nil {
|
||||
keyAlreadyAdded, domainRegCodeEmitted, err := c.emitUpdateNNSGroupScript(bw, nnsHash, pub)
|
||||
if keyAlreadyAdded || err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
script := bw.Bytes()
|
||||
if needRegister {
|
||||
if domainRegCodeEmitted {
|
||||
w := io.NewBufBinWriter()
|
||||
emit.Instruction(w.BinWriter, opcode.INITSSLOT, []byte{1})
|
||||
wrapRegisterScriptWithPrice(w, nnsHash, script)
|
||||
|
@ -228,20 +228,27 @@ func nnsResolve(inv *invoker.Invoker, nnsHash util.Uint160, domain string) (stac
|
|||
}
|
||||
|
||||
func nnsResolveKey(inv *invoker.Invoker, nnsHash util.Uint160, domain string) (*keys.PublicKey, error) {
|
||||
item, err := nnsResolve(inv, nnsHash, domain)
|
||||
res, err := nnsResolve(inv, nnsHash, domain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v, ok := item.Value().(stackitem.Null)
|
||||
if ok {
|
||||
if _, ok := res.Value().(stackitem.Null); ok {
|
||||
return nil, errors.New("NNS record is missing")
|
||||
}
|
||||
bs, err := v.TryBytes()
|
||||
if err != nil {
|
||||
return nil, errors.New("malformed response")
|
||||
arr, ok := res.Value().([]stackitem.Item)
|
||||
if !ok {
|
||||
return nil, errors.New("API of the NNS contract method `resolve` has changed")
|
||||
}
|
||||
for i := range arr {
|
||||
var bs []byte
|
||||
bs, err = arr[i].TryBytes()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
return keys.NewPublicKeyFromString(string(bs))
|
||||
return keys.NewPublicKeyFromString(string(bs))
|
||||
}
|
||||
return nil, errors.New("no valid keys are found")
|
||||
}
|
||||
|
||||
// parseNNSResolveResult parses the result of resolving NNS record.
|
||||
|
@ -279,6 +286,7 @@ func parseNNSResolveResult(res stackitem.Item) (util.Uint160, error) {
|
|||
func nnsIsAvailable(c Client, nnsHash util.Uint160, name string) (bool, error) {
|
||||
switch ct := c.(type) {
|
||||
case *rpcclient.Client:
|
||||
//lint:ignore SA1019 https://git.frostfs.info/TrueCloudLab/frostfs-node/issues/202
|
||||
return ct.NNSIsAvailable(nnsHash, name)
|
||||
default:
|
||||
b, err := unwrap.Bool(invokeFunction(c, nnsHash, "isAvailable", []any{name}, nil))
|
||||
|
|
|
@ -118,6 +118,7 @@ var errGetPriceInvalid = errors.New("`getRegisterPrice`: invalid response")
|
|||
func (c *initializeContext) getCandidateRegisterPrice() (int64, error) {
|
||||
switch ct := c.Client.(type) {
|
||||
case *rpcclient.Client:
|
||||
//lint:ignore SA1019 https://git.frostfs.info/TrueCloudLab/frostfs-node/issues/202
|
||||
return ct.GetCandidateRegisterPrice()
|
||||
default:
|
||||
neoHash := neo.Hash
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
|
@ -101,11 +101,11 @@ func generateTestData(t *testing.T, dir string, size int) {
|
|||
cfg := config.Config{}
|
||||
cfg.ProtocolConfiguration.Magic = 12345
|
||||
cfg.ProtocolConfiguration.ValidatorsCount = size
|
||||
cfg.ProtocolConfiguration.SecondsPerBlock = 1
|
||||
cfg.ProtocolConfiguration.SecondsPerBlock = 1 //lint:ignore SA1019 https://git.frostfs.info/TrueCloudLab/frostfs-node/issues/202
|
||||
cfg.ProtocolConfiguration.StandbyCommittee = pubs // sorted by glagolic letters
|
||||
cfg.ProtocolConfiguration.P2PSigExtensions = true
|
||||
cfg.ProtocolConfiguration.VerifyTransactions = true
|
||||
cfg.ProtocolConfiguration.VerifyBlocks = true
|
||||
cfg.ProtocolConfiguration.VerifyBlocks = true //lint:ignore SA1019 https://git.frostfs.info/TrueCloudLab/frostfs-node/issues/202
|
||||
data, err := yaml.Marshal(cfg)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
|
Binary file not shown.
|
@ -2,7 +2,7 @@ syntax = "proto3";
|
|||
|
||||
package neo.fs.v2.refs;
|
||||
|
||||
option go_package = "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/internal";
|
||||
option go_package = "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/internal";
|
||||
|
||||
// Client group identifier in the FrostFS subnet.
|
||||
//
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package morph
|
||||
|
||||
import (
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
|
|
@ -9,10 +9,12 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/gas"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/nep17"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/notary"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
@ -23,16 +25,9 @@ import (
|
|||
const defaultNotaryDepositLifetime = 5760
|
||||
|
||||
func depositNotary(cmd *cobra.Command, _ []string) error {
|
||||
p, err := cmd.Flags().GetString(storageWalletFlag)
|
||||
w, err := openWallet(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if p == "" {
|
||||
return fmt.Errorf("missing wallet path (use '--%s <out.json>')", storageWalletFlag)
|
||||
}
|
||||
|
||||
w, err := wallet.NewWalletFromFile(p)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't open wallet: %v", err)
|
||||
}
|
||||
|
||||
accHash := w.GetChangeAddress()
|
||||
|
@ -80,6 +75,10 @@ func depositNotary(cmd *cobra.Command, _ []string) error {
|
|||
}
|
||||
}
|
||||
|
||||
return transferGas(cmd, acc, accHash, gasAmount, till)
|
||||
}
|
||||
|
||||
func transferGas(cmd *cobra.Command, acc *wallet.Account, accHash util.Uint160, gasAmount fixedn.Fixed8, till int64) error {
|
||||
c, err := getN3Client(viper.GetViper())
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -119,3 +118,18 @@ func depositNotary(cmd *cobra.Command, _ []string) error {
|
|||
|
||||
return awaitTx(cmd, c, []hashVUBPair{{hash: txHash, vub: vub}})
|
||||
}
|
||||
|
||||
func openWallet(cmd *cobra.Command) (*wallet.Wallet, error) {
|
||||
p, err := cmd.Flags().GetString(storageWalletFlag)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if p == "" {
|
||||
return nil, fmt.Errorf("missing wallet path (use '--%s <out.json>')", storageWalletFlag)
|
||||
}
|
||||
|
||||
w, err := wallet.NewWalletFromFile(p)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't open wallet: %v", err)
|
||||
}
|
||||
return w, nil
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
netmapcontract "github.com/TrueCloudLab/frostfs-contract/netmap"
|
||||
netmapcontract "git.frostfs.info/TrueCloudLab/frostfs-contract/netmap"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
|
|
|
@ -239,10 +239,139 @@ var (
|
|||
)
|
||||
|
||||
func init() {
|
||||
RootCmd.AddCommand(generateAlphabetCmd)
|
||||
generateAlphabetCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
generateAlphabetCmd.Flags().Uint(alphabetSizeFlag, 7, "Amount of alphabet wallets to generate")
|
||||
initGenerateAlphabetCmd()
|
||||
initInitCmd()
|
||||
initDeployCmd()
|
||||
initGenerateStorageCmd()
|
||||
initForceNewEpochCmd()
|
||||
initRemoveNodesCmd()
|
||||
initSetPolicyCmd()
|
||||
initDumpContractHashesCmd()
|
||||
initDumpNetworkConfigCmd()
|
||||
initSetConfigCmd()
|
||||
initDumpBalancesCmd()
|
||||
initUpdateContractsCmd()
|
||||
initDumpContainersCmd()
|
||||
initRestoreContainersCmd()
|
||||
initListContainersCmd()
|
||||
initRefillGasCmd()
|
||||
initSubnetCmd()
|
||||
initDepositoryNotaryCmd()
|
||||
initNetmapCandidatesCmd()
|
||||
}
|
||||
|
||||
func initNetmapCandidatesCmd() {
|
||||
RootCmd.AddCommand(netmapCandidatesCmd)
|
||||
netmapCandidatesCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
}
|
||||
|
||||
func initDepositoryNotaryCmd() {
|
||||
RootCmd.AddCommand(depositNotaryCmd)
|
||||
depositNotaryCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
depositNotaryCmd.Flags().String(storageWalletFlag, "", "Path to storage node wallet")
|
||||
depositNotaryCmd.Flags().String(walletAccountFlag, "", "Wallet account address")
|
||||
depositNotaryCmd.Flags().String(refillGasAmountFlag, "", "Amount of GAS to deposit")
|
||||
depositNotaryCmd.Flags().String(notaryDepositTillFlag, "", "Notary deposit duration in blocks")
|
||||
}
|
||||
|
||||
func initSubnetCmd() {
|
||||
RootCmd.AddCommand(cmdSubnet)
|
||||
}
|
||||
|
||||
func initRefillGasCmd() {
|
||||
RootCmd.AddCommand(refillGasCmd)
|
||||
refillGasCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
refillGasCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
refillGasCmd.Flags().String(storageWalletFlag, "", "Path to storage node wallet")
|
||||
refillGasCmd.Flags().String(walletAddressFlag, "", "Address of wallet")
|
||||
refillGasCmd.Flags().String(refillGasAmountFlag, "", "Additional amount of GAS to transfer")
|
||||
refillGasCmd.MarkFlagsMutuallyExclusive(walletAddressFlag, storageWalletFlag)
|
||||
}
|
||||
|
||||
func initListContainersCmd() {
|
||||
RootCmd.AddCommand(listContainersCmd)
|
||||
listContainersCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
listContainersCmd.Flags().String(containerContractFlag, "", "Container contract hash (for networks without NNS)")
|
||||
}
|
||||
|
||||
func initRestoreContainersCmd() {
|
||||
RootCmd.AddCommand(restoreContainersCmd)
|
||||
restoreContainersCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
restoreContainersCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
restoreContainersCmd.Flags().String(containerDumpFlag, "", "File to restore containers from")
|
||||
restoreContainersCmd.Flags().StringSlice(containerIDsFlag, nil, "Containers to restore")
|
||||
}
|
||||
|
||||
func initDumpContainersCmd() {
|
||||
RootCmd.AddCommand(dumpContainersCmd)
|
||||
dumpContainersCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
dumpContainersCmd.Flags().String(containerDumpFlag, "", "File where to save dumped containers")
|
||||
dumpContainersCmd.Flags().String(containerContractFlag, "", "Container contract hash (for networks without NNS)")
|
||||
dumpContainersCmd.Flags().StringSlice(containerIDsFlag, nil, "Containers to dump")
|
||||
}
|
||||
|
||||
func initUpdateContractsCmd() {
|
||||
RootCmd.AddCommand(updateContractsCmd)
|
||||
updateContractsCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
updateContractsCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
updateContractsCmd.Flags().String(contractsInitFlag, "", "Path to archive with compiled FrostFS contracts (default fetched from latest github release)")
|
||||
}
|
||||
|
||||
func initDumpBalancesCmd() {
|
||||
RootCmd.AddCommand(dumpBalancesCmd)
|
||||
dumpBalancesCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
dumpBalancesCmd.Flags().BoolP(dumpBalancesStorageFlag, "s", false, "Dump balances of storage nodes from the current netmap")
|
||||
dumpBalancesCmd.Flags().BoolP(dumpBalancesAlphabetFlag, "a", false, "Dump balances of alphabet contracts")
|
||||
dumpBalancesCmd.Flags().BoolP(dumpBalancesProxyFlag, "p", false, "Dump balances of the proxy contract")
|
||||
dumpBalancesCmd.Flags().Bool(dumpBalancesUseScriptHashFlag, false, "Use script-hash format for addresses")
|
||||
}
|
||||
|
||||
func initSetConfigCmd() {
|
||||
RootCmd.AddCommand(setConfig)
|
||||
setConfig.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
setConfig.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
setConfig.Flags().Bool(forceConfigSet, false, "Force setting not well-known configuration key")
|
||||
}
|
||||
|
||||
func initDumpNetworkConfigCmd() {
|
||||
RootCmd.AddCommand(dumpNetworkConfigCmd)
|
||||
dumpNetworkConfigCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
}
|
||||
|
||||
func initDumpContractHashesCmd() {
|
||||
RootCmd.AddCommand(dumpContractHashesCmd)
|
||||
dumpContractHashesCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
dumpContractHashesCmd.Flags().String(customZoneFlag, "", "Custom zone to search.")
|
||||
}
|
||||
|
||||
func initSetPolicyCmd() {
|
||||
RootCmd.AddCommand(setPolicy)
|
||||
setPolicy.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
setPolicy.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
}
|
||||
|
||||
func initRemoveNodesCmd() {
|
||||
RootCmd.AddCommand(removeNodes)
|
||||
removeNodes.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
removeNodes.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
}
|
||||
|
||||
func initForceNewEpochCmd() {
|
||||
RootCmd.AddCommand(forceNewEpoch)
|
||||
forceNewEpoch.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
forceNewEpoch.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
}
|
||||
|
||||
func initGenerateStorageCmd() {
|
||||
RootCmd.AddCommand(generateStorageCmd)
|
||||
generateStorageCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
generateStorageCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
generateStorageCmd.Flags().String(storageWalletFlag, "", "Path to new storage node wallet")
|
||||
generateStorageCmd.Flags().String(storageGasCLIFlag, "", "Initial amount of GAS to transfer")
|
||||
generateStorageCmd.Flags().StringP(storageWalletLabelFlag, "l", "", "Wallet label")
|
||||
}
|
||||
|
||||
func initInitCmd() {
|
||||
RootCmd.AddCommand(initCmd)
|
||||
initCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
initCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
|
@ -255,85 +384,14 @@ func init() {
|
|||
initCmd.Flags().Uint64(containerAliasFeeCLIFlag, 500, "Container alias fee")
|
||||
initCmd.Flags().String(protoConfigPath, "", "Path to the consensus node configuration")
|
||||
initCmd.Flags().String(localDumpFlag, "", "Path to the blocks dump file")
|
||||
|
||||
RootCmd.AddCommand(deployCmd)
|
||||
|
||||
RootCmd.AddCommand(generateStorageCmd)
|
||||
generateStorageCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
generateStorageCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
generateStorageCmd.Flags().String(storageWalletFlag, "", "Path to new storage node wallet")
|
||||
generateStorageCmd.Flags().String(storageGasCLIFlag, "", "Initial amount of GAS to transfer")
|
||||
generateStorageCmd.Flags().StringP(storageWalletLabelFlag, "l", "", "Wallet label")
|
||||
|
||||
RootCmd.AddCommand(forceNewEpoch)
|
||||
forceNewEpoch.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
forceNewEpoch.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
|
||||
RootCmd.AddCommand(removeNodes)
|
||||
removeNodes.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
removeNodes.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
|
||||
RootCmd.AddCommand(setPolicy)
|
||||
setPolicy.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
setPolicy.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
|
||||
RootCmd.AddCommand(dumpContractHashesCmd)
|
||||
dumpContractHashesCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
dumpContractHashesCmd.Flags().String(customZoneFlag, "", "Custom zone to search.")
|
||||
|
||||
RootCmd.AddCommand(dumpNetworkConfigCmd)
|
||||
dumpNetworkConfigCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
|
||||
RootCmd.AddCommand(setConfig)
|
||||
setConfig.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
setConfig.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
setConfig.Flags().Bool(forceConfigSet, false, "Force setting not well-known configuration key")
|
||||
|
||||
RootCmd.AddCommand(dumpBalancesCmd)
|
||||
dumpBalancesCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
dumpBalancesCmd.Flags().BoolP(dumpBalancesStorageFlag, "s", false, "Dump balances of storage nodes from the current netmap")
|
||||
dumpBalancesCmd.Flags().BoolP(dumpBalancesAlphabetFlag, "a", false, "Dump balances of alphabet contracts")
|
||||
dumpBalancesCmd.Flags().BoolP(dumpBalancesProxyFlag, "p", false, "Dump balances of the proxy contract")
|
||||
dumpBalancesCmd.Flags().Bool(dumpBalancesUseScriptHashFlag, false, "Use script-hash format for addresses")
|
||||
|
||||
RootCmd.AddCommand(updateContractsCmd)
|
||||
updateContractsCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
updateContractsCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
updateContractsCmd.Flags().String(contractsInitFlag, "", "Path to archive with compiled FrostFS contracts (default fetched from latest github release)")
|
||||
|
||||
RootCmd.AddCommand(dumpContainersCmd)
|
||||
dumpContainersCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
dumpContainersCmd.Flags().String(containerDumpFlag, "", "File where to save dumped containers")
|
||||
dumpContainersCmd.Flags().String(containerContractFlag, "", "Container contract hash (for networks without NNS)")
|
||||
dumpContainersCmd.Flags().StringSlice(containerIDsFlag, nil, "Containers to dump")
|
||||
|
||||
RootCmd.AddCommand(restoreContainersCmd)
|
||||
restoreContainersCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
restoreContainersCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
restoreContainersCmd.Flags().String(containerDumpFlag, "", "File to restore containers from")
|
||||
restoreContainersCmd.Flags().StringSlice(containerIDsFlag, nil, "Containers to restore")
|
||||
|
||||
RootCmd.AddCommand(listContainersCmd)
|
||||
listContainersCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
listContainersCmd.Flags().String(containerContractFlag, "", "Container contract hash (for networks without NNS)")
|
||||
|
||||
RootCmd.AddCommand(refillGasCmd)
|
||||
refillGasCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
refillGasCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
refillGasCmd.Flags().String(storageWalletFlag, "", "Path to storage node wallet")
|
||||
refillGasCmd.Flags().String(walletAddressFlag, "", "Address of wallet")
|
||||
refillGasCmd.Flags().String(refillGasAmountFlag, "", "Additional amount of GAS to transfer")
|
||||
refillGasCmd.MarkFlagsMutuallyExclusive(walletAddressFlag, storageWalletFlag)
|
||||
|
||||
RootCmd.AddCommand(cmdSubnet)
|
||||
|
||||
RootCmd.AddCommand(depositNotaryCmd)
|
||||
depositNotaryCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
depositNotaryCmd.Flags().String(storageWalletFlag, "", "Path to storage node wallet")
|
||||
depositNotaryCmd.Flags().String(walletAccountFlag, "", "Wallet account address")
|
||||
depositNotaryCmd.Flags().String(refillGasAmountFlag, "", "Amount of GAS to deposit")
|
||||
depositNotaryCmd.Flags().String(notaryDepositTillFlag, "", "Notary deposit duration in blocks")
|
||||
|
||||
RootCmd.AddCommand(netmapCandidatesCmd)
|
||||
netmapCandidatesCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
}
|
||||
|
||||
func initGenerateAlphabetCmd() {
|
||||
RootCmd.AddCommand(generateAlphabetCmd)
|
||||
generateAlphabetCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
generateAlphabetCmd.Flags().Uint(alphabetSizeFlag, 7, "Amount of alphabet wallets to generate")
|
||||
}
|
||||
|
||||
func initDeployCmd() {
|
||||
RootCmd.AddCommand(deployCmd)
|
||||
}
|
||||
|
|
|
@ -5,12 +5,12 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/internal"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/util/rand"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/subnet"
|
||||
subnetid "github.com/TrueCloudLab/frostfs-sdk-go/subnet/id"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/internal"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/rand"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/subnet"
|
||||
subnetid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/subnet/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"github.com/nspcc-dev/neo-go/cli/flags"
|
||||
"github.com/nspcc-dev/neo-go/cli/input"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
||||
|
@ -339,17 +339,19 @@ func manageSubnetAdmins(cmd *cobra.Command, rm bool) error {
|
|||
return fmt.Errorf("admin key format: %w", err)
|
||||
}
|
||||
|
||||
// prepare call parameters
|
||||
return invokeMethodWithParams(cmd, id, rm, binAdminKey, key)
|
||||
}
|
||||
|
||||
func invokeMethodWithParams(cmd *cobra.Command, id subnetid.ID, rm bool, binAdminKey []byte, key keys.PrivateKey) error {
|
||||
prm := make([]any, 0, 3)
|
||||
prm = append(prm, id.Marshal())
|
||||
|
||||
var method string
|
||||
|
||||
if viper.GetBool(flagSubnetAdminClient) {
|
||||
// read group ID and encode it
|
||||
var groupID internal.SubnetClientGroupID
|
||||
|
||||
err = groupID.UnmarshalText([]byte(viper.GetString(flagSubnetAdminAddGroup)))
|
||||
err := groupID.UnmarshalText([]byte(viper.GetString(flagSubnetAdminAddGroup)))
|
||||
if err != nil {
|
||||
return fmt.Errorf("decode group ID text: %w", err)
|
||||
}
|
||||
|
@ -376,7 +378,7 @@ func manageSubnetAdmins(cmd *cobra.Command, rm bool) error {
|
|||
|
||||
prm = append(prm, binAdminKey)
|
||||
|
||||
err = invokeMethod(key, false, method, prm...)
|
||||
err := invokeMethod(key, false, method, prm...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("morph invocation: %w", err)
|
||||
}
|
||||
|
@ -652,52 +654,13 @@ func addCommandInheritPreRun(par *cobra.Command, subs ...*cobra.Command) {
|
|||
|
||||
// registers flags and binds sub-commands for subnet commands.
|
||||
func init() {
|
||||
cmdSubnetCreate.Flags().StringP(flagSubnetWallet, "w", "", "Path to file with wallet")
|
||||
_ = cmdSubnetCreate.MarkFlagRequired(flagSubnetWallet)
|
||||
cmdSubnetCreate.Flags().StringP(flagSubnetAddress, "a", "", "Address in the wallet, optional")
|
||||
|
||||
// get subnet flags
|
||||
cmdSubnetGet.Flags().String(flagSubnetGetID, "", "ID of the subnet to read")
|
||||
_ = cmdSubnetAdminAdd.MarkFlagRequired(flagSubnetGetID)
|
||||
|
||||
// remove subnet flags
|
||||
cmdSubnetRemove.Flags().String(flagSubnetRemoveID, "", "ID of the subnet to remove")
|
||||
_ = cmdSubnetRemove.MarkFlagRequired(flagSubnetRemoveID)
|
||||
cmdSubnetRemove.Flags().StringP(flagSubnetWallet, "w", "", "Path to file with wallet")
|
||||
_ = cmdSubnetRemove.MarkFlagRequired(flagSubnetWallet)
|
||||
cmdSubnetRemove.Flags().StringP(flagSubnetAddress, "a", "", "Address in the wallet, optional")
|
||||
|
||||
// subnet administer flags
|
||||
adminFlags := cmdSubnetAdmin.PersistentFlags()
|
||||
adminFlags.String(flagSubnetAdminSubnet, "", "ID of the subnet to manage administrators")
|
||||
_ = cmdSubnetAdmin.MarkFlagRequired(flagSubnetAdminSubnet)
|
||||
adminFlags.String(flagSubnetAdminID, "", "Hex-encoded public key of the admin")
|
||||
_ = cmdSubnetAdmin.MarkFlagRequired(flagSubnetAdminID)
|
||||
adminFlags.StringP(flagSubnetWallet, "w", "", "Path to file with wallet")
|
||||
_ = cmdSubnetAdmin.MarkFlagRequired(flagSubnetWallet)
|
||||
adminFlags.StringP(flagSubnetAddress, "a", "", "Address in the wallet, optional")
|
||||
|
||||
// add admin flags
|
||||
cmdSubnetAdminAddFlags := cmdSubnetAdminAdd.Flags()
|
||||
cmdSubnetAdminAddFlags.String(flagSubnetAdminAddGroup, "", fmt.Sprintf(
|
||||
"Client group ID in text format (needed with --%s only)", flagSubnetAdminClient))
|
||||
cmdSubnetAdminAddFlags.Bool(flagSubnetAdminClient, false, "Add client admin instead of node one")
|
||||
|
||||
// remove admin flags
|
||||
cmdSubnetAdminRemoveFlags := cmdSubnetAdminRemove.Flags()
|
||||
cmdSubnetAdminRemoveFlags.Bool(flagSubnetAdminClient, false, "Remove client admin instead of node one")
|
||||
|
||||
// client managements flags
|
||||
clientFlags := cmdSubnetClient.PersistentFlags()
|
||||
clientFlags.String(flagSubnetClientSubnet, "", "ID of the subnet to be managed")
|
||||
_ = cmdSubnetClient.MarkFlagRequired(flagSubnetClientSubnet)
|
||||
clientFlags.String(flagSubnetClientGroup, "", "ID of the client group to work with")
|
||||
_ = cmdSubnetClient.MarkFlagRequired(flagSubnetClientGroup)
|
||||
clientFlags.String(flagSubnetClientID, "", "Client's user ID in FrostFS system in text format")
|
||||
_ = cmdSubnetClient.MarkFlagRequired(flagSubnetClientID)
|
||||
clientFlags.StringP(flagSubnetWallet, "w", "", "Path to file with wallet")
|
||||
_ = cmdSubnetClient.MarkFlagRequired(flagSubnetWallet)
|
||||
clientFlags.StringP(flagSubnetAddress, "a", "", "Address in the wallet, optional")
|
||||
initCreateSubnetFlags()
|
||||
initGetSubnetFlags()
|
||||
initRemoveSubnetFlags()
|
||||
initSubnetAdminFlags()
|
||||
initSubnetAdminAddFlags()
|
||||
initSubnetAdminRemoveFlags()
|
||||
initClientManagementFlags()
|
||||
|
||||
// add all admin managing commands to corresponding command section
|
||||
addCommandInheritPreRun(cmdSubnetAdmin,
|
||||
|
@ -711,14 +674,7 @@ func init() {
|
|||
cmdSubnetClientRemove,
|
||||
)
|
||||
|
||||
// subnet node flags
|
||||
nodeFlags := cmdSubnetNode.PersistentFlags()
|
||||
nodeFlags.StringP(flagSubnetWallet, "w", "", "Path to file with wallet")
|
||||
_ = cmdSubnetNode.MarkFlagRequired(flagSubnetWallet)
|
||||
nodeFlags.String(flagSubnetNode, "", "Hex-encoded public key of the node")
|
||||
_ = cmdSubnetNode.MarkFlagRequired(flagSubnetNode)
|
||||
nodeFlags.String(flagSubnetNodeSubnet, "", "ID of the subnet to manage nodes")
|
||||
_ = cmdSubnetNode.MarkFlagRequired(flagSubnetNodeSubnet)
|
||||
initSubnetNodeFlags()
|
||||
|
||||
// add all node managing commands to corresponding command section
|
||||
addCommandInheritPreRun(cmdSubnetNode,
|
||||
|
@ -726,10 +682,7 @@ func init() {
|
|||
cmdSubnetNodeRemove,
|
||||
)
|
||||
|
||||
// subnet global flags
|
||||
cmdSubnetFlags := cmdSubnet.PersistentFlags()
|
||||
cmdSubnetFlags.StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
_ = cmdSubnet.MarkFlagRequired(endpointFlag)
|
||||
initSubnetGlobalFlags()
|
||||
|
||||
// add all subnet commands to corresponding command section
|
||||
addCommandInheritPreRun(cmdSubnet,
|
||||
|
@ -742,6 +695,77 @@ func init() {
|
|||
)
|
||||
}
|
||||
|
||||
func initSubnetGlobalFlags() {
|
||||
cmdSubnetFlags := cmdSubnet.PersistentFlags()
|
||||
cmdSubnetFlags.StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
_ = cmdSubnet.MarkFlagRequired(endpointFlag)
|
||||
}
|
||||
|
||||
func initSubnetNodeFlags() {
|
||||
nodeFlags := cmdSubnetNode.PersistentFlags()
|
||||
nodeFlags.StringP(flagSubnetWallet, "w", "", "Path to file with wallet")
|
||||
_ = cmdSubnetNode.MarkFlagRequired(flagSubnetWallet)
|
||||
nodeFlags.String(flagSubnetNode, "", "Hex-encoded public key of the node")
|
||||
_ = cmdSubnetNode.MarkFlagRequired(flagSubnetNode)
|
||||
nodeFlags.String(flagSubnetNodeSubnet, "", "ID of the subnet to manage nodes")
|
||||
_ = cmdSubnetNode.MarkFlagRequired(flagSubnetNodeSubnet)
|
||||
}
|
||||
|
||||
func initClientManagementFlags() {
|
||||
clientFlags := cmdSubnetClient.PersistentFlags()
|
||||
clientFlags.String(flagSubnetClientSubnet, "", "ID of the subnet to be managed")
|
||||
_ = cmdSubnetClient.MarkFlagRequired(flagSubnetClientSubnet)
|
||||
clientFlags.String(flagSubnetClientGroup, "", "ID of the client group to work with")
|
||||
_ = cmdSubnetClient.MarkFlagRequired(flagSubnetClientGroup)
|
||||
clientFlags.String(flagSubnetClientID, "", "Client's user ID in FrostFS system in text format")
|
||||
_ = cmdSubnetClient.MarkFlagRequired(flagSubnetClientID)
|
||||
clientFlags.StringP(flagSubnetWallet, "w", "", "Path to file with wallet")
|
||||
_ = cmdSubnetClient.MarkFlagRequired(flagSubnetWallet)
|
||||
clientFlags.StringP(flagSubnetAddress, "a", "", "Address in the wallet, optional")
|
||||
}
|
||||
|
||||
func initSubnetAdminRemoveFlags() {
|
||||
cmdSubnetAdminRemoveFlags := cmdSubnetAdminRemove.Flags()
|
||||
cmdSubnetAdminRemoveFlags.Bool(flagSubnetAdminClient, false, "Remove client admin instead of node one")
|
||||
}
|
||||
|
||||
func initSubnetAdminAddFlags() {
|
||||
cmdSubnetAdminAddFlags := cmdSubnetAdminAdd.Flags()
|
||||
cmdSubnetAdminAddFlags.String(flagSubnetAdminAddGroup, "", fmt.Sprintf(
|
||||
"Client group ID in text format (needed with --%s only)", flagSubnetAdminClient))
|
||||
cmdSubnetAdminAddFlags.Bool(flagSubnetAdminClient, false, "Add client admin instead of node one")
|
||||
}
|
||||
|
||||
func initSubnetAdminFlags() {
|
||||
adminFlags := cmdSubnetAdmin.PersistentFlags()
|
||||
adminFlags.String(flagSubnetAdminSubnet, "", "ID of the subnet to manage administrators")
|
||||
_ = cmdSubnetAdmin.MarkFlagRequired(flagSubnetAdminSubnet)
|
||||
adminFlags.String(flagSubnetAdminID, "", "Hex-encoded public key of the admin")
|
||||
_ = cmdSubnetAdmin.MarkFlagRequired(flagSubnetAdminID)
|
||||
adminFlags.StringP(flagSubnetWallet, "w", "", "Path to file with wallet")
|
||||
_ = cmdSubnetAdmin.MarkFlagRequired(flagSubnetWallet)
|
||||
adminFlags.StringP(flagSubnetAddress, "a", "", "Address in the wallet, optional")
|
||||
}
|
||||
|
||||
func initRemoveSubnetFlags() {
|
||||
cmdSubnetRemove.Flags().String(flagSubnetRemoveID, "", "ID of the subnet to remove")
|
||||
_ = cmdSubnetRemove.MarkFlagRequired(flagSubnetRemoveID)
|
||||
cmdSubnetRemove.Flags().StringP(flagSubnetWallet, "w", "", "Path to file with wallet")
|
||||
_ = cmdSubnetRemove.MarkFlagRequired(flagSubnetWallet)
|
||||
cmdSubnetRemove.Flags().StringP(flagSubnetAddress, "a", "", "Address in the wallet, optional")
|
||||
}
|
||||
|
||||
func initGetSubnetFlags() {
|
||||
cmdSubnetGet.Flags().String(flagSubnetGetID, "", "ID of the subnet to read")
|
||||
_ = cmdSubnetAdminAdd.MarkFlagRequired(flagSubnetGetID)
|
||||
}
|
||||
|
||||
func initCreateSubnetFlags() {
|
||||
cmdSubnetCreate.Flags().StringP(flagSubnetWallet, "w", "", "Path to file with wallet")
|
||||
_ = cmdSubnetCreate.MarkFlagRequired(flagSubnetWallet)
|
||||
cmdSubnetCreate.Flags().StringP(flagSubnetAddress, "a", "", "Address in the wallet, optional")
|
||||
}
|
||||
|
||||
func testInvokeMethod(key keys.PrivateKey, method string, args ...any) ([]stackitem.Item, error) {
|
||||
c, err := getN3Client(viper.GetViper())
|
||||
if err != nil {
|
||||
|
@ -896,13 +920,7 @@ func invokeNotary(c Client, key keys.PrivateKey, method string, notaryHash util.
|
|||
return fmt.Errorf("subnet hash resolving: %w", err)
|
||||
}
|
||||
|
||||
// make test invocation of the method
|
||||
test, err := inv.Call(subnetHash, method, args...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("test invocation: %w", err)
|
||||
}
|
||||
|
||||
err = checkInvocationResults(test)
|
||||
test, err := makeTestInvocation(inv, subnetHash, method, args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -918,7 +936,26 @@ func invokeNotary(c Client, key keys.PrivateKey, method string, notaryHash util.
|
|||
return fmt.Errorf("blockchain height: %w", err)
|
||||
}
|
||||
|
||||
signersNumber := uint8(smartcontract.GetDefaultHonestNodeCount(len(alphabet)) + 1) // alphabet multisig + key signature
|
||||
return createAndPushTransaction(alphabet, test, bc, cosigners, c, key, multisigAccount)
|
||||
}
|
||||
|
||||
func makeTestInvocation(inv *invoker.Invoker, subnetHash util.Uint160, method string, args []any) (*result.Invoke, error) {
|
||||
test, err := inv.Call(subnetHash, method, args...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("test invocation: %w", err)
|
||||
}
|
||||
|
||||
err = checkInvocationResults(test)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return test, nil
|
||||
}
|
||||
|
||||
func createAndPushTransaction(alphabet keys.PublicKeys, test *result.Invoke, blockCount uint32, cosigners []transaction.Signer,
|
||||
client Client, key keys.PrivateKey, multisigAccount *wallet.Account) error {
|
||||
// alphabet multisig + key signature
|
||||
signersNumber := uint8(smartcontract.GetDefaultHonestNodeCount(len(alphabet)) + 1)
|
||||
|
||||
// notaryRequestValidity is number of blocks during
|
||||
// witch notary request is considered valid
|
||||
|
@ -927,7 +964,7 @@ func invokeNotary(c Client, key keys.PrivateKey, method string, notaryHash util.
|
|||
mainTx := &transaction.Transaction{
|
||||
Nonce: rand.Uint32(),
|
||||
SystemFee: test.GasConsumed,
|
||||
ValidUntilBlock: bc + notaryRequestValidity,
|
||||
ValidUntilBlock: blockCount + notaryRequestValidity,
|
||||
Script: test.Script,
|
||||
Attributes: []transaction.Attribute{
|
||||
{
|
||||
|
@ -938,7 +975,7 @@ func invokeNotary(c Client, key keys.PrivateKey, method string, notaryHash util.
|
|||
Signers: cosigners,
|
||||
}
|
||||
|
||||
notaryFee, err := c.CalculateNotaryFee(signersNumber)
|
||||
notaryFee, err := client.CalculateNotaryFee(signersNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -946,14 +983,14 @@ func invokeNotary(c Client, key keys.PrivateKey, method string, notaryHash util.
|
|||
acc := wallet.NewAccountFromPrivateKey(&key)
|
||||
aa := notaryAccounts(multisigAccount, acc)
|
||||
|
||||
err = c.AddNetworkFee(mainTx, notaryFee, aa...)
|
||||
err = client.AddNetworkFee(mainTx, notaryFee, aa...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("notary network fee adding: %w", err)
|
||||
}
|
||||
|
||||
mainTx.Scripts = notaryWitnesses(c, multisigAccount, acc, mainTx)
|
||||
mainTx.Scripts = notaryWitnesses(client, multisigAccount, acc, mainTx)
|
||||
|
||||
_, err = c.SignAndPushP2PNotaryRequest(mainTx,
|
||||
_, err = client.SignAndPushP2PNotaryRequest(mainTx,
|
||||
[]byte{byte(opcode.RET)},
|
||||
-1,
|
||||
0,
|
||||
|
|
|
@ -3,14 +3,14 @@ package modules
|
|||
import (
|
||||
"os"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/storagecfg"
|
||||
"github.com/TrueCloudLab/frostfs-node/misc"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/util/autocomplete"
|
||||
utilConfig "github.com/TrueCloudLab/frostfs-node/pkg/util/config"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/util/gendoc"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/storagecfg"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/misc"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/autocomplete"
|
||||
utilConfig "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/config"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/gendoc"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
"text/template"
|
||||
"time"
|
||||
|
||||
netutil "github.com/TrueCloudLab/frostfs-node/pkg/network"
|
||||
netutil "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/network"
|
||||
"github.com/chzyer/readline"
|
||||
"github.com/nspcc-dev/neo-go/cli/flags"
|
||||
"github.com/nspcc-dev/neo-go/cli/input"
|
||||
|
@ -80,15 +80,7 @@ type config struct {
|
|||
}
|
||||
|
||||
func storageConfig(cmd *cobra.Command, args []string) {
|
||||
var outPath string
|
||||
if len(args) != 0 {
|
||||
outPath = args[0]
|
||||
} else {
|
||||
outPath = getPath("File to write config at [./config.yml]: ")
|
||||
if outPath == "" {
|
||||
outPath = "./config.yml"
|
||||
}
|
||||
}
|
||||
outPath := getOutputPath(args)
|
||||
|
||||
historyPath := filepath.Join(os.TempDir(), "frostfs-adm.history")
|
||||
readline.SetHistoryPath(historyPath)
|
||||
|
@ -103,14 +95,7 @@ func storageConfig(cmd *cobra.Command, args []string) {
|
|||
w, err := wallet.NewWalletFromFile(c.Wallet.Path)
|
||||
fatalOnErr(err)
|
||||
|
||||
c.Wallet.Account, _ = cmd.Flags().GetString(accountFlag)
|
||||
if c.Wallet.Account == "" {
|
||||
addr := address.Uint160ToString(w.GetChangeAddress())
|
||||
c.Wallet.Account = getWalletAccount(w, fmt.Sprintf("Wallet account [%s]: ", addr))
|
||||
if c.Wallet.Account == "" {
|
||||
c.Wallet.Account = addr
|
||||
}
|
||||
}
|
||||
fillWalletAccount(cmd, &c, w)
|
||||
|
||||
accH, err := flags.ParseAddress(c.Wallet.Account)
|
||||
fatalOnErr(err)
|
||||
|
@ -128,32 +113,51 @@ func storageConfig(cmd *cobra.Command, args []string) {
|
|||
|
||||
c.AuthorizedKeys = append(c.AuthorizedKeys, hex.EncodeToString(acc.PrivateKey().PublicKey().Bytes()))
|
||||
|
||||
var network string
|
||||
for {
|
||||
network = getString("Choose network [mainnet]/testnet: ")
|
||||
switch network {
|
||||
case "":
|
||||
network = "mainnet"
|
||||
case "testnet", "mainnet":
|
||||
default:
|
||||
cmd.Println(`Network must be either "mainnet" or "testnet"`)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
network := readNetwork(cmd)
|
||||
|
||||
c.MorphRPC = n3config[network].MorphRPC
|
||||
|
||||
depositGas(cmd, acc, network)
|
||||
|
||||
c.Attribute.Locode = getString("UN-LOCODE attribute in [XX YYY] format: ")
|
||||
|
||||
endpoint := getDefaultEndpoint(cmd, &c)
|
||||
c.Endpoint = getString(fmt.Sprintf("Listening address [%s]: ", endpoint))
|
||||
if c.Endpoint == "" {
|
||||
c.Endpoint = endpoint
|
||||
}
|
||||
|
||||
c.ControlEndpoint = getString(fmt.Sprintf("Listening address (control endpoint) [%s]: ", defaultControlEndpoint))
|
||||
if c.ControlEndpoint == "" {
|
||||
c.ControlEndpoint = defaultControlEndpoint
|
||||
}
|
||||
|
||||
c.TLSCert = getPath("TLS Certificate (optional): ")
|
||||
if c.TLSCert != "" {
|
||||
c.TLSKey = getPath("TLS Key: ")
|
||||
}
|
||||
|
||||
c.Relay = getConfirmation(false, "Use node as a relay? yes/[no]: ")
|
||||
if !c.Relay {
|
||||
p := getPath("Path to the storage directory (all available storage will be used): ")
|
||||
c.BlobstorPath = filepath.Join(p, "blob")
|
||||
c.MetabasePath = filepath.Join(p, "meta")
|
||||
}
|
||||
|
||||
out := applyTemplate(c)
|
||||
fatalOnErr(os.WriteFile(outPath, out, 0644))
|
||||
|
||||
cmd.Println("Node is ready for work! Run `frostfs-node -config " + outPath + "`")
|
||||
}
|
||||
|
||||
func getDefaultEndpoint(cmd *cobra.Command, c *config) string {
|
||||
var addr, port string
|
||||
for {
|
||||
c.AnnouncedAddress = getString("Publicly announced address: ")
|
||||
validator := netutil.Address{}
|
||||
err := validator.FromString(c.AnnouncedAddress)
|
||||
if err != nil {
|
||||
cmd.Println("Incorrect address format. See https://github.com/TrueCloudLab/frostfs-node/blob/master/pkg/network/address.go for details.")
|
||||
cmd.Println("Incorrect address format. See https://git.frostfs.info/TrueCloudLab/frostfs-node/src/branch/master/pkg/network/address.go for details.")
|
||||
continue
|
||||
}
|
||||
uriAddr, err := url.Parse(validator.URIAddr())
|
||||
|
@ -182,34 +186,46 @@ func storageConfig(cmd *cobra.Command, args []string) {
|
|||
|
||||
break
|
||||
}
|
||||
return net.JoinHostPort(defaultDataEndpoint, port)
|
||||
}
|
||||
|
||||
defaultAddr := net.JoinHostPort(defaultDataEndpoint, port)
|
||||
c.Endpoint = getString(fmt.Sprintf("Listening address [%s]: ", defaultAddr))
|
||||
if c.Endpoint == "" {
|
||||
c.Endpoint = defaultAddr
|
||||
func fillWalletAccount(cmd *cobra.Command, c *config, w *wallet.Wallet) {
|
||||
c.Wallet.Account, _ = cmd.Flags().GetString(accountFlag)
|
||||
if c.Wallet.Account == "" {
|
||||
addr := address.Uint160ToString(w.GetChangeAddress())
|
||||
c.Wallet.Account = getWalletAccount(w, fmt.Sprintf("Wallet account [%s]: ", addr))
|
||||
if c.Wallet.Account == "" {
|
||||
c.Wallet.Account = addr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c.ControlEndpoint = getString(fmt.Sprintf("Listening address (control endpoint) [%s]: ", defaultControlEndpoint))
|
||||
if c.ControlEndpoint == "" {
|
||||
c.ControlEndpoint = defaultControlEndpoint
|
||||
func readNetwork(cmd *cobra.Command) string {
|
||||
var network string
|
||||
for {
|
||||
network = getString("Choose network [mainnet]/testnet: ")
|
||||
switch network {
|
||||
case "":
|
||||
network = "mainnet"
|
||||
case "testnet", "mainnet":
|
||||
default:
|
||||
cmd.Println(`Network must be either "mainnet" or "testnet"`)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
return network
|
||||
}
|
||||
|
||||
c.TLSCert = getPath("TLS Certificate (optional): ")
|
||||
if c.TLSCert != "" {
|
||||
c.TLSKey = getPath("TLS Key: ")
|
||||
func getOutputPath(args []string) string {
|
||||
if len(args) != 0 {
|
||||
return args[0]
|
||||
}
|
||||
|
||||
c.Relay = getConfirmation(false, "Use node as a relay? yes/[no]: ")
|
||||
if !c.Relay {
|
||||
p := getPath("Path to the storage directory (all available storage will be used): ")
|
||||
c.BlobstorPath = filepath.Join(p, "blob")
|
||||
c.MetabasePath = filepath.Join(p, "meta")
|
||||
outPath := getPath("File to write config at [./config.yml]: ")
|
||||
if outPath == "" {
|
||||
outPath = "./config.yml"
|
||||
}
|
||||
|
||||
out := applyTemplate(c)
|
||||
fatalOnErr(os.WriteFile(outPath, out, 0644))
|
||||
|
||||
cmd.Println("Node is ready for work! Run `frostfs-node -config " + outPath + "`")
|
||||
return outPath
|
||||
}
|
||||
|
||||
func getWalletAccount(w *wallet.Wallet, prompt string) string {
|
||||
|
|
|
@ -3,7 +3,7 @@ package main
|
|||
import (
|
||||
"os"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
|
@ -9,16 +9,16 @@ duplicated header names or headers with empty values are considered invalid.
|
|||
|
||||
## Existing headers
|
||||
|
||||
There are some "well-known" headers starting with `__FROSTFS__` prefix that
|
||||
There are some "well-known" headers starting with `__SYSTEM__` prefix that
|
||||
affect system behaviour. For backward compatibility, the same set of
|
||||
"well-known" headers may also use `__NEOFS__` prefix:
|
||||
|
||||
* `__FROSTFS__NETMAP_EPOCH` - netmap epoch to use for object placement calculation. The `value` is string
|
||||
* `__SYSTEM__NETMAP_EPOCH` - netmap epoch to use for object placement calculation. The `value` is string
|
||||
encoded `uint64` in decimal presentation. If set to '0' or omitted, the
|
||||
current epoch only will be used.
|
||||
* `__FROSTFS__NETMAP_LOOKUP_DEPTH` - if object can't be found using current epoch's netmap, this header limits
|
||||
* `__SYSTEM__NETMAP_LOOKUP_DEPTH` - if object can't be found using current epoch's netmap, this header limits
|
||||
how many past epochs the node can look up through. Depth is applied to a current epoch or the value
|
||||
of `__FROSTFS__NETMAP_EPOCH` attribute. The `value` is string encoded `uint64` in decimal presentation.
|
||||
of `__SYSTEM__NETMAP_EPOCH` attribute. The `value` is string encoded `uint64` in decimal presentation.
|
||||
If set to '0' or not set, only the current epoch is used.
|
||||
|
||||
## `frostfs-cli` commands with `--xhdr`
|
||||
|
@ -30,5 +30,5 @@ List of commands with support of extended headers:
|
|||
|
||||
Example:
|
||||
```shell
|
||||
$ frostfs-cli object put -r s01.frostfs.devenv:8080 -w wallet.json --cid CID --file FILE --xhdr "__FROSTFS__NETMAP_EPOCH=777"
|
||||
$ frostfs-cli object put -r s01.frostfs.devenv:8080 -w wallet.json --cid CID --file FILE --xhdr "__SYSTEM__NETMAP_EPOCH=777"
|
||||
```
|
||||
|
|
|
@ -7,15 +7,15 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/accounting"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/client"
|
||||
containerSDK "github.com/TrueCloudLab/frostfs-sdk-go/container"
|
||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/version"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/accounting"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||
containerSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version"
|
||||
)
|
||||
|
||||
// BalanceOfPrm groups parameters of BalanceOf operation.
|
||||
|
|
|
@ -3,11 +3,11 @@ package internal
|
|||
import (
|
||||
"io"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/client"
|
||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
|
||||
)
|
||||
|
||||
// here are small structures with public setters to share between parameter structures
|
||||
|
|
|
@ -8,11 +8,11 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/network"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/network"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
@ -48,7 +48,7 @@ func GetSDKClient(cmd *cobra.Command, key *ecdsa.PrivateKey, addr network.Addres
|
|||
)
|
||||
|
||||
prmInit.SetDefaultPrivateKey(*key)
|
||||
prmInit.ResolveNeoFSFailures()
|
||||
prmInit.ResolveFrostFSFailures()
|
||||
prmDial.SetServerURI(addr.URIAddr())
|
||||
if timeout := viper.GetDuration(commonflags.Timeout); timeout > 0 {
|
||||
// In CLI we can only set a timeout for the whole operation.
|
||||
|
|
|
@ -4,10 +4,10 @@ import (
|
|||
"errors"
|
||||
"os"
|
||||
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/core/version"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
versionSDK "github.com/TrueCloudLab/frostfs-sdk-go/version"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/version"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
versionSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/checksum"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/checksum"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/nspcc-dev/neo-go/cli/input"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
"github.com/spf13/cobra"
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"crypto/ecdsa"
|
||||
"errors"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"github.com/nspcc-dev/neo-go/cli/flags"
|
||||
"github.com/nspcc-dev/neo-go/cli/input"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package main
|
||||
|
||||
import cmd "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules"
|
||||
import cmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules"
|
||||
|
||||
func main() {
|
||||
cmd.Execute()
|
||||
|
|
|
@ -3,13 +3,13 @@ package accounting
|
|||
import (
|
||||
"math/big"
|
||||
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/util/precision"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/accounting"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/precision"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/accounting"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package accounting
|
||||
|
||||
import (
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package basic
|
||||
|
||||
import (
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -6,11 +6,11 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -26,18 +26,18 @@ Action is 'allow' or 'deny'.
|
|||
Operation is an object service verb: 'get', 'head', 'put', 'search', 'delete', 'getrange', or 'getrangehash'.
|
||||
|
||||
Filter consists of <typ>:<key><match><value>
|
||||
Typ is 'obj' for object applied filter or 'req' for request applied filter.
|
||||
Key is a valid unicode string corresponding to object or request header key.
|
||||
Typ is 'obj' for object applied filter or 'req' for request applied filter.
|
||||
Key is a valid unicode string corresponding to object or request header key.
|
||||
Well-known system object headers start with '$Object:' prefix.
|
||||
User defined headers start without prefix.
|
||||
Read more about filter keys at github.com/TrueCloudLab/frostfs-api/blob/master/proto-docs/acl.md#message-eaclrecordfilter
|
||||
Read more about filter keys at git.frostfs.info.com/TrueCloudLab/frostfs-api/src/branch/master/proto-docs/acl.md#message-eaclrecordfilter
|
||||
Match is '=' for matching and '!=' for non-matching filter.
|
||||
Value is a valid unicode string corresponding to object or request header value.
|
||||
|
||||
Target is
|
||||
'user' for container owner,
|
||||
Target is
|
||||
'user' for container owner,
|
||||
'system' for Storage nodes in container and Inner Ring nodes,
|
||||
'others' for all other request senders,
|
||||
'others' for all other request senders,
|
||||
'pubkey:<key1>,<key2>,...' for exact request sender, where <key> is a hex-encoded 33-byte public key.
|
||||
|
||||
When both '--rule' and '--file' arguments are used, '--rule' records will be placed higher in resulting extended ACL table.
|
||||
|
|
|
@ -3,8 +3,8 @@ package extended
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package acl
|
||||
|
||||
import (
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/acl/basic"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/acl/extended"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/acl/basic"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/acl/extended"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -7,13 +7,13 @@ import (
|
|||
"os"
|
||||
"time"
|
||||
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||
eaclSDK "github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||
eaclSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/util/autocomplete"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/autocomplete"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
|
|
@ -7,17 +7,17 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
containerApi "github.com/TrueCloudLab/frostfs-api-go/v2/container"
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/container"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
subnetid "github.com/TrueCloudLab/frostfs-sdk-go/subnet/id"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||
containerApi "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
subnetid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/subnet/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -37,7 +37,7 @@ var (
|
|||
var createContainerCmd = &cobra.Command{
|
||||
Use: "create",
|
||||
Short: "Create new container",
|
||||
Long: `Create new container and register it in the FrostFS.
|
||||
Long: `Create new container and register it in the FrostFS.
|
||||
It will be stored in sidechain when inner ring will accepts it.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
placementPolicy, err := parseContainerPolicy(cmd, containerPolicy)
|
||||
|
|
|
@ -4,20 +4,20 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
objectSDK "github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var deleteContainerCmd = &cobra.Command{
|
||||
Use: "delete",
|
||||
Short: "Delete existing container",
|
||||
Long: `Delete existing container.
|
||||
Long: `Delete existing container.
|
||||
Only owner of the container has a permission to remove container.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
id := parseContainerID(cmd)
|
||||
|
@ -77,8 +77,8 @@ Only owner of the container has a permission to remove container.`,
|
|||
|
||||
if len(res.IDList()) != 0 {
|
||||
commonCmd.ExitOnErr(cmd, "",
|
||||
fmt.Errorf("Container wasn't removed because LOCK objects were found.\n"+
|
||||
"Use --%s flag to remove anyway.", commonflags.ForceFlag))
|
||||
fmt.Errorf("container wasn't removed because LOCK objects were found, "+
|
||||
"use --%s flag to remove anyway", commonflags.ForceFlag))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,15 +4,15 @@ import (
|
|||
"crypto/ecdsa"
|
||||
"os"
|
||||
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/container"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -3,11 +3,11 @@ package container
|
|||
import (
|
||||
"os"
|
||||
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -3,12 +3,12 @@ package container
|
|||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-api-go/v2/container"
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -62,7 +62,7 @@ var listContainersCmd = &cobra.Command{
|
|||
res, err := internalclient.GetContainer(prmGet)
|
||||
if err == nil {
|
||||
res.Container().IterateAttributes(func(key, val string) {
|
||||
if !strings.HasPrefix(key, container.SysAttributePrefix) {
|
||||
if !strings.HasPrefix(key, container.SysAttributePrefix) && !strings.HasPrefix(key, container.SysAttributePrefixNeoFS) {
|
||||
// FIXME(@cthulhu-rider): neofs-sdk-go#314 use dedicated method to skip system attributes
|
||||
cmd.Printf(" %s: %s\n", key, val)
|
||||
}
|
||||
|
|
|
@ -3,14 +3,14 @@ package container
|
|||
import (
|
||||
"strings"
|
||||
|
||||
v2object "github.com/TrueCloudLab/frostfs-api-go/v2/object"
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
objectCli "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/object"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
v2object "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
objectCli "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/object"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -70,7 +70,7 @@ var listContainerObjectsCmd = &cobra.Command{
|
|||
attrs := resHead.Header().Attributes()
|
||||
for i := range attrs {
|
||||
attrKey := attrs[i].Key()
|
||||
if !strings.HasPrefix(attrKey, v2object.SysAttributePrefix) {
|
||||
if !strings.HasPrefix(attrKey, v2object.SysAttributePrefix) && !strings.HasPrefix(attrKey, v2object.SysAttributePrefixNeoFS) {
|
||||
// FIXME(@cthulhu-rider): neofs-sdk-go#226 use dedicated method to skip system attributes
|
||||
cmd.Printf(" %s: %s\n", attrKey, attrs[i].Value())
|
||||
}
|
||||
|
|
|
@ -3,13 +3,13 @@ package container
|
|||
import (
|
||||
"crypto/sha256"
|
||||
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
containerAPI "github.com/TrueCloudLab/frostfs-sdk-go/container"
|
||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
containerAPI "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package container
|
||||
|
||||
import (
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -5,11 +5,11 @@ import (
|
|||
"errors"
|
||||
"time"
|
||||
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -3,11 +3,11 @@ package container
|
|||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
53
cmd/frostfs-cli/modules/control/doctor.go
Normal file
53
cmd/frostfs-cli/modules/control/doctor.go
Normal file
|
@ -0,0 +1,53 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const (
|
||||
concurrencyFlag = "concurrency"
|
||||
removeDuplicatesFlag = "remove-duplicates"
|
||||
)
|
||||
|
||||
var doctorCmd = &cobra.Command{
|
||||
Use: "doctor",
|
||||
Short: "Restructure node's storage",
|
||||
Long: "Restructure node's storage",
|
||||
Run: doctor,
|
||||
}
|
||||
|
||||
func doctor(cmd *cobra.Command, _ []string) {
|
||||
pk := key.Get(cmd)
|
||||
|
||||
req := &control.DoctorRequest{Body: new(control.DoctorRequest_Body)}
|
||||
req.Body.Concurrency, _ = cmd.Flags().GetUint32(concurrencyFlag)
|
||||
req.Body.RemoveDuplicates, _ = cmd.Flags().GetBool(removeDuplicatesFlag)
|
||||
|
||||
signRequest(cmd, pk, req)
|
||||
|
||||
cli := getClient(cmd, pk)
|
||||
|
||||
var resp *control.DoctorResponse
|
||||
var err error
|
||||
err = cli.ExecRaw(func(client *client.Client) error {
|
||||
resp, err = control.Doctor(client, req)
|
||||
return err
|
||||
})
|
||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
||||
|
||||
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
||||
|
||||
cmd.Println("Operation has finished.")
|
||||
}
|
||||
|
||||
func initControlDoctorCmd() {
|
||||
initControlFlags(doctorCmd)
|
||||
|
||||
ff := doctorCmd.Flags()
|
||||
ff.Uint32(concurrencyFlag, 0, "Number of parallel threads to use")
|
||||
ff.Bool(removeDuplicatesFlag, false, "Remove duplicate objects")
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -3,13 +3,13 @@ package control
|
|||
import (
|
||||
"crypto/ecdsa"
|
||||
|
||||
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
ircontrol "github.com/TrueCloudLab/frostfs-node/pkg/services/control/ir"
|
||||
ircontrolsrv "github.com/TrueCloudLab/frostfs-node/pkg/services/control/ir/server"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/client"
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
ircontrol "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir"
|
||||
ircontrolsrv "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir/server"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
|
|
@ -3,12 +3,12 @@ package control
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ func initControlShardsCmd() {
|
|||
shardsCmd.AddCommand(restoreShardCmd)
|
||||
shardsCmd.AddCommand(evacuateShardCmd)
|
||||
shardsCmd.AddCommand(flushCacheCmd)
|
||||
shardsCmd.AddCommand(doctorCmd)
|
||||
|
||||
initControlShardsListCmd()
|
||||
initControlSetShardModeCmd()
|
||||
|
@ -24,4 +25,5 @@ func initControlShardsCmd() {
|
|||
initControlRestoreShardCmd()
|
||||
initControlEvacuateShardCmd()
|
||||
initControlFlushCacheCmd()
|
||||
initControlDoctorCmd()
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -6,11 +6,11 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
|
@ -4,13 +4,13 @@ import (
|
|||
"crypto/sha256"
|
||||
"errors"
|
||||
|
||||
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
controlSvc "github.com/TrueCloudLab/frostfs-node/pkg/services/control/server"
|
||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
controlSvc "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/server"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -4,13 +4,13 @@ import (
|
|||
"crypto/ecdsa"
|
||||
"errors"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
controlSvc "github.com/TrueCloudLab/frostfs-node/pkg/services/control/server"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/client"
|
||||
frostfscrypto "github.com/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
controlSvc "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/server"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package netmap
|
||||
|
||||
import (
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@ import (
|
|||
"encoding/hex"
|
||||
"time"
|
||||
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
|
@ -3,12 +3,12 @@ package netmap
|
|||
import (
|
||||
"encoding/hex"
|
||||
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package netmap
|
||||
|
||||
import (
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package netmap
|
||||
|
||||
import (
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -3,12 +3,12 @@ package object
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -6,13 +6,13 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"github.com/cheggaaa/pb"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
@ -48,20 +48,9 @@ func getObject(cmd *cobra.Command, _ []string) {
|
|||
|
||||
objAddr := readObjectAddress(cmd, &cnr, &obj)
|
||||
|
||||
var out io.Writer
|
||||
filename := cmd.Flag(fileFlag).Value.String()
|
||||
if filename == "" {
|
||||
out = os.Stdout
|
||||
} else {
|
||||
f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
||||
if err != nil {
|
||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("can't open file '%s': %w", filename, err))
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
out = f
|
||||
}
|
||||
out, closer := createOutWriter(cmd, filename)
|
||||
defer closer()
|
||||
|
||||
pk := key.GetOrGenerate(cmd)
|
||||
|
||||
|
@ -113,6 +102,10 @@ func getObject(cmd *cobra.Command, _ []string) {
|
|||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
||||
}
|
||||
|
||||
processResult(cmd, res, binary, payloadBuffer, out, filename)
|
||||
}
|
||||
|
||||
func processResult(cmd *cobra.Command, res *internalclient.GetObjectRes, binary bool, payloadBuffer *bytes.Buffer, out io.Writer, filename string) {
|
||||
if binary {
|
||||
objToStore := res.Header()
|
||||
// TODO(@acid-ant): #1932 Use streams to marshal/unmarshal payload
|
||||
|
@ -129,11 +122,29 @@ func getObject(cmd *cobra.Command, _ []string) {
|
|||
|
||||
// Print header only if file is not streamed to stdout.
|
||||
if filename != "" {
|
||||
err = printHeader(cmd, res.Header())
|
||||
err := printHeader(cmd, res.Header())
|
||||
commonCmd.ExitOnErr(cmd, "", err)
|
||||
}
|
||||
}
|
||||
|
||||
func createOutWriter(cmd *cobra.Command, filename string) (out io.Writer, closer func()) {
|
||||
if filename == "" {
|
||||
out = os.Stdout
|
||||
closer = func() {}
|
||||
} else {
|
||||
f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
||||
if err != nil {
|
||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("can't open file '%s': %w", filename, err))
|
||||
}
|
||||
|
||||
out = f
|
||||
closer = func() {
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func strictOutput(cmd *cobra.Command) bool {
|
||||
toJSON, _ := cmd.Flags().GetBool(commonflags.JSON)
|
||||
toProto, _ := cmd.Flags().GetBool("proto")
|
||||
|
|
|
@ -5,13 +5,13 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/checksum"
|
||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/checksum"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -6,16 +6,15 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
oidSDK "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -113,7 +112,7 @@ func marshalHeader(cmd *cobra.Command, hdr *object.Object) ([]byte, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func printObjectID(cmd *cobra.Command, recv func() (oidSDK.ID, bool)) {
|
||||
func printObjectID(cmd *cobra.Command, recv func() (oid.ID, bool)) {
|
||||
var strID string
|
||||
|
||||
id, ok := recv()
|
||||
|
|
|
@ -7,16 +7,16 @@ import (
|
|||
"strconv"
|
||||
"time"
|
||||
|
||||
objectV2 "github.com/TrueCloudLab/frostfs-api-go/v2/object"
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
objectSDK "github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -32,16 +32,35 @@ var objectLockCmd = &cobra.Command{
|
|||
err := cnr.DecodeString(cidRaw)
|
||||
commonCmd.ExitOnErr(cmd, "Incorrect container arg: %v", err)
|
||||
|
||||
key := key.GetOrGenerate(cmd)
|
||||
cli := internalclient.GetSDKClientByFlag(cmd, key, commonflags.RPC)
|
||||
|
||||
oidsRaw, _ := cmd.Flags().GetStringSlice(commonflags.OIDFlag)
|
||||
|
||||
lockList := make([]oid.ID, len(oidsRaw))
|
||||
lockList := make([]oid.ID, 0, len(oidsRaw))
|
||||
oidM := make(map[oid.ID]struct{})
|
||||
|
||||
for i := range oidsRaw {
|
||||
err = lockList[i].DecodeString(oidsRaw[i])
|
||||
for i, oidRaw := range oidsRaw {
|
||||
var oID oid.ID
|
||||
err = oID.DecodeString(oidRaw)
|
||||
commonCmd.ExitOnErr(cmd, fmt.Sprintf("Incorrect object arg #%d: %%v", i+1), err)
|
||||
}
|
||||
|
||||
key := key.GetOrGenerate(cmd)
|
||||
if _, ok := oidM[oID]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
lockList = append(lockList, oID)
|
||||
oidM[oID] = struct{}{}
|
||||
|
||||
for _, relative := range collectObjectRelatives(cmd, cli, cnr, oID) {
|
||||
if _, ok := oidM[relative]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
lockList = append(lockList, relative)
|
||||
oidM[relative] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
var idOwner user.ID
|
||||
user.IDFromKey(&idOwner, key.PublicKey)
|
||||
|
@ -81,7 +100,7 @@ var objectLockCmd = &cobra.Command{
|
|||
obj.SetPayload(lock.Marshal())
|
||||
|
||||
var prm internalclient.PutObjectPrm
|
||||
ReadOrOpenSession(cmd, &prm, key, cnr, nil)
|
||||
ReadOrOpenSessionViaClient(cmd, &prm, cli, key, cnr, nil)
|
||||
Prepare(cmd, &prm)
|
||||
prm.SetHeader(obj)
|
||||
|
||||
|
|
|
@ -10,14 +10,14 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
objectV2 "github.com/TrueCloudLab/frostfs-api-go/v2/object"
|
||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"github.com/cheggaaa/pb"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
@ -79,42 +79,13 @@ func putObject(cmd *cobra.Command, _ []string) {
|
|||
obj := object.New()
|
||||
|
||||
if binary {
|
||||
buf, err := os.ReadFile(filename)
|
||||
commonCmd.ExitOnErr(cmd, "unable to read given file: %w", err)
|
||||
objTemp := object.New()
|
||||
// TODO(@acid-ant): #1932 Use streams to marshal/unmarshal payload
|
||||
commonCmd.ExitOnErr(cmd, "can't unmarshal object from given file: %w", objTemp.Unmarshal(buf))
|
||||
payloadReader = bytes.NewReader(objTemp.Payload())
|
||||
cnr, _ = objTemp.ContainerID()
|
||||
ownerID = *objTemp.OwnerID()
|
||||
payloadReader, cnr, ownerID = readFilePayload(filename, cmd)
|
||||
} else {
|
||||
readCID(cmd, &cnr)
|
||||
user.IDFromKey(&ownerID, pk.PublicKey)
|
||||
}
|
||||
|
||||
attrs, err := parseObjectAttrs(cmd)
|
||||
commonCmd.ExitOnErr(cmd, "can't parse object attributes: %w", err)
|
||||
|
||||
expiresOn, _ := cmd.Flags().GetUint64(commonflags.ExpireAt)
|
||||
if expiresOn > 0 {
|
||||
var expAttrFound bool
|
||||
expAttrValue := strconv.FormatUint(expiresOn, 10)
|
||||
|
||||
for i := range attrs {
|
||||
if attrs[i].Key() == objectV2.SysAttributeExpEpoch {
|
||||
attrs[i].SetValue(expAttrValue)
|
||||
expAttrFound = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !expAttrFound {
|
||||
index := len(attrs)
|
||||
attrs = append(attrs, object.Attribute{})
|
||||
attrs[index].SetKey(objectV2.SysAttributeExpEpoch)
|
||||
attrs[index].SetValue(expAttrValue)
|
||||
}
|
||||
}
|
||||
attrs := getAllObjectAttributes(cmd)
|
||||
|
||||
obj.SetContainerID(cnr)
|
||||
obj.SetOwnerID(&ownerID)
|
||||
|
@ -139,23 +110,9 @@ func putObject(cmd *cobra.Command, _ []string) {
|
|||
prm.SetPayloadReader(payloadReader)
|
||||
} else {
|
||||
if binary {
|
||||
p = pb.New(len(obj.Payload()))
|
||||
p.Output = cmd.OutOrStdout()
|
||||
prm.SetPayloadReader(p.NewProxyReader(payloadReader))
|
||||
prm.SetHeaderCallback(func(o *object.Object) { p.Start() })
|
||||
p = setBinaryPayloadReader(cmd, obj, &prm, payloadReader)
|
||||
} else {
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
cmd.PrintErrf("Failed to get file size, progress bar is disabled: %v\n", err)
|
||||
prm.SetPayloadReader(f)
|
||||
} else {
|
||||
p = pb.New64(fi.Size())
|
||||
p.Output = cmd.OutOrStdout()
|
||||
prm.SetPayloadReader(p.NewProxyReader(f))
|
||||
prm.SetHeaderCallback(func(o *object.Object) {
|
||||
p.Start()
|
||||
})
|
||||
}
|
||||
p = setFilePayloadReader(cmd, f, &prm)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,6 +126,67 @@ func putObject(cmd *cobra.Command, _ []string) {
|
|||
cmd.Printf(" OID: %s\n CID: %s\n", res.ID(), cnr)
|
||||
}
|
||||
|
||||
func readFilePayload(filename string, cmd *cobra.Command) (io.Reader, cid.ID, user.ID) {
|
||||
buf, err := os.ReadFile(filename)
|
||||
commonCmd.ExitOnErr(cmd, "unable to read given file: %w", err)
|
||||
objTemp := object.New()
|
||||
// TODO(@acid-ant): #1932 Use streams to marshal/unmarshal payload
|
||||
commonCmd.ExitOnErr(cmd, "can't unmarshal object from given file: %w", objTemp.Unmarshal(buf))
|
||||
payloadReader := bytes.NewReader(objTemp.Payload())
|
||||
cnr, _ := objTemp.ContainerID()
|
||||
ownerID := *objTemp.OwnerID()
|
||||
return payloadReader, cnr, ownerID
|
||||
}
|
||||
|
||||
func setFilePayloadReader(cmd *cobra.Command, f *os.File, prm *internalclient.PutObjectPrm) *pb.ProgressBar {
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
cmd.PrintErrf("Failed to get file size, progress bar is disabled: %v\n", err)
|
||||
prm.SetPayloadReader(f)
|
||||
return nil
|
||||
}
|
||||
p := pb.New64(fi.Size())
|
||||
p.Output = cmd.OutOrStdout()
|
||||
prm.SetPayloadReader(p.NewProxyReader(f))
|
||||
prm.SetHeaderCallback(func(o *object.Object) { p.Start() })
|
||||
return p
|
||||
}
|
||||
|
||||
func setBinaryPayloadReader(cmd *cobra.Command, obj *object.Object, prm *internalclient.PutObjectPrm, payloadReader io.Reader) *pb.ProgressBar {
|
||||
p := pb.New(len(obj.Payload()))
|
||||
p.Output = cmd.OutOrStdout()
|
||||
prm.SetPayloadReader(p.NewProxyReader(payloadReader))
|
||||
prm.SetHeaderCallback(func(o *object.Object) { p.Start() })
|
||||
return p
|
||||
}
|
||||
|
||||
func getAllObjectAttributes(cmd *cobra.Command) []object.Attribute {
|
||||
attrs, err := parseObjectAttrs(cmd)
|
||||
commonCmd.ExitOnErr(cmd, "can't parse object attributes: %w", err)
|
||||
|
||||
expiresOn, _ := cmd.Flags().GetUint64(commonflags.ExpireAt)
|
||||
if expiresOn > 0 {
|
||||
var expAttrFound bool
|
||||
expAttrValue := strconv.FormatUint(expiresOn, 10)
|
||||
|
||||
for i := range attrs {
|
||||
if attrs[i].Key() == objectV2.SysAttributeExpEpoch {
|
||||
attrs[i].SetValue(expAttrValue)
|
||||
expAttrFound = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !expAttrFound {
|
||||
index := len(attrs)
|
||||
attrs = append(attrs, object.Attribute{})
|
||||
attrs[index].SetKey(objectV2.SysAttributeExpEpoch)
|
||||
attrs[index].SetValue(expAttrValue)
|
||||
}
|
||||
}
|
||||
return attrs
|
||||
}
|
||||
|
||||
func parseObjectAttrs(cmd *cobra.Command) ([]object.Attribute, error) {
|
||||
var rawAttrs []string
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue