forked from TrueCloudLab/frostfs-node
Compare commits
No commits in common. "plan-a" and "master" have entirely different histories.
959 changed files with 11716 additions and 17345 deletions
|
@ -1,25 +0,0 @@
|
||||||
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,5 +5,4 @@ docker-compose.yml
|
||||||
Dockerfile
|
Dockerfile
|
||||||
temp
|
temp
|
||||||
.dockerignore
|
.dockerignore
|
||||||
docker
|
docker
|
||||||
.cache
|
|
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
* @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
|
name: Bug report
|
||||||
about: Create a report to help us improve
|
about: Create a report to help us improve
|
||||||
title: ''
|
title: ''
|
||||||
labels: community, triage, bug
|
labels: community, triage
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -18,11 +18,8 @@ assignees: ''
|
||||||
If suggesting a change/improvement, explain the difference from current behavior -->
|
If suggesting a change/improvement, explain the difference from current behavior -->
|
||||||
|
|
||||||
## Possible Solution
|
## Possible Solution
|
||||||
<!-- Not obligatory
|
<!-- Not obligatory, but suggest a fix/reason for the bug,
|
||||||
If no reason/fix/additions for the bug can be suggested,
|
or ideas how to implement the addition or change -->
|
||||||
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)
|
## Steps to Reproduce (for bugs)
|
||||||
<!-- Provide a link to a live example, or an unambiguous set of steps
|
<!-- Provide a link to a live example, or an unambiguous set of steps
|
||||||
|
@ -44,3 +41,10 @@ assignees: ''
|
||||||
* Version used:
|
* Version used:
|
||||||
* Server setup and configuration:
|
* Server setup and configuration:
|
||||||
* Operating System and version (`uname -a`):
|
* 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
Normal file
29
.github/workflows/changelog.yml
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
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
Normal file
37
.github/workflows/config-update.yml
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
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
Normal file
22
.github/workflows/dco.yml
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
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
Normal file
60
.github/workflows/go.yml
vendored
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
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
11
.gitlint
|
@ -1,11 +0,0 @@
|
||||||
[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
|
# options for analysis running
|
||||||
run:
|
run:
|
||||||
# timeout for analysis, e.g. 30s, 5m, default is 1m
|
# timeout for analysis, e.g. 30s, 5m, default is 1m
|
||||||
timeout: 10m
|
timeout: 5m
|
||||||
|
|
||||||
# include test files or not, default is true
|
# include test files or not, default is true
|
||||||
tests: false
|
tests: false
|
||||||
|
@ -24,13 +24,6 @@ linters-settings:
|
||||||
govet:
|
govet:
|
||||||
# report about shadowed variables
|
# report about shadowed variables
|
||||||
check-shadowing: false
|
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:
|
linters:
|
||||||
enable:
|
enable:
|
||||||
|
@ -58,9 +51,6 @@ linters:
|
||||||
- predeclared
|
- predeclared
|
||||||
- reassign
|
- reassign
|
||||||
- whitespace
|
- whitespace
|
||||||
- containedctx
|
|
||||||
- funlen
|
|
||||||
- gocognit
|
|
||||||
- contextcheck
|
|
||||||
disable-all: true
|
disable-all: true
|
||||||
fast: false
|
fast: false
|
||||||
|
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
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
|
|
|
@ -1,11 +0,0 @@
|
||||||
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
|
|
1592
CHANGELOG.md
1592
CHANGELOG.md
File diff suppressed because it is too large
Load diff
|
@ -10,7 +10,7 @@ In alphabetical order:
|
||||||
- Alexey Vanin
|
- Alexey Vanin
|
||||||
- Anastasia Prasolova
|
- Anastasia Prasolova
|
||||||
- Anatoly Bogatyrev
|
- Anatoly Bogatyrev
|
||||||
- Evgeny Kulikov
|
- Evgeny Kulikov
|
||||||
- Evgeny Stratonikov
|
- Evgeny Stratonikov
|
||||||
- Leonard Liubich
|
- Leonard Liubich
|
||||||
- Sergei Liubich
|
- Sergei Liubich
|
||||||
|
|
20
Makefile
Executable file → Normal file
20
Makefile
Executable file → Normal file
|
@ -26,7 +26,7 @@ PKG_VERSION ?= $(shell echo $(VERSION) | sed "s/^v//" | \
|
||||||
sed "s/-/~/")-${OS_RELEASE}
|
sed "s/-/~/")-${OS_RELEASE}
|
||||||
|
|
||||||
.PHONY: help all images dep clean fmts fmt imports test lint docker/lint
|
.PHONY: help all images dep clean fmts fmt imports test lint docker/lint
|
||||||
prepare-release debpackage pre-commit unpre-commit
|
prepare-release debpackage
|
||||||
|
|
||||||
# To build a specific binary, use it's name prefix with bin/ as a target
|
# 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
|
# For example `make bin/frostfs-node` will build only storage node binary
|
||||||
|
@ -70,7 +70,7 @@ protoc:
|
||||||
@GOPRIVATE=github.com/TrueCloudLab go mod vendor
|
@GOPRIVATE=github.com/TrueCloudLab go mod vendor
|
||||||
# Install specific version for protobuf lib
|
# Install specific version for protobuf lib
|
||||||
@go list -f '{{.Path}}/...@{{.Version}}' -m github.com/golang/protobuf | xargs go install -v
|
@go list -f '{{.Path}}/...@{{.Version}}' -m github.com/golang/protobuf | xargs go install -v
|
||||||
@GOBIN=$(abspath $(BIN)) go install -mod=mod -v git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/protogen
|
@GOBIN=$(abspath $(BIN)) go install -mod=mod -v github.com/TrueCloudLab/frostfs-api-go/v2/util/protogen
|
||||||
# Protoc generate
|
# Protoc generate
|
||||||
@for f in `find . -type f -name '*.proto' -not -path './vendor/*'`; do \
|
@for f in `find . -type f -name '*.proto' -not -path './vendor/*'`; do \
|
||||||
echo "⇒ Processing $$f "; \
|
echo "⇒ Processing $$f "; \
|
||||||
|
@ -128,17 +128,10 @@ test:
|
||||||
@echo "⇒ Running go test"
|
@echo "⇒ Running go test"
|
||||||
@go test ./...
|
@go test ./...
|
||||||
|
|
||||||
pre-commit-run:
|
|
||||||
@pre-commit run -a --hook-stage manual
|
|
||||||
|
|
||||||
# Run linters
|
# Run linters
|
||||||
lint:
|
lint:
|
||||||
@golangci-lint --timeout=5m run
|
@golangci-lint --timeout=5m run
|
||||||
|
|
||||||
# Run staticcheck
|
|
||||||
staticcheck:
|
|
||||||
@staticcheck ./...
|
|
||||||
|
|
||||||
# Run linters in Docker
|
# Run linters in Docker
|
||||||
docker/lint:
|
docker/lint:
|
||||||
docker run --rm -t \
|
docker run --rm -t \
|
||||||
|
@ -147,19 +140,10 @@ docker/lint:
|
||||||
--env HOME=/src \
|
--env HOME=/src \
|
||||||
golangci/golangci-lint:v$(LINT_VERSION) bash -c 'cd /src/ && make lint'
|
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
|
# Print version
|
||||||
version:
|
version:
|
||||||
@echo $(VERSION)
|
@echo $(VERSION)
|
||||||
|
|
||||||
# Delete built artifacts
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf vendor
|
rm -rf vendor
|
||||||
rm -rf .cache
|
rm -rf .cache
|
||||||
|
|
|
@ -31,7 +31,7 @@ dApps directly from
|
||||||
code level. This way dApps are not limited to on-chain storage and can
|
code level. This way dApps are not limited to on-chain storage and can
|
||||||
manipulate large amounts of data without paying a prohibitive price.
|
manipulate large amounts of data without paying a prohibitive price.
|
||||||
|
|
||||||
FrostFS has a native [gRPC API](https://git.frostfs.info/TrueCloudLab/frostfs-api) and has
|
FrostFS has a native [gRPC API](https://github.com/TrueCloudLab/frostfs-api) and has
|
||||||
protocol gateways for popular protocols such as [AWS
|
protocol gateways for popular protocols such as [AWS
|
||||||
S3](https://github.com/TrueCloudLab/frostfs-s3-gw),
|
S3](https://github.com/TrueCloudLab/frostfs-s3-gw),
|
||||||
[HTTP](https://github.com/TrueCloudLab/frostfs-http-gw),
|
[HTTP](https://github.com/TrueCloudLab/frostfs-http-gw),
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
v0.36.0
|
v0.35.0
|
||||||
|
|
|
@ -3,22 +3,23 @@
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
Admin tool provides an easier way to deploy and maintain private installation
|
Admin tool provides an easier way to deploy and maintain private installation
|
||||||
of FrostFS. Private installation provides a set of N3 consensus nodes, FrostFS
|
of FrostFS. Private installation provides a set of N3 consensus nodes, FrostFS
|
||||||
Alphabet, and Storage nodes. Admin tool generates consensus keys, initializes
|
Alphabet, and Storage nodes. Admin tool generates consensus keys, initializes
|
||||||
the sidechain, and provides functions to update the network and register new
|
the sidechain, and provides functions to update the network and register new
|
||||||
Storage nodes.
|
Storage nodes.
|
||||||
|
|
||||||
## Build
|
## 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`.
|
Build docker image with `make image-adm`.
|
||||||
|
|
||||||
At FrostFS private install deployment, frostfs-adm requires compiled FrostFS
|
At FrostFS private install deployment, frostfs-adm requires compiled FrostFS
|
||||||
contracts. Find them in the latest release of
|
contracts. Find them in the latest release of
|
||||||
[frostfs-contract repository](https://git.frostfs.info/TrueCloudLab/frostfs-contract/releases).
|
[frostfs-contract repository](https://github.com/TrueCloudLab/frostfs-contract/releases).
|
||||||
|
|
||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ contracts. Find them in the latest release of
|
||||||
|
|
||||||
Config section provides `init` command that creates a configuration file for
|
Config section provides `init` command that creates a configuration file for
|
||||||
private installation deployment and updates. Config file is optional, all
|
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).
|
passwords).
|
||||||
|
|
||||||
Config example:
|
Config example:
|
||||||
|
@ -57,14 +58,14 @@ credentials: # passwords for consensus node / alphabet wallets
|
||||||
|
|
||||||
#### Network deployment
|
#### Network deployment
|
||||||
|
|
||||||
- `generate-alphabet` generates a set of wallets for consensus and
|
- `generate-alphabet` generates a set of wallets for consensus and
|
||||||
Alphabet nodes.
|
Alphabet nodes.
|
||||||
|
|
||||||
- `init` initializes the sidechain by deploying smart contracts and
|
- `init` initializes the sidechain by deploying smart contracts and
|
||||||
setting provided FrostFS network configuration.
|
setting provided FrostFS network configuration.
|
||||||
|
|
||||||
- `generate-storage-wallet` generates a wallet for the Storage node that
|
- `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
|
is ready for deployment. It also transfers a bit of sidechain GAS, so this
|
||||||
wallet can be used for FrostFS bootstrap.
|
wallet can be used for FrostFS bootstrap.
|
||||||
|
|
||||||
#### Network maintenance
|
#### Network maintenance
|
||||||
|
@ -74,7 +75,7 @@ credentials: # passwords for consensus node / alphabet wallets
|
||||||
- `force-new-epoch` increments FrostFS epoch number and executes new epoch
|
- `force-new-epoch` increments FrostFS epoch number and executes new epoch
|
||||||
handlers in FrostFS nodes.
|
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.
|
- `update-contracts` updates contracts to a new version.
|
||||||
|
|
||||||
|
@ -86,7 +87,7 @@ info. These commands **do not migrate actual objects**.
|
||||||
- `dump-containers` saves all containers and metadata registered in the container
|
- `dump-containers` saves all containers and metadata registered in the container
|
||||||
contract to a file.
|
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.
|
the container contract.
|
||||||
|
|
||||||
- `list-containers` output all containers ids.
|
- `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
|
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
|
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.
|
related configuration details.
|
||||||
|
|
||||||
## Prerequisites
|
## 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 [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).
|
- 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
|
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
|
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 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.
|
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
|
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
|
$ frostfs-adm config init --path foo.network.yml
|
||||||
Initial config file saved to 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
|
rpc-endpoint: https://neo.rpc.node:30333
|
||||||
alphabet-wallets: /home/user/deploy/alphabet-wallets
|
alphabet-wallets: /home/user/deploy/alphabet-wallets
|
||||||
network:
|
network:
|
||||||
|
@ -43,17 +43,17 @@ credentials:
|
||||||
az: hunter2
|
az: hunter2
|
||||||
```
|
```
|
||||||
|
|
||||||
For private installation, it is recommended to set all **fees** and **basic
|
For private installation, it is recommended to set all **fees** and **basic
|
||||||
income rate** to 0.
|
income rate** to 0.
|
||||||
|
|
||||||
As for **epoch duration**, consider consensus node block generation frequency.
|
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.
|
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.
|
good chunk distribution in most cases.
|
||||||
|
|
||||||
With this config, generate wallets (private keys) of consensus nodes. The same
|
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.
|
wallets already exists.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -69,14 +69,14 @@ storage.
|
||||||
## Step 2: Launch consensus nodes
|
## Step 2: Launch consensus nodes
|
||||||
|
|
||||||
Configure blockchain nodes with the generated wallets from the previous step.
|
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).
|
[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
|
Gather public keys from **all** generated wallets. We are interested in the first
|
||||||
`simple signature contract` public key.
|
`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):
|
NitdS4k4f1Hh5mbLJhAswBK3WC2gQgPN1o (simple signature contract):
|
||||||
02c1cc85f9c856dbe2d02017349bcb7b4e5defa78b8056a09b3240ba2a8c078869
|
02c1cc85f9c856dbe2d02017349bcb7b4e5defa78b8056a09b3240ba2a8c078869
|
||||||
|
|
||||||
|
@ -87,10 +87,10 @@ NiMKabp3ddi3xShmLAXhTfbnuWb4cSJT6E (1 out of 1 multisig contract):
|
||||||
02c1cc85f9c856dbe2d02017349bcb7b4e5defa78b8056a09b3240ba2a8c078869
|
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`
|
section. Specify the wallet path and the password in `ApplicationConfiguration.P2PNotary`
|
||||||
and `ApplicationConfiguration.UnlockWallet` sections. If config includes
|
and `ApplicationConfiguration.UnlockWallet` sections. If config includes
|
||||||
`ProtocolConfiguration.NativeActivations` section, add notary
|
`ProtocolConfiguration.NativeActivations` section, add notary
|
||||||
contract `Notary: [0]`.
|
contract `Notary: [0]`.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
@ -121,7 +121,7 @@ and possible overload issues.
|
||||||
Use archive with compiled FrostFS contracts to initialize the sidechain.
|
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
|
$ ./frostfs-adm -c foo.network.yml morph init --contracts ./frostfs-contract-v0.11.0
|
||||||
Stage 1: transfer GAS to alphabet nodes.
|
Stage 1: transfer GAS to alphabet nodes.
|
||||||
|
@ -153,8 +153,8 @@ Waiting for transactions to persist...
|
||||||
|
|
||||||
## Step 4: Launch Alphabet nodes
|
## Step 4: Launch Alphabet nodes
|
||||||
|
|
||||||
Configure Alphabet nodes with the wallets generated in step 1. For
|
Configure Alphabet nodes with the wallets generated in step 1. For
|
||||||
`morph.validators` use a list of public keys from
|
`morph.validators` use a list of public keys from
|
||||||
`ProtocolConfiguration.StandbyCommittee`.
|
`ProtocolConfiguration.StandbyCommittee`.
|
||||||
|
|
||||||
```yaml
|
```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
|
$ 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...
|
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):
|
Ngr7p8Z9S22XDH6VkUG9oXobv8zZRAWwwv (simple signature contract):
|
||||||
0355eccb72cd46f09a3e5237eaa0f4949cceb5ecfa5a225bd3bb9fd021c4d75b85
|
0355eccb72cd46f09a3e5237eaa0f4949cceb5ecfa5a225bd3bb9fd021c4d75b85
|
||||||
```
|
```
|
||||||
|
@ -205,7 +205,7 @@ Current epoch: 8, increase to 9.
|
||||||
Waiting for transactions to persist...
|
Waiting for transactions to persist...
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
After that, FrostFS Storage is ready to work. You can access it directly or
|
After that, FrostFS Storage is ready to work. You can access it directly or
|
||||||
with protocol gates.
|
with protocol gates.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# FrostFS subnetwork creation
|
# FrostFS subnetwork creation
|
||||||
|
|
||||||
This is a short guide on how to create FrostFS subnetworks. This guide
|
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
|
considers that the sidechain and the inner ring (alphabet nodes) have already been
|
||||||
deployed and the sidechain contains a deployed `subnet` contract.
|
deployed and the sidechain contains a deployed `subnet` contract.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
|
@ -88,11 +88,11 @@ has been added by the subnet owner).
|
||||||
|
|
||||||
# Bootstrapping Storage Node
|
# 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.
|
node could be bootstrapped and service subnetwork containers.
|
||||||
|
|
||||||
For bootstrapping, you need to specify the ID of the subnetwork in the node's
|
For bootstrapping, you need to specify the ID of the subnetwork in the node's
|
||||||
configuration:
|
configuration:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
...
|
...
|
||||||
|
@ -106,7 +106,7 @@ node:
|
||||||
```
|
```
|
||||||
|
|
||||||
**NOTE:** specifying subnetwork that is denied for the node is not an error:
|
**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
|
(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:
|
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 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.
|
creating container in the zero subnetwork.
|
||||||
|
|
||||||
To create a container in a private network, your wallet must be added to
|
To create a container in a private network, your wallet must be added to
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
|
"github.com/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||||
"github.com/nspcc-dev/neo-go/cli/input"
|
"github.com/nspcc-dev/neo-go/cli/input"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
|
"github.com/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,8 +6,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
|
"github.com/TrueCloudLab/frostfs-contract/nns"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
"github.com/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/native/noderoles"
|
"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/core/state"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
@ -83,110 +83,86 @@ func dumpBalances(cmd *cobra.Command, _ []string) error {
|
||||||
printBalances(cmd, "Inner ring nodes balances:", irList)
|
printBalances(cmd, "Inner ring nodes balances:", irList)
|
||||||
|
|
||||||
if dumpStorage {
|
if dumpStorage {
|
||||||
if err := printStorageNodeBalances(cmd, inv, nmHash); err != nil {
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
printBalances(cmd, "\nStorage node balances:", snList)
|
||||||
}
|
}
|
||||||
|
|
||||||
if dumpProxy {
|
if dumpProxy {
|
||||||
if err := printProxyContractBalance(cmd, inv, nnsCs.Hash); err != nil {
|
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 {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
printBalances(cmd, "\nProxy contract balance:", proxyList)
|
||||||
}
|
}
|
||||||
|
|
||||||
if dumpAlphabet {
|
if dumpAlphabet {
|
||||||
if err := printAlphabetContractBalances(cmd, c, inv, len(irList), nnsCs.Hash); err != nil {
|
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 {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
printBalances(cmd, "\nAlphabet contracts balances:", alphaList)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
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) {
|
func fetchIRNodes(c Client, nmHash, desigHash util.Uint160) ([]accBalancePair, error) {
|
||||||
var irList []accBalancePair
|
var irList []accBalancePair
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"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/invoker"
|
||||||
|
@ -41,28 +41,16 @@ func getContainerContractHash(cmd *cobra.Command, inv *invoker.Invoker, c Client
|
||||||
return ch, nil
|
return ch, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func iterateContainerList(inv *invoker.Invoker, ch util.Uint160, f func([]byte) error) error {
|
func getContainersList(inv *invoker.Invoker, ch util.Uint160) ([][]byte, error) {
|
||||||
sid, r, err := unwrap.SessionIterator(inv.Call(ch, "containersOf", ""))
|
res, err := inv.Call(ch, "list", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
|
return nil, fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
|
||||||
}
|
}
|
||||||
// Nothing bad, except live session on the server, do not report to the user.
|
itm, err := unwrap.Item(res, err)
|
||||||
defer func() { _ = inv.TerminateSession(sid) }()
|
if _, ok := itm.(stackitem.Null); !ok {
|
||||||
|
return unwrap.ArrayOfBytes(res, err)
|
||||||
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 err
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func dumpContainers(cmd *cobra.Command, _ []string) error {
|
func dumpContainers(cmd *cobra.Command, _ []string) error {
|
||||||
|
@ -83,81 +71,56 @@ func dumpContainers(cmd *cobra.Command, _ []string) error {
|
||||||
return fmt.Errorf("unable to get contaract hash: %w", err)
|
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)
|
isOK, err := getCIDFilterFunc(cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := os.OpenFile(filename, os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0o660)
|
var containers []*Container
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
_, err = f.Write([]byte{'['})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
written := 0
|
|
||||||
enc := json.NewEncoder(f)
|
|
||||||
bw := io.NewBufBinWriter()
|
bw := io.NewBufBinWriter()
|
||||||
iterErr := iterateContainerList(inv, ch, func(id []byte) error {
|
for _, id := range cids {
|
||||||
if !isOK(id) {
|
if !isOK(id) {
|
||||||
return nil
|
continue
|
||||||
}
|
}
|
||||||
|
bw.Reset()
|
||||||
cnt, err := dumpSingleContainer(bw, ch, inv, id)
|
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 {
|
if err != nil {
|
||||||
return err
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Writing directly to the file is ok, because json.Encoder does no internal buffering.
|
cnt := new(Container)
|
||||||
if written != 0 {
|
err = cnt.FromStackItem(res.Stack[0])
|
||||||
_, err = f.Write([]byte{','})
|
if err != nil {
|
||||||
if err != nil {
|
return fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
written++
|
ea := new(EACL)
|
||||||
return enc.Encode(cnt)
|
err = ea.FromStackItem(res.Stack[1])
|
||||||
})
|
if err != nil {
|
||||||
if iterErr != nil {
|
return fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
|
||||||
return iterErr
|
}
|
||||||
|
if len(ea.Value) != 0 {
|
||||||
|
cnt.EACL = ea
|
||||||
|
}
|
||||||
|
|
||||||
|
containers = append(containers, cnt)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = f.Write([]byte{']'})
|
out, err := json.Marshal(containers)
|
||||||
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't get container info: %w", err)
|
return err
|
||||||
}
|
}
|
||||||
if len(res.Stack) != 2 {
|
return os.WriteFile(filename, out, 0o660)
|
||||||
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 {
|
func listContainers(cmd *cobra.Command, _ []string) error {
|
||||||
|
@ -173,15 +136,20 @@ func listContainers(cmd *cobra.Command, _ []string) error {
|
||||||
return fmt.Errorf("unable to get contaract hash: %w", err)
|
return fmt.Errorf("unable to get contaract hash: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return iterateContainerList(inv, ch, func(id []byte) error {
|
cids, err := getContainersList(inv, ch)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, id := range cids {
|
||||||
var idCnr cid.ID
|
var idCnr cid.ID
|
||||||
err = idCnr.Decode(id)
|
err = idCnr.Decode(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to decode container id: %w", err)
|
return fmt.Errorf("unable to decode container id: %w", err)
|
||||||
}
|
}
|
||||||
cmd.Println(idCnr)
|
cmd.Println(idCnr)
|
||||||
return nil
|
}
|
||||||
})
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func restoreContainers(cmd *cobra.Command, _ []string) error {
|
func restoreContainers(cmd *cobra.Command, _ []string) error {
|
||||||
|
@ -196,14 +164,25 @@ func restoreContainers(cmd *cobra.Command, _ []string) error {
|
||||||
}
|
}
|
||||||
defer wCtx.close()
|
defer wCtx.close()
|
||||||
|
|
||||||
containers, err := parseContainers(filename)
|
nnsCs, err := wCtx.Client.GetContractStateByID(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("can't get NNS contract state: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ch, err := fetchContainerContractHash(wCtx)
|
ch, err := nnsResolveHash(wCtx.ReadOnlyInvoker, nnsCs.Hash, containerContract+".frostfs")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
isOK, err := getCIDFilterFunc(cmd)
|
isOK, err := getCIDFilterFunc(cmd)
|
||||||
|
@ -211,15 +190,6 @@ func restoreContainers(cmd *cobra.Command, _ []string) error {
|
||||||
return err
|
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()
|
bw := io.NewBufBinWriter()
|
||||||
for _, cnt := range containers {
|
for _, cnt := range containers {
|
||||||
hv := hash.Sha256(cnt.Value)
|
hv := hash.Sha256(cnt.Value)
|
||||||
|
@ -227,18 +197,33 @@ func restoreOrPutContainers(containers []Container, isOK func([]byte) bool, cmd
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
bw.Reset()
|
bw.Reset()
|
||||||
restored, err := isContainerRestored(cmd, wCtx, ch, bw, hv)
|
emit.AppCall(bw.BinWriter, ch, "get", callflag.All, hv.BytesBE())
|
||||||
|
res, err := wCtx.Client.InvokeScript(bw.Bytes(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("can't check if container is already restored: %w", err)
|
||||||
}
|
}
|
||||||
if restored {
|
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)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
bw.Reset()
|
bw.Reset()
|
||||||
|
emit.AppCall(bw.BinWriter, ch, "put", callflag.All,
|
||||||
putContainer(bw, ch, cnt)
|
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)
|
||||||
|
}
|
||||||
if bw.Err != nil {
|
if bw.Err != nil {
|
||||||
panic(bw.Err)
|
panic(bw.Err)
|
||||||
}
|
}
|
||||||
|
@ -247,67 +232,8 @@ func restoreOrPutContainers(containers []Container, isOK func([]byte) bool, cmd
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func putContainer(bw *io.BufBinWriter, ch util.Uint160, cnt Container) {
|
return wCtx.awaitTx()
|
||||||
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.
|
// Container represents container struct in contract storage.
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
|
"github.com/TrueCloudLab/frostfs-contract/nns"
|
||||||
"github.com/nspcc-dev/neo-go/cli/cmdargs"
|
"github.com/nspcc-dev/neo-go/cli/cmdargs"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||||
|
@ -100,88 +100,80 @@ func deployContractCmd(cmd *cobra.Command, args []string) error {
|
||||||
cs.Manifest.Name)
|
cs.Manifest.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
writer := io.NewBufBinWriter()
|
w := io.NewBufBinWriter()
|
||||||
if err := emitDeploymentArguments(writer.BinWriter, args); err != nil {
|
if err := emitDeploymentArguments(w.BinWriter, args); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
emit.Bytes(writer.BinWriter, cs.RawManifest)
|
emit.Bytes(w.BinWriter, cs.RawManifest)
|
||||||
emit.Bytes(writer.BinWriter, cs.RawNEF)
|
emit.Bytes(w.BinWriter, cs.RawNEF)
|
||||||
emit.Int(writer.BinWriter, 3)
|
emit.Int(w.BinWriter, 3)
|
||||||
emit.Opcodes(writer.BinWriter, opcode.PACK)
|
emit.Opcodes(w.BinWriter, opcode.PACK)
|
||||||
emit.AppCallNoArgs(writer.BinWriter, callHash, method, callflag.All)
|
emit.AppCallNoArgs(w.BinWriter, callHash, method, callflag.All)
|
||||||
emit.Opcodes(writer.BinWriter, opcode.DROP) // contract state on stack
|
emit.Opcodes(w.BinWriter, opcode.DROP) // contract state on stack
|
||||||
if !isUpdate {
|
if !isUpdate {
|
||||||
err := registerNNS(nnsCs, c, zone, domain, cs, writer)
|
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 {
|
if err != nil {
|
||||||
return err
|
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 writer.Err != nil {
|
if w.Err != nil {
|
||||||
panic(fmt.Errorf("BUG: can't create deployment script: %w", writer.Err))
|
panic(fmt.Errorf("BUG: can't create deployment script: %w", w.Err))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.sendCommitteeTx(writer.Bytes(), false); err != nil {
|
if err := c.sendCommitteeTx(w.Bytes(), false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return c.awaitTx()
|
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 {
|
func emitDeploymentArguments(w *io.BinWriter, args []string) error {
|
||||||
_, ps, err := cmdargs.ParseParams(args, true)
|
_, ps, err := cmdargs.ParseParams(args, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -7,8 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
|
"github.com/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/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
|
||||||
|
@ -124,7 +123,7 @@ func dumpCustomZoneHashes(cmd *cobra.Command, nnsHash util.Uint160, zone string,
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bytes.HasSuffix(bs, []byte(zone)) || bytes.HasPrefix(bs, []byte(morphClient.NNSGroupKeyName)) {
|
if !bytes.HasSuffix(bs, []byte(zone)) {
|
||||||
// Related https://github.com/nspcc-dev/neofs-contract/issues/316.
|
// Related https://github.com/nspcc-dev/neofs-contract/issues/316.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,8 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
|
"github.com/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"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/address"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
|
"github.com/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||||
"github.com/nspcc-dev/neo-go/cli/input"
|
"github.com/nspcc-dev/neo-go/cli/input"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
"github.com/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/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
|
|
@ -7,9 +7,9 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
|
"github.com/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||||
morphClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
morphClient "github.com/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
"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/state"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
|
@ -118,14 +118,24 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex
|
||||||
needContracts := cmd.Name() == "update-contracts" || cmd.Name() == "init"
|
needContracts := cmd.Name() == "update-contracts" || cmd.Name() == "init"
|
||||||
|
|
||||||
var w *wallet.Wallet
|
var w *wallet.Wallet
|
||||||
w, err = getWallet(cmd, v, needContracts, walletDir)
|
if needContracts {
|
||||||
if err != nil {
|
w, err = openContractWallet(v, cmd, walletDir)
|
||||||
return nil, err
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c, err := createClient(cmd, v, wallets)
|
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)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("can't create N3 client: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
committeeAcc, err := getWalletAccount(wallets[0], committeeAccountName)
|
committeeAcc, err := getWalletAccount(wallets[0], committeeAccountName)
|
||||||
|
@ -138,22 +148,35 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex
|
||||||
return nil, fmt.Errorf("can't find consensus account: %w", err)
|
return nil, fmt.Errorf("can't find consensus account: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := validateInit(cmd); err != nil {
|
var ctrPath string
|
||||||
return nil, err
|
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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctrPath, err := getContractsPath(cmd, v, needContracts)
|
if needContracts {
|
||||||
if err != nil {
|
ctrPath, err = cmd.Flags().GetString(contractsInitFlag)
|
||||||
return nil, err
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("invalid contracts path: %w", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := checkNotaryEnabled(c); err != nil {
|
if err := checkNotaryEnabled(c); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
accounts, err := createWalletAccounts(wallets)
|
accounts := make([]*wallet.Account, len(wallets))
|
||||||
if err != nil {
|
for i, w := range wallets {
|
||||||
return nil, err
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
cliCtx, err := defaultClientContext(c, committeeAcc)
|
cliCtx, err := defaultClientContext(c, committeeAcc)
|
||||||
|
@ -183,69 +206,6 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex
|
||||||
return initCtx, nil
|
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) {
|
func openAlphabetWallets(v *viper.Viper, walletDir string) ([]*wallet.Wallet, error) {
|
||||||
walletFiles, err := os.ReadDir(walletDir)
|
walletFiles, err := os.ReadDir(walletDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -12,10 +12,10 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-contract/common"
|
"github.com/TrueCloudLab/frostfs-contract/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
|
"github.com/TrueCloudLab/frostfs-contract/nns"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
|
"github.com/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||||
morphClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
morphClient "github.com/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"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/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||||
|
@ -167,6 +167,8 @@ func (c *initializeContext) updateContracts() error {
|
||||||
|
|
||||||
w := io2.NewBufBinWriter()
|
w := io2.NewBufBinWriter()
|
||||||
|
|
||||||
|
var keysParam []any
|
||||||
|
|
||||||
// Update script size for a single-node committee is close to the maximum allowed size of 65535.
|
// 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.
|
// Because of this we want to reuse alphabet contract NEF and manifest for different updates.
|
||||||
// The generated script is as following.
|
// The generated script is as following.
|
||||||
|
@ -180,36 +182,42 @@ func (c *initializeContext) updateContracts() error {
|
||||||
emit.Bytes(w.BinWriter, alphaCs.RawNEF)
|
emit.Bytes(w.BinWriter, alphaCs.RawNEF)
|
||||||
emit.Opcodes(w.BinWriter, opcode.STSFLD0)
|
emit.Opcodes(w.BinWriter, opcode.STSFLD0)
|
||||||
|
|
||||||
keysParam, err := c.deployAlphabetAccounts(nnsHash, w, alphaCs)
|
baseGroups := alphaCs.Manifest.Groups
|
||||||
if err != nil {
|
|
||||||
return err
|
// 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.")
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Reset()
|
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.Instruction(w.BinWriter, opcode.INITSSLOT, []byte{1})
|
||||||
emit.AppCall(w.BinWriter, nnsHash, "getPrice", callflag.All)
|
emit.AppCall(w.BinWriter, nnsHash, "getPrice", callflag.All)
|
||||||
emit.Opcodes(w.BinWriter, opcode.STSFLD0)
|
emit.Opcodes(w.BinWriter, opcode.STSFLD0)
|
||||||
|
@ -269,46 +277,23 @@ func (c *initializeContext) deployOrUpdateContracts(w *io2.BufBinWriter, nnsHash
|
||||||
c.Command.Printf("NNS: Set %s -> %s\n", domain, cs.Hash.StringLE())
|
c.Command.Printf("NNS: Set %s -> %s\n", domain, cs.Hash.StringLE())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *initializeContext) deployAlphabetAccounts(nnsHash util.Uint160, w *io2.BufBinWriter, alphaCs *contractState) ([]any, error) {
|
groupKey := c.ContractWallet.Accounts[0].PrivateKey().PublicKey()
|
||||||
var keysParam []any
|
_, _, err = c.emitUpdateNNSGroupScript(w, nnsHash, groupKey)
|
||||||
|
if err != nil {
|
||||||
baseGroups := alphaCs.Manifest.Groups
|
return err
|
||||||
|
|
||||||
// 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 {
|
if err := c.sendCommitteeTx(w.Bytes(), false); err != nil {
|
||||||
if !strings.Contains(err.Error(), common.ErrAlreadyUpdated) {
|
return err
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
c.Command.Println("Alphabet contracts are already updated.")
|
|
||||||
}
|
}
|
||||||
|
return c.awaitTx()
|
||||||
return keysParam, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) deployContracts() error {
|
func (c *initializeContext) deployContracts() error {
|
||||||
|
|
|
@ -7,15 +7,14 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
|
"github.com/TrueCloudLab/frostfs-contract/nns"
|
||||||
morphClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
morphClient "github.com/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"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/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
||||||
nnsClient "github.com/nspcc-dev/neo-go/pkg/rpcclient/nns"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
@ -83,13 +82,13 @@ func (c *initializeContext) setNNS() error {
|
||||||
|
|
||||||
func (c *initializeContext) updateNNSGroup(nnsHash util.Uint160, pub *keys.PublicKey) error {
|
func (c *initializeContext) updateNNSGroup(nnsHash util.Uint160, pub *keys.PublicKey) error {
|
||||||
bw := io.NewBufBinWriter()
|
bw := io.NewBufBinWriter()
|
||||||
keyAlreadyAdded, domainRegCodeEmitted, err := c.emitUpdateNNSGroupScript(bw, nnsHash, pub)
|
needUpdate, needRegister, err := c.emitUpdateNNSGroupScript(bw, nnsHash, pub)
|
||||||
if keyAlreadyAdded || err != nil {
|
if !needUpdate || err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
script := bw.Bytes()
|
script := bw.Bytes()
|
||||||
if domainRegCodeEmitted {
|
if needRegister {
|
||||||
w := io.NewBufBinWriter()
|
w := io.NewBufBinWriter()
|
||||||
emit.Instruction(w.BinWriter, opcode.INITSSLOT, []byte{1})
|
emit.Instruction(w.BinWriter, opcode.INITSSLOT, []byte{1})
|
||||||
wrapRegisterScriptWithPrice(w, nnsHash, script)
|
wrapRegisterScriptWithPrice(w, nnsHash, script)
|
||||||
|
@ -229,27 +228,20 @@ func nnsResolve(inv *invoker.Invoker, nnsHash util.Uint160, domain string) (stac
|
||||||
}
|
}
|
||||||
|
|
||||||
func nnsResolveKey(inv *invoker.Invoker, nnsHash util.Uint160, domain string) (*keys.PublicKey, error) {
|
func nnsResolveKey(inv *invoker.Invoker, nnsHash util.Uint160, domain string) (*keys.PublicKey, error) {
|
||||||
res, err := nnsResolve(inv, nnsHash, domain)
|
item, err := nnsResolve(inv, nnsHash, domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if _, ok := res.Value().(stackitem.Null); ok {
|
v, ok := item.Value().(stackitem.Null)
|
||||||
|
if ok {
|
||||||
return nil, errors.New("NNS record is missing")
|
return nil, errors.New("NNS record is missing")
|
||||||
}
|
}
|
||||||
arr, ok := res.Value().([]stackitem.Item)
|
bs, err := v.TryBytes()
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, errors.New("API of the NNS contract method `resolve` has changed")
|
return nil, errors.New("malformed response")
|
||||||
}
|
}
|
||||||
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.
|
// parseNNSResolveResult parses the result of resolving NNS record.
|
||||||
|
@ -285,11 +277,9 @@ func parseNNSResolveResult(res stackitem.Item) (util.Uint160, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func nnsIsAvailable(c Client, nnsHash util.Uint160, name string) (bool, error) {
|
func nnsIsAvailable(c Client, nnsHash util.Uint160, name string) (bool, error) {
|
||||||
switch c.(type) {
|
switch ct := c.(type) {
|
||||||
case *rpcclient.Client:
|
case *rpcclient.Client:
|
||||||
inv := invoker.New(c, nil)
|
return ct.NNSIsAvailable(nnsHash, name)
|
||||||
reader := nnsClient.NewReader(inv, nnsHash)
|
|
||||||
return reader.IsAvailable(name)
|
|
||||||
default:
|
default:
|
||||||
b, err := unwrap.Bool(invokeFunction(c, nnsHash, "isAvailable", []any{name}, nil))
|
b, err := unwrap.Bool(invokeFunction(c, nnsHash, "isAvailable", []any{name}, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/neo"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/neo"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||||
|
@ -117,11 +116,9 @@ func (c *initializeContext) transferNEOFinished(neoHash util.Uint160) (bool, err
|
||||||
var errGetPriceInvalid = errors.New("`getRegisterPrice`: invalid response")
|
var errGetPriceInvalid = errors.New("`getRegisterPrice`: invalid response")
|
||||||
|
|
||||||
func (c *initializeContext) getCandidateRegisterPrice() (int64, error) {
|
func (c *initializeContext) getCandidateRegisterPrice() (int64, error) {
|
||||||
switch c.Client.(type) {
|
switch ct := c.Client.(type) {
|
||||||
case *rpcclient.Client:
|
case *rpcclient.Client:
|
||||||
inv := invoker.New(c.Client, nil)
|
return ct.GetCandidateRegisterPrice()
|
||||||
reader := neo.NewReader(inv)
|
|
||||||
return reader.GetRegisterPrice()
|
|
||||||
default:
|
default:
|
||||||
neoHash := neo.Hash
|
neoHash := neo.Hash
|
||||||
res, err := invokeFunction(c.Client, neoHash, "getRegisterPrice", nil, nil)
|
res, err := invokeFunction(c.Client, neoHash, "getRegisterPrice", nil, nil)
|
||||||
|
|
|
@ -6,9 +6,8 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
|
"github.com/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
|
@ -102,10 +101,11 @@ func generateTestData(t *testing.T, dir string, size int) {
|
||||||
cfg := config.Config{}
|
cfg := config.Config{}
|
||||||
cfg.ProtocolConfiguration.Magic = 12345
|
cfg.ProtocolConfiguration.Magic = 12345
|
||||||
cfg.ProtocolConfiguration.ValidatorsCount = size
|
cfg.ProtocolConfiguration.ValidatorsCount = size
|
||||||
cfg.ProtocolConfiguration.TimePerBlock = time.Second
|
cfg.ProtocolConfiguration.SecondsPerBlock = 1
|
||||||
cfg.ProtocolConfiguration.StandbyCommittee = pubs // sorted by glagolic letters
|
cfg.ProtocolConfiguration.StandbyCommittee = pubs // sorted by glagolic letters
|
||||||
cfg.ProtocolConfiguration.P2PSigExtensions = true
|
cfg.ProtocolConfiguration.P2PSigExtensions = true
|
||||||
cfg.ProtocolConfiguration.VerifyTransactions = true
|
cfg.ProtocolConfiguration.VerifyTransactions = true
|
||||||
|
cfg.ProtocolConfiguration.VerifyBlocks = true
|
||||||
data, err := yaml.Marshal(cfg)
|
data, err := yaml.Marshal(cfg)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -2,7 +2,7 @@ syntax = "proto3";
|
||||||
|
|
||||||
package neo.fs.v2.refs;
|
package neo.fs.v2.refs;
|
||||||
|
|
||||||
option go_package = "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/internal";
|
option go_package = "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/internal";
|
||||||
|
|
||||||
// Client group identifier in the FrostFS subnet.
|
// Client group identifier in the FrostFS subnet.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package morph
|
package morph
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
|
"github.com/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
|
@ -9,12 +9,10 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"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/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
"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/actor"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/gas"
|
"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/nep17"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/notary"
|
"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/nspcc-dev/neo-go/pkg/wallet"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
@ -25,9 +23,16 @@ import (
|
||||||
const defaultNotaryDepositLifetime = 5760
|
const defaultNotaryDepositLifetime = 5760
|
||||||
|
|
||||||
func depositNotary(cmd *cobra.Command, _ []string) error {
|
func depositNotary(cmd *cobra.Command, _ []string) error {
|
||||||
w, err := openWallet(cmd)
|
p, err := cmd.Flags().GetString(storageWalletFlag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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()
|
accHash := w.GetChangeAddress()
|
||||||
|
@ -75,10 +80,6 @@ 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())
|
c, err := getN3Client(viper.GetViper())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -118,18 +119,3 @@ func transferGas(cmd *cobra.Command, acc *wallet.Account, accHash util.Uint160,
|
||||||
|
|
||||||
return awaitTx(cmd, c, []hashVUBPair{{hash: txHash, vub: vub}})
|
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"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
netmapcontract "git.frostfs.info/TrueCloudLab/frostfs-contract/netmap"
|
netmapcontract "github.com/TrueCloudLab/frostfs-contract/netmap"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||||
|
|
|
@ -239,139 +239,10 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
initGenerateAlphabetCmd()
|
RootCmd.AddCommand(generateAlphabetCmd)
|
||||||
initInitCmd()
|
generateAlphabetCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||||
initDeployCmd()
|
generateAlphabetCmd.Flags().Uint(alphabetSizeFlag, 7, "Amount of alphabet wallets to generate")
|
||||||
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)
|
RootCmd.AddCommand(initCmd)
|
||||||
initCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
initCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||||
initCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
initCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||||
|
@ -384,14 +255,85 @@ func initInitCmd() {
|
||||||
initCmd.Flags().Uint64(containerAliasFeeCLIFlag, 500, "Container alias fee")
|
initCmd.Flags().Uint64(containerAliasFeeCLIFlag, 500, "Container alias fee")
|
||||||
initCmd.Flags().String(protoConfigPath, "", "Path to the consensus node configuration")
|
initCmd.Flags().String(protoConfigPath, "", "Path to the consensus node configuration")
|
||||||
initCmd.Flags().String(localDumpFlag, "", "Path to the blocks dump file")
|
initCmd.Flags().String(localDumpFlag, "", "Path to the blocks dump file")
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,12 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/internal"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/internal"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
"github.com/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/rand"
|
"github.com/TrueCloudLab/frostfs-node/pkg/util/rand"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/subnet"
|
"github.com/TrueCloudLab/frostfs-sdk-go/subnet"
|
||||||
subnetid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/subnet/id"
|
subnetid "github.com/TrueCloudLab/frostfs-sdk-go/subnet/id"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
"github.com/nspcc-dev/neo-go/cli/flags"
|
"github.com/nspcc-dev/neo-go/cli/flags"
|
||||||
"github.com/nspcc-dev/neo-go/cli/input"
|
"github.com/nspcc-dev/neo-go/cli/input"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
||||||
|
@ -339,19 +339,17 @@ func manageSubnetAdmins(cmd *cobra.Command, rm bool) error {
|
||||||
return fmt.Errorf("admin key format: %w", err)
|
return fmt.Errorf("admin key format: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return invokeMethodWithParams(cmd, id, rm, binAdminKey, key)
|
// prepare call parameters
|
||||||
}
|
|
||||||
|
|
||||||
func invokeMethodWithParams(cmd *cobra.Command, id subnetid.ID, rm bool, binAdminKey []byte, key keys.PrivateKey) error {
|
|
||||||
prm := make([]any, 0, 3)
|
prm := make([]any, 0, 3)
|
||||||
prm = append(prm, id.Marshal())
|
prm = append(prm, id.Marshal())
|
||||||
|
|
||||||
var method string
|
var method string
|
||||||
|
|
||||||
if viper.GetBool(flagSubnetAdminClient) {
|
if viper.GetBool(flagSubnetAdminClient) {
|
||||||
|
// read group ID and encode it
|
||||||
var groupID internal.SubnetClientGroupID
|
var groupID internal.SubnetClientGroupID
|
||||||
|
|
||||||
err := groupID.UnmarshalText([]byte(viper.GetString(flagSubnetAdminAddGroup)))
|
err = groupID.UnmarshalText([]byte(viper.GetString(flagSubnetAdminAddGroup)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("decode group ID text: %w", err)
|
return fmt.Errorf("decode group ID text: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -378,7 +376,7 @@ func invokeMethodWithParams(cmd *cobra.Command, id subnetid.ID, rm bool, binAdmi
|
||||||
|
|
||||||
prm = append(prm, binAdminKey)
|
prm = append(prm, binAdminKey)
|
||||||
|
|
||||||
err := invokeMethod(key, false, method, prm...)
|
err = invokeMethod(key, false, method, prm...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("morph invocation: %w", err)
|
return fmt.Errorf("morph invocation: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -654,13 +652,52 @@ func addCommandInheritPreRun(par *cobra.Command, subs ...*cobra.Command) {
|
||||||
|
|
||||||
// registers flags and binds sub-commands for subnet commands.
|
// registers flags and binds sub-commands for subnet commands.
|
||||||
func init() {
|
func init() {
|
||||||
initCreateSubnetFlags()
|
cmdSubnetCreate.Flags().StringP(flagSubnetWallet, "w", "", "Path to file with wallet")
|
||||||
initGetSubnetFlags()
|
_ = cmdSubnetCreate.MarkFlagRequired(flagSubnetWallet)
|
||||||
initRemoveSubnetFlags()
|
cmdSubnetCreate.Flags().StringP(flagSubnetAddress, "a", "", "Address in the wallet, optional")
|
||||||
initSubnetAdminFlags()
|
|
||||||
initSubnetAdminAddFlags()
|
// get subnet flags
|
||||||
initSubnetAdminRemoveFlags()
|
cmdSubnetGet.Flags().String(flagSubnetGetID, "", "ID of the subnet to read")
|
||||||
initClientManagementFlags()
|
_ = 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")
|
||||||
|
|
||||||
// add all admin managing commands to corresponding command section
|
// add all admin managing commands to corresponding command section
|
||||||
addCommandInheritPreRun(cmdSubnetAdmin,
|
addCommandInheritPreRun(cmdSubnetAdmin,
|
||||||
|
@ -674,7 +711,14 @@ func init() {
|
||||||
cmdSubnetClientRemove,
|
cmdSubnetClientRemove,
|
||||||
)
|
)
|
||||||
|
|
||||||
initSubnetNodeFlags()
|
// 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)
|
||||||
|
|
||||||
// add all node managing commands to corresponding command section
|
// add all node managing commands to corresponding command section
|
||||||
addCommandInheritPreRun(cmdSubnetNode,
|
addCommandInheritPreRun(cmdSubnetNode,
|
||||||
|
@ -682,7 +726,10 @@ func init() {
|
||||||
cmdSubnetNodeRemove,
|
cmdSubnetNodeRemove,
|
||||||
)
|
)
|
||||||
|
|
||||||
initSubnetGlobalFlags()
|
// subnet global flags
|
||||||
|
cmdSubnetFlags := cmdSubnet.PersistentFlags()
|
||||||
|
cmdSubnetFlags.StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||||
|
_ = cmdSubnet.MarkFlagRequired(endpointFlag)
|
||||||
|
|
||||||
// add all subnet commands to corresponding command section
|
// add all subnet commands to corresponding command section
|
||||||
addCommandInheritPreRun(cmdSubnet,
|
addCommandInheritPreRun(cmdSubnet,
|
||||||
|
@ -695,77 +742,6 @@ 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) {
|
func testInvokeMethod(key keys.PrivateKey, method string, args ...any) ([]stackitem.Item, error) {
|
||||||
c, err := getN3Client(viper.GetViper())
|
c, err := getN3Client(viper.GetViper())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -920,7 +896,13 @@ func invokeNotary(c Client, key keys.PrivateKey, method string, notaryHash util.
|
||||||
return fmt.Errorf("subnet hash resolving: %w", err)
|
return fmt.Errorf("subnet hash resolving: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
test, err := makeTestInvocation(inv, subnetHash, method, args)
|
// 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)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -936,26 +918,7 @@ func invokeNotary(c Client, key keys.PrivateKey, method string, notaryHash util.
|
||||||
return fmt.Errorf("blockchain height: %w", err)
|
return fmt.Errorf("blockchain height: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return createAndPushTransaction(alphabet, test, bc, cosigners, c, key, multisigAccount)
|
signersNumber := uint8(smartcontract.GetDefaultHonestNodeCount(len(alphabet)) + 1) // alphabet multisig + key signature
|
||||||
}
|
|
||||||
|
|
||||||
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
|
// notaryRequestValidity is number of blocks during
|
||||||
// witch notary request is considered valid
|
// witch notary request is considered valid
|
||||||
|
@ -964,7 +927,7 @@ func createAndPushTransaction(alphabet keys.PublicKeys, test *result.Invoke, blo
|
||||||
mainTx := &transaction.Transaction{
|
mainTx := &transaction.Transaction{
|
||||||
Nonce: rand.Uint32(),
|
Nonce: rand.Uint32(),
|
||||||
SystemFee: test.GasConsumed,
|
SystemFee: test.GasConsumed,
|
||||||
ValidUntilBlock: blockCount + notaryRequestValidity,
|
ValidUntilBlock: bc + notaryRequestValidity,
|
||||||
Script: test.Script,
|
Script: test.Script,
|
||||||
Attributes: []transaction.Attribute{
|
Attributes: []transaction.Attribute{
|
||||||
{
|
{
|
||||||
|
@ -975,7 +938,7 @@ func createAndPushTransaction(alphabet keys.PublicKeys, test *result.Invoke, blo
|
||||||
Signers: cosigners,
|
Signers: cosigners,
|
||||||
}
|
}
|
||||||
|
|
||||||
notaryFee, err := client.CalculateNotaryFee(signersNumber)
|
notaryFee, err := c.CalculateNotaryFee(signersNumber)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -983,14 +946,14 @@ func createAndPushTransaction(alphabet keys.PublicKeys, test *result.Invoke, blo
|
||||||
acc := wallet.NewAccountFromPrivateKey(&key)
|
acc := wallet.NewAccountFromPrivateKey(&key)
|
||||||
aa := notaryAccounts(multisigAccount, acc)
|
aa := notaryAccounts(multisigAccount, acc)
|
||||||
|
|
||||||
err = client.AddNetworkFee(mainTx, notaryFee, aa...)
|
err = c.AddNetworkFee(mainTx, notaryFee, aa...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("notary network fee adding: %w", err)
|
return fmt.Errorf("notary network fee adding: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
mainTx.Scripts = notaryWitnesses(client, multisigAccount, acc, mainTx)
|
mainTx.Scripts = notaryWitnesses(c, multisigAccount, acc, mainTx)
|
||||||
|
|
||||||
_, err = client.SignAndPushP2PNotaryRequest(mainTx,
|
_, err = c.SignAndPushP2PNotaryRequest(mainTx,
|
||||||
[]byte{byte(opcode.RET)},
|
[]byte{byte(opcode.RET)},
|
||||||
-1,
|
-1,
|
||||||
0,
|
0,
|
||||||
|
|
|
@ -3,14 +3,14 @@ package modules
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/storagecfg"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/storagecfg"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/misc"
|
"github.com/TrueCloudLab/frostfs-node/misc"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/autocomplete"
|
"github.com/TrueCloudLab/frostfs-node/pkg/util/autocomplete"
|
||||||
utilConfig "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/config"
|
utilConfig "github.com/TrueCloudLab/frostfs-node/pkg/util/config"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/gendoc"
|
"github.com/TrueCloudLab/frostfs-node/pkg/util/gendoc"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
netutil "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/network"
|
netutil "github.com/TrueCloudLab/frostfs-node/pkg/network"
|
||||||
"github.com/chzyer/readline"
|
"github.com/chzyer/readline"
|
||||||
"github.com/nspcc-dev/neo-go/cli/flags"
|
"github.com/nspcc-dev/neo-go/cli/flags"
|
||||||
"github.com/nspcc-dev/neo-go/cli/input"
|
"github.com/nspcc-dev/neo-go/cli/input"
|
||||||
|
@ -80,7 +80,15 @@ type config struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func storageConfig(cmd *cobra.Command, args []string) {
|
func storageConfig(cmd *cobra.Command, args []string) {
|
||||||
outPath := getOutputPath(args)
|
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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
historyPath := filepath.Join(os.TempDir(), "frostfs-adm.history")
|
historyPath := filepath.Join(os.TempDir(), "frostfs-adm.history")
|
||||||
readline.SetHistoryPath(historyPath)
|
readline.SetHistoryPath(historyPath)
|
||||||
|
@ -95,7 +103,14 @@ func storageConfig(cmd *cobra.Command, args []string) {
|
||||||
w, err := wallet.NewWalletFromFile(c.Wallet.Path)
|
w, err := wallet.NewWalletFromFile(c.Wallet.Path)
|
||||||
fatalOnErr(err)
|
fatalOnErr(err)
|
||||||
|
|
||||||
fillWalletAccount(cmd, &c, w)
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
accH, err := flags.ParseAddress(c.Wallet.Account)
|
accH, err := flags.ParseAddress(c.Wallet.Account)
|
||||||
fatalOnErr(err)
|
fatalOnErr(err)
|
||||||
|
@ -113,51 +128,32 @@ func storageConfig(cmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
c.AuthorizedKeys = append(c.AuthorizedKeys, hex.EncodeToString(acc.PrivateKey().PublicKey().Bytes()))
|
c.AuthorizedKeys = append(c.AuthorizedKeys, hex.EncodeToString(acc.PrivateKey().PublicKey().Bytes()))
|
||||||
|
|
||||||
network := readNetwork(cmd)
|
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
|
||||||
|
}
|
||||||
|
|
||||||
c.MorphRPC = n3config[network].MorphRPC
|
c.MorphRPC = n3config[network].MorphRPC
|
||||||
|
|
||||||
depositGas(cmd, acc, network)
|
depositGas(cmd, acc, network)
|
||||||
|
|
||||||
c.Attribute.Locode = getString("UN-LOCODE attribute in [XX YYY] format: ")
|
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
|
var addr, port string
|
||||||
for {
|
for {
|
||||||
c.AnnouncedAddress = getString("Publicly announced address: ")
|
c.AnnouncedAddress = getString("Publicly announced address: ")
|
||||||
validator := netutil.Address{}
|
validator := netutil.Address{}
|
||||||
err := validator.FromString(c.AnnouncedAddress)
|
err := validator.FromString(c.AnnouncedAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cmd.Println("Incorrect address format. See https://git.frostfs.info/TrueCloudLab/frostfs-node/src/branch/master/pkg/network/address.go for details.")
|
cmd.Println("Incorrect address format. See https://github.com/TrueCloudLab/frostfs-node/blob/master/pkg/network/address.go for details.")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
uriAddr, err := url.Parse(validator.URIAddr())
|
uriAddr, err := url.Parse(validator.URIAddr())
|
||||||
|
@ -186,46 +182,34 @@ func getDefaultEndpoint(cmd *cobra.Command, c *config) string {
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return net.JoinHostPort(defaultDataEndpoint, port)
|
|
||||||
}
|
|
||||||
|
|
||||||
func fillWalletAccount(cmd *cobra.Command, c *config, w *wallet.Wallet) {
|
defaultAddr := net.JoinHostPort(defaultDataEndpoint, port)
|
||||||
c.Wallet.Account, _ = cmd.Flags().GetString(accountFlag)
|
c.Endpoint = getString(fmt.Sprintf("Listening address [%s]: ", defaultAddr))
|
||||||
if c.Wallet.Account == "" {
|
if c.Endpoint == "" {
|
||||||
addr := address.Uint160ToString(w.GetChangeAddress())
|
c.Endpoint = defaultAddr
|
||||||
c.Wallet.Account = getWalletAccount(w, fmt.Sprintf("Wallet account [%s]: ", addr))
|
|
||||||
if c.Wallet.Account == "" {
|
|
||||||
c.Wallet.Account = addr
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func readNetwork(cmd *cobra.Command) string {
|
c.ControlEndpoint = getString(fmt.Sprintf("Listening address (control endpoint) [%s]: ", defaultControlEndpoint))
|
||||||
var network string
|
if c.ControlEndpoint == "" {
|
||||||
for {
|
c.ControlEndpoint = defaultControlEndpoint
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
func getOutputPath(args []string) string {
|
c.TLSCert = getPath("TLS Certificate (optional): ")
|
||||||
if len(args) != 0 {
|
if c.TLSCert != "" {
|
||||||
return args[0]
|
c.TLSKey = getPath("TLS Key: ")
|
||||||
}
|
}
|
||||||
outPath := getPath("File to write config at [./config.yml]: ")
|
|
||||||
if outPath == "" {
|
c.Relay = getConfirmation(false, "Use node as a relay? yes/[no]: ")
|
||||||
outPath = "./config.yml"
|
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")
|
||||||
}
|
}
|
||||||
return outPath
|
|
||||||
|
out := applyTemplate(c)
|
||||||
|
fatalOnErr(os.WriteFile(outPath, out, 0644))
|
||||||
|
|
||||||
|
cmd.Println("Node is ready for work! Run `frostfs-node -config " + outPath + "`")
|
||||||
}
|
}
|
||||||
|
|
||||||
func getWalletAccount(w *wallet.Wallet, prompt string) string {
|
func getWalletAccount(w *wallet.Wallet, prompt string) string {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -9,16 +9,16 @@ duplicated header names or headers with empty values are considered invalid.
|
||||||
|
|
||||||
## Existing headers
|
## Existing headers
|
||||||
|
|
||||||
There are some "well-known" headers starting with `__SYSTEM__` prefix that
|
There are some "well-known" headers starting with `__FROSTFS__` prefix that
|
||||||
affect system behaviour. For backward compatibility, the same set of
|
affect system behaviour. For backward compatibility, the same set of
|
||||||
"well-known" headers may also use `__NEOFS__` prefix:
|
"well-known" headers may also use `__NEOFS__` prefix:
|
||||||
|
|
||||||
* `__SYSTEM__NETMAP_EPOCH` - netmap epoch to use for object placement calculation. The `value` is string
|
* `__FROSTFS__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
|
encoded `uint64` in decimal presentation. If set to '0' or omitted, the
|
||||||
current epoch only will be used.
|
current epoch only will be used.
|
||||||
* `__SYSTEM__NETMAP_LOOKUP_DEPTH` - if object can't be found using current epoch's netmap, this header limits
|
* `__FROSTFS__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
|
how many past epochs the node can look up through. Depth is applied to a current epoch or the value
|
||||||
of `__SYSTEM__NETMAP_EPOCH` attribute. The `value` is string encoded `uint64` in decimal presentation.
|
of `__FROSTFS__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.
|
If set to '0' or not set, only the current epoch is used.
|
||||||
|
|
||||||
## `frostfs-cli` commands with `--xhdr`
|
## `frostfs-cli` commands with `--xhdr`
|
||||||
|
@ -30,5 +30,5 @@ List of commands with support of extended headers:
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```shell
|
```shell
|
||||||
$ frostfs-cli object put -r s01.frostfs.devenv:8080 -w wallet.json --cid CID --file FILE --xhdr "__SYSTEM__NETMAP_EPOCH=777"
|
$ frostfs-cli object put -r s01.frostfs.devenv:8080 -w wallet.json --cid CID --file FILE --xhdr "__FROSTFS__NETMAP_EPOCH=777"
|
||||||
```
|
```
|
||||||
|
|
|
@ -7,15 +7,15 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/accounting"
|
"github.com/TrueCloudLab/frostfs-sdk-go/accounting"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
"github.com/TrueCloudLab/frostfs-sdk-go/client"
|
||||||
containerSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
containerSDK "github.com/TrueCloudLab/frostfs-sdk-go/container"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
"github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
"github.com/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version"
|
"github.com/TrueCloudLab/frostfs-sdk-go/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BalanceOfPrm groups parameters of BalanceOf operation.
|
// BalanceOfPrm groups parameters of BalanceOf operation.
|
||||||
|
|
|
@ -3,11 +3,11 @@ package internal
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
"github.com/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
"github.com/TrueCloudLab/frostfs-sdk-go/client"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
|
"github.com/TrueCloudLab/frostfs-sdk-go/session"
|
||||||
)
|
)
|
||||||
|
|
||||||
// here are small structures with public setters to share between parameter structures
|
// here are small structures with public setters to share between parameter structures
|
||||||
|
|
|
@ -8,11 +8,11 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/network"
|
"github.com/TrueCloudLab/frostfs-node/pkg/network"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
"github.com/TrueCloudLab/frostfs-sdk-go/client"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
@ -48,7 +48,7 @@ func GetSDKClient(cmd *cobra.Command, key *ecdsa.PrivateKey, addr network.Addres
|
||||||
)
|
)
|
||||||
|
|
||||||
prmInit.SetDefaultPrivateKey(*key)
|
prmInit.SetDefaultPrivateKey(*key)
|
||||||
prmInit.ResolveFrostFSFailures()
|
prmInit.ResolveNeoFSFailures()
|
||||||
prmDial.SetServerURI(addr.URIAddr())
|
prmDial.SetServerURI(addr.URIAddr())
|
||||||
if timeout := viper.GetDuration(commonflags.Timeout); timeout > 0 {
|
if timeout := viper.GetDuration(commonflags.Timeout); timeout > 0 {
|
||||||
// In CLI we can only set a timeout for the whole operation.
|
// In CLI we can only set a timeout for the whole operation.
|
||||||
|
|
|
@ -4,10 +4,10 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/version"
|
"github.com/TrueCloudLab/frostfs-node/pkg/core/version"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
"github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||||
versionSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version"
|
versionSDK "github.com/TrueCloudLab/frostfs-sdk-go/version"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
"github.com/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/checksum"
|
"github.com/TrueCloudLab/frostfs-sdk-go/checksum"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/nspcc-dev/neo-go/cli/input"
|
"github.com/nspcc-dev/neo-go/cli/input"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||||
|
|
|
@ -6,8 +6,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/nspcc-dev/neo-go/cli/flags"
|
"github.com/nspcc-dev/neo-go/cli/flags"
|
||||||
"github.com/nspcc-dev/neo-go/cli/input"
|
"github.com/nspcc-dev/neo-go/cli/input"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import cmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules"
|
import cmd "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cmd.Execute()
|
cmd.Execute()
|
||||||
|
|
|
@ -3,13 +3,13 @@ package accounting
|
||||||
import (
|
import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/precision"
|
"github.com/TrueCloudLab/frostfs-node/pkg/util/precision"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/accounting"
|
"github.com/TrueCloudLab/frostfs-sdk-go/accounting"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package accounting
|
package accounting
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package basic
|
package basic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
"github.com/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,11 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
"github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||||
"github.com/spf13/cobra"
|
"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'.
|
Operation is an object service verb: 'get', 'head', 'put', 'search', 'delete', 'getrange', or 'getrangehash'.
|
||||||
|
|
||||||
Filter consists of <typ>:<key><match><value>
|
Filter consists of <typ>:<key><match><value>
|
||||||
Typ is 'obj' for object applied filter or 'req' for request applied filter.
|
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.
|
Key is a valid unicode string corresponding to object or request header key.
|
||||||
Well-known system object headers start with '$Object:' prefix.
|
Well-known system object headers start with '$Object:' prefix.
|
||||||
User defined headers start without prefix.
|
User defined headers start without prefix.
|
||||||
Read more about filter keys at git.frostfs.info.com/TrueCloudLab/frostfs-api/src/branch/master/proto-docs/acl.md#message-eaclrecordfilter
|
Read more about filter keys at github.com/TrueCloudLab/frostfs-api/blob/master/proto-docs/acl.md#message-eaclrecordfilter
|
||||||
Match is '=' for matching and '!=' for non-matching filter.
|
Match is '=' for matching and '!=' for non-matching filter.
|
||||||
Value is a valid unicode string corresponding to object or request header value.
|
Value is a valid unicode string corresponding to object or request header value.
|
||||||
|
|
||||||
Target is
|
Target is
|
||||||
'user' for container owner,
|
'user' for container owner,
|
||||||
'system' for Storage nodes in container and Inner Ring nodes,
|
'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.
|
'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.
|
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 (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
"github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,9 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
"github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package acl
|
package acl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/acl/basic"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/acl/basic"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/acl/extended"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/acl/extended"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,13 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
"github.com/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||||
eaclSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
eaclSDK "github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/autocomplete"
|
"github.com/TrueCloudLab/frostfs-node/pkg/util/autocomplete"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
@ -7,17 +7,17 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
containerApi "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
|
containerApi "github.com/TrueCloudLab/frostfs-api-go/v2/container"
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
"github.com/TrueCloudLab/frostfs-sdk-go/container"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
"github.com/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
"github.com/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||||
subnetid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/subnet/id"
|
subnetid "github.com/TrueCloudLab/frostfs-sdk-go/subnet/id"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ var (
|
||||||
var createContainerCmd = &cobra.Command{
|
var createContainerCmd = &cobra.Command{
|
||||||
Use: "create",
|
Use: "create",
|
||||||
Short: "Create new container",
|
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.`,
|
It will be stored in sidechain when inner ring will accepts it.`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
placementPolicy, err := parseContainerPolicy(cmd, containerPolicy)
|
placementPolicy, err := parseContainerPolicy(cmd, containerPolicy)
|
||||||
|
|
|
@ -4,20 +4,20 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
objectSDK "github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
var deleteContainerCmd = &cobra.Command{
|
var deleteContainerCmd = &cobra.Command{
|
||||||
Use: "delete",
|
Use: "delete",
|
||||||
Short: "Delete existing container",
|
Short: "Delete existing container",
|
||||||
Long: `Delete existing container.
|
Long: `Delete existing container.
|
||||||
Only owner of the container has a permission to remove container.`,
|
Only owner of the container has a permission to remove container.`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
id := parseContainerID(cmd)
|
id := parseContainerID(cmd)
|
||||||
|
@ -77,8 +77,8 @@ Only owner of the container has a permission to remove container.`,
|
||||||
|
|
||||||
if len(res.IDList()) != 0 {
|
if len(res.IDList()) != 0 {
|
||||||
commonCmd.ExitOnErr(cmd, "",
|
commonCmd.ExitOnErr(cmd, "",
|
||||||
fmt.Errorf("container wasn't removed because LOCK objects were found, "+
|
fmt.Errorf("Container wasn't removed because LOCK objects were found.\n"+
|
||||||
"use --%s flag to remove anyway", commonflags.ForceFlag))
|
"Use --%s flag to remove anyway.", commonflags.ForceFlag))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,15 +4,15 @@ import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
"github.com/TrueCloudLab/frostfs-sdk-go/container"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
"github.com/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,11 @@ package container
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,12 @@ package container
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
|
"github.com/TrueCloudLab/frostfs-api-go/v2/container"
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
containerSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,14 +16,12 @@ import (
|
||||||
const (
|
const (
|
||||||
flagListPrintAttr = "with-attr"
|
flagListPrintAttr = "with-attr"
|
||||||
flagListContainerOwner = "owner"
|
flagListContainerOwner = "owner"
|
||||||
flagListName = "name"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// flag vars of list command.
|
// flag vars of list command.
|
||||||
var (
|
var (
|
||||||
flagVarListPrintAttr bool
|
flagVarListPrintAttr bool
|
||||||
flagVarListContainerOwner string
|
flagVarListContainerOwner string
|
||||||
flagVarListName string
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var listContainersCmd = &cobra.Command{
|
var listContainersCmd = &cobra.Command{
|
||||||
|
@ -55,33 +52,24 @@ var listContainersCmd = &cobra.Command{
|
||||||
var prmGet internalclient.GetContainerPrm
|
var prmGet internalclient.GetContainerPrm
|
||||||
prmGet.SetClient(cli)
|
prmGet.SetClient(cli)
|
||||||
|
|
||||||
containerIDs := res.IDList()
|
list := res.IDList()
|
||||||
for _, cnrID := range containerIDs {
|
for i := range list {
|
||||||
if flagVarListName == "" && !flagVarListPrintAttr {
|
cmd.Println(list[i].String())
|
||||||
cmd.Println(cnrID.String())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
prmGet.SetContainer(cnrID)
|
|
||||||
res, err := internalclient.GetContainer(prmGet)
|
|
||||||
if err != nil {
|
|
||||||
cmd.Printf(" failed to read attributes: %v\n", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
cnr := res.Container()
|
|
||||||
if cnrName := containerSDK.Name(cnr); flagVarListName != "" && cnrName != flagVarListName {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
cmd.Println(cnrID.String())
|
|
||||||
|
|
||||||
if flagVarListPrintAttr {
|
if flagVarListPrintAttr {
|
||||||
cnr.IterateAttributes(func(key, val string) {
|
prmGet.SetContainer(list[i])
|
||||||
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
|
res, err := internalclient.GetContainer(prmGet)
|
||||||
cmd.Printf(" %s: %s\n", key, val)
|
if err == nil {
|
||||||
}
|
res.Container().IterateAttributes(func(key, val string) {
|
||||||
})
|
if !strings.HasPrefix(key, container.SysAttributePrefix) {
|
||||||
|
// FIXME(@cthulhu-rider): neofs-sdk-go#314 use dedicated method to skip system attributes
|
||||||
|
cmd.Printf(" %s: %s\n", key, val)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
cmd.Printf(" failed to read attributes: %v\n", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -92,9 +80,6 @@ func initContainerListContainersCmd() {
|
||||||
|
|
||||||
flags := listContainersCmd.Flags()
|
flags := listContainersCmd.Flags()
|
||||||
|
|
||||||
flags.StringVar(&flagVarListName, flagListName, "",
|
|
||||||
"List containers by the attribute name",
|
|
||||||
)
|
|
||||||
flags.StringVar(&flagVarListContainerOwner, flagListContainerOwner, "",
|
flags.StringVar(&flagVarListContainerOwner, flagListContainerOwner, "",
|
||||||
"Owner of containers (omit to use owner from private key)",
|
"Owner of containers (omit to use owner from private key)",
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,14 +3,14 @@ package container
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
v2object "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
v2object "github.com/TrueCloudLab/frostfs-api-go/v2/object"
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
objectCli "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/object"
|
objectCli "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/object"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ var listContainerObjectsCmd = &cobra.Command{
|
||||||
attrs := resHead.Header().Attributes()
|
attrs := resHead.Header().Attributes()
|
||||||
for i := range attrs {
|
for i := range attrs {
|
||||||
attrKey := attrs[i].Key()
|
attrKey := attrs[i].Key()
|
||||||
if !strings.HasPrefix(attrKey, v2object.SysAttributePrefix) && !strings.HasPrefix(attrKey, v2object.SysAttributePrefixNeoFS) {
|
if !strings.HasPrefix(attrKey, v2object.SysAttributePrefix) {
|
||||||
// FIXME(@cthulhu-rider): neofs-sdk-go#226 use dedicated method to skip system attributes
|
// FIXME(@cthulhu-rider): neofs-sdk-go#226 use dedicated method to skip system attributes
|
||||||
cmd.Printf(" %s: %s\n", attrKey, attrs[i].Value())
|
cmd.Printf(" %s: %s\n", attrKey, attrs[i].Value())
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,13 @@ package container
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
containerAPI "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
containerAPI "github.com/TrueCloudLab/frostfs-sdk-go/container"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
"github.com/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,11 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,11 @@ package container
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
|
"github.com/TrueCloudLab/frostfs-sdk-go/session"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
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
|
package control
|
||||||
|
|
||||||
import (
|
import (
|
||||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package control
|
package control
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package control
|
package control
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,13 @@ package control
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
|
||||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
ircontrol "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir"
|
ircontrol "github.com/TrueCloudLab/frostfs-node/pkg/services/control/ir"
|
||||||
ircontrolsrv "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir/server"
|
ircontrolsrv "github.com/TrueCloudLab/frostfs-node/pkg/services/control/ir/server"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
"github.com/TrueCloudLab/frostfs-sdk-go/client"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package control
|
package control
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,12 +3,12 @@ package control
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@ func initControlShardsCmd() {
|
||||||
shardsCmd.AddCommand(restoreShardCmd)
|
shardsCmd.AddCommand(restoreShardCmd)
|
||||||
shardsCmd.AddCommand(evacuateShardCmd)
|
shardsCmd.AddCommand(evacuateShardCmd)
|
||||||
shardsCmd.AddCommand(flushCacheCmd)
|
shardsCmd.AddCommand(flushCacheCmd)
|
||||||
shardsCmd.AddCommand(doctorCmd)
|
|
||||||
|
|
||||||
initControlShardsListCmd()
|
initControlShardsListCmd()
|
||||||
initControlSetShardModeCmd()
|
initControlSetShardModeCmd()
|
||||||
|
@ -25,5 +24,4 @@ func initControlShardsCmd() {
|
||||||
initControlRestoreShardCmd()
|
initControlRestoreShardCmd()
|
||||||
initControlEvacuateShardCmd()
|
initControlEvacuateShardCmd()
|
||||||
initControlFlushCacheCmd()
|
initControlFlushCacheCmd()
|
||||||
initControlDoctorCmd()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package control
|
package control
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,11 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
"github.com/mr-tron/base58"
|
"github.com/mr-tron/base58"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package control
|
package control
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,10 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
"github.com/mr-tron/base58"
|
"github.com/mr-tron/base58"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,13 +4,13 @@ import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
controlSvc "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/server"
|
controlSvc "github.com/TrueCloudLab/frostfs-node/pkg/services/control/server"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,13 @@ import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
"github.com/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
controlSvc "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/server"
|
controlSvc "github.com/TrueCloudLab/frostfs-node/pkg/services/control/server"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
"github.com/TrueCloudLab/frostfs-sdk-go/client"
|
||||||
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
frostfscrypto "github.com/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package netmap
|
package netmap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,10 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,12 +3,12 @@ package netmap
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
"github.com/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package netmap
|
package netmap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package netmap
|
package netmap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,12 @@ package object
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -6,13 +6,13 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"github.com/cheggaaa/pb"
|
"github.com/cheggaaa/pb"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -48,9 +48,20 @@ func getObject(cmd *cobra.Command, _ []string) {
|
||||||
|
|
||||||
objAddr := readObjectAddress(cmd, &cnr, &obj)
|
objAddr := readObjectAddress(cmd, &cnr, &obj)
|
||||||
|
|
||||||
|
var out io.Writer
|
||||||
filename := cmd.Flag(fileFlag).Value.String()
|
filename := cmd.Flag(fileFlag).Value.String()
|
||||||
out, closer := createOutWriter(cmd, filename)
|
if filename == "" {
|
||||||
defer closer()
|
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
|
||||||
|
}
|
||||||
|
|
||||||
pk := key.GetOrGenerate(cmd)
|
pk := key.GetOrGenerate(cmd)
|
||||||
|
|
||||||
|
@ -102,10 +113,6 @@ func getObject(cmd *cobra.Command, _ []string) {
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
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 {
|
if binary {
|
||||||
objToStore := res.Header()
|
objToStore := res.Header()
|
||||||
// TODO(@acid-ant): #1932 Use streams to marshal/unmarshal payload
|
// TODO(@acid-ant): #1932 Use streams to marshal/unmarshal payload
|
||||||
|
@ -122,29 +129,11 @@ func processResult(cmd *cobra.Command, res *internalclient.GetObjectRes, binary
|
||||||
|
|
||||||
// Print header only if file is not streamed to stdout.
|
// Print header only if file is not streamed to stdout.
|
||||||
if filename != "" {
|
if filename != "" {
|
||||||
err := printHeader(cmd, res.Header())
|
err = printHeader(cmd, res.Header())
|
||||||
commonCmd.ExitOnErr(cmd, "", err)
|
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 {
|
func strictOutput(cmd *cobra.Command) bool {
|
||||||
toJSON, _ := cmd.Flags().GetBool(commonflags.JSON)
|
toJSON, _ := cmd.Flags().GetBool(commonflags.JSON)
|
||||||
toProto, _ := cmd.Flags().GetBool("proto")
|
toProto, _ := cmd.Flags().GetBool("proto")
|
||||||
|
|
|
@ -5,13 +5,13 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/checksum"
|
"github.com/TrueCloudLab/frostfs-sdk-go/checksum"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -6,15 +6,16 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
"github.com/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
|
oidSDK "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -112,7 +113,7 @@ func marshalHeader(cmd *cobra.Command, hdr *object.Object) ([]byte, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func printObjectID(cmd *cobra.Command, recv func() (oid.ID, bool)) {
|
func printObjectID(cmd *cobra.Command, recv func() (oidSDK.ID, bool)) {
|
||||||
var strID string
|
var strID string
|
||||||
|
|
||||||
id, ok := recv()
|
id, ok := recv()
|
||||||
|
|
|
@ -7,16 +7,16 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
objectV2 "github.com/TrueCloudLab/frostfs-api-go/v2/object"
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
objectSDK "github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -32,36 +32,17 @@ var objectLockCmd = &cobra.Command{
|
||||||
err := cnr.DecodeString(cidRaw)
|
err := cnr.DecodeString(cidRaw)
|
||||||
commonCmd.ExitOnErr(cmd, "Incorrect container arg: %v", err)
|
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)
|
oidsRaw, _ := cmd.Flags().GetStringSlice(commonflags.OIDFlag)
|
||||||
|
|
||||||
lockList := make([]oid.ID, 0, len(oidsRaw))
|
lockList := make([]oid.ID, len(oidsRaw))
|
||||||
oidM := make(map[oid.ID]struct{})
|
|
||||||
|
|
||||||
for i, oidRaw := range oidsRaw {
|
for i := range oidsRaw {
|
||||||
var oID oid.ID
|
err = lockList[i].DecodeString(oidsRaw[i])
|
||||||
err = oID.DecodeString(oidRaw)
|
|
||||||
commonCmd.ExitOnErr(cmd, fmt.Sprintf("Incorrect object arg #%d: %%v", i+1), err)
|
commonCmd.ExitOnErr(cmd, fmt.Sprintf("Incorrect object arg #%d: %%v", i+1), err)
|
||||||
|
|
||||||
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{}{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key := key.GetOrGenerate(cmd)
|
||||||
|
|
||||||
var idOwner user.ID
|
var idOwner user.ID
|
||||||
user.IDFromKey(&idOwner, key.PublicKey)
|
user.IDFromKey(&idOwner, key.PublicKey)
|
||||||
|
|
||||||
|
@ -100,7 +81,7 @@ var objectLockCmd = &cobra.Command{
|
||||||
obj.SetPayload(lock.Marshal())
|
obj.SetPayload(lock.Marshal())
|
||||||
|
|
||||||
var prm internalclient.PutObjectPrm
|
var prm internalclient.PutObjectPrm
|
||||||
ReadOrOpenSessionViaClient(cmd, &prm, cli, key, cnr, nil)
|
ReadOrOpenSession(cmd, &prm, key, cnr, nil)
|
||||||
Prepare(cmd, &prm)
|
Prepare(cmd, &prm)
|
||||||
prm.SetHeader(obj)
|
prm.SetHeader(obj)
|
||||||
|
|
||||||
|
|
|
@ -10,14 +10,14 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
objectV2 "github.com/TrueCloudLab/frostfs-api-go/v2/object"
|
||||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
"github.com/cheggaaa/pb"
|
"github.com/cheggaaa/pb"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -79,13 +79,42 @@ func putObject(cmd *cobra.Command, _ []string) {
|
||||||
obj := object.New()
|
obj := object.New()
|
||||||
|
|
||||||
if binary {
|
if binary {
|
||||||
payloadReader, cnr, ownerID = readFilePayload(filename, cmd)
|
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()
|
||||||
} else {
|
} else {
|
||||||
readCID(cmd, &cnr)
|
readCID(cmd, &cnr)
|
||||||
user.IDFromKey(&ownerID, pk.PublicKey)
|
user.IDFromKey(&ownerID, pk.PublicKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
attrs := getAllObjectAttributes(cmd)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
obj.SetContainerID(cnr)
|
obj.SetContainerID(cnr)
|
||||||
obj.SetOwnerID(&ownerID)
|
obj.SetOwnerID(&ownerID)
|
||||||
|
@ -110,9 +139,23 @@ func putObject(cmd *cobra.Command, _ []string) {
|
||||||
prm.SetPayloadReader(payloadReader)
|
prm.SetPayloadReader(payloadReader)
|
||||||
} else {
|
} else {
|
||||||
if binary {
|
if binary {
|
||||||
p = setBinaryPayloadReader(cmd, obj, &prm, payloadReader)
|
p = pb.New(len(obj.Payload()))
|
||||||
|
p.Output = cmd.OutOrStdout()
|
||||||
|
prm.SetPayloadReader(p.NewProxyReader(payloadReader))
|
||||||
|
prm.SetHeaderCallback(func(o *object.Object) { p.Start() })
|
||||||
} else {
|
} else {
|
||||||
p = setFilePayloadReader(cmd, f, &prm)
|
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()
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,67 +169,6 @@ func putObject(cmd *cobra.Command, _ []string) {
|
||||||
cmd.Printf(" OID: %s\n CID: %s\n", res.ID(), cnr)
|
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) {
|
func parseObjectAttrs(cmd *cobra.Command) ([]object.Attribute, error) {
|
||||||
var rawAttrs []string
|
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