Compare commits

...

123 commits

Author SHA1 Message Date
9aeea0b974 [#153] ci: Minor pipeline fixes
- We can skip full pre-commit run
- On a very slow agent golangci run may take up to 10 minutes

Signed-off-by: Stanislav Bogatyrev <s.bogatyrev@yadro.com>
2023-03-21 09:33:45 +00:00
Pavel Karpy
9a4f40626c [#128] IR: Do not try to emit GAS to nobody
Fix sending GAS to an empty extra wallets receivers list. Also, send GAS to
extra wallets even if netmap is empty.

Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
2023-03-21 08:59:46 +00:00
7a31988a36 [#145] docs: Add expired object collector params
Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
2023-03-21 11:31:08 +03:00
5059dcc19d [#145] shard-gc: Delete expired objects after locks
GC deletes expired locks and objects sequentially. Expired locks and
objects are now being deleted concurrently in batches. Added a config
parameter that controls the number of concurrent workers and batch size.

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
2023-03-21 11:31:08 +03:00
6c4a1699ef [#145] shard-gc: Expired locked unit test
Added unit test that verifies that GC deletes expired
locked objects in one epoch.

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
2023-03-21 11:31:08 +03:00
Pavel Karpy
9cd8f7cea0 [#152] IR: Process empty basic incomes
If network is not configured for basic income earnings, do not distribute
GAS by the Alphabet nodes.

Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
2023-03-21 06:59:33 +00:00
44b86bac5a [#148] linter: Add contextcheck linter
Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
2023-03-21 09:54:41 +03:00
481a1ca6f3 [#148] linter: Add gocognit linter
Code with high cognitive complexity is hard intuitively to understand

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
2023-03-21 09:54:41 +03:00
97c36ed3ec [#148] linter: Add funlen linter
Long functions are hard to understand and source of errors

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
2023-03-21 09:54:41 +03:00
cc8ff015b4 [#148] linter: Add containedctx linter
Context has to be passed as an argument: https://pkg.go.dev/context

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
2023-03-21 09:52:39 +03:00
2dc86058c3 [#148] memstore: Drop space line
Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
2023-03-21 09:52:39 +03:00
573d920821 [#149] Use custom image and kludges for node
Until #139 is fixed, we can't use root inside Docker container running
CI, but Woodpecker CI can't run non-root containers until they fix
https://github.com/woodpecker-ci/woodpecker/issues/1077, hence we use
temporary kludges with custom image and manual permissions in pipelines.

Signed-off-by: Stanislav Bogatyrev <s.bogatyrev@yadro.com>
2023-03-20 18:37:37 +03:00
d64fb887ff [#149] Reorder pre-commit hooks
Minor changes to see what fails first

Signed-off-by: Stanislav Bogatyrev <s.bogatyrev@yadro.com>
2023-03-20 18:37:34 +03:00
392be818e5 [#149] Fix gitlint regex to match our policy
In our policy we mark commits not having a PR/Issue yet with a `[#XX]`
reference to be replaced after PR creation.

Signed-off-by: Stanislav Bogatyrev <s.bogatyrev@yadro.com>
2023-03-20 18:37:27 +03:00
db3ccd2762 [#128] innerring: Add GAS pouring mechanism for a configurable list of wallets
Signed-off-by: Artem Tataurov <a.tataurov@yadro.com>
2023-03-20 12:50:05 +00:00
Pavel Karpy
abd21f8099 [#136] Revert "[#2260] services/object: Do not assemble object with TTL=1"
This reverts commit 2567f8020e. It assumes
that assembling logic could break some failover scenarios if request
forwarding is done. However, it also breaks requesting big objects via a
non-container node with TTL=2. Failover has been rechecked without that
commit and no problems were found. Any (if found) other bugs related to
the forwarding and object assembling must be solved more carefully.

Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
2023-03-20 10:52:18 +03:00
Pavel Karpy
10c419adf0 [#67] node: Fix infinite recursion in SE's wrapper
Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
2023-03-17 18:47:59 +03:00
b70caa216b [#144] Don't copy cache inside Docker environment
May make docker builds not so clean.

Signed-off-by: Stanislav Bogatyrev <s.bogatyrev@yadro.com>
2023-03-17 10:36:50 +03:00
Pavel Karpy
64bde68fb9 [#67] node: Accept expired locked objects
Allow replication of any (expired too) locked object. Information about
object locking is considered to be presented on the _container nodes_.

Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
2023-03-16 16:22:19 +03:00
Pavel Karpy
f006f3b342 [#67] node: Make engine's IsLocked public
It will allow reusing that method in expiration checks.

Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
2023-03-16 16:20:45 +03:00
22be532cbd object/put: Persist session token till the end of a session
Previously a token could've expired in the middle of an object.PUT
stream, leading to upload being interrupted. This is bad, because user
doesn't always now what is the right values for the session token
lifetime. More than that, setting it to a very high value will
eventually blow up the session token database.

In this commit we read the session token once and reuse it for the whole
stream duration.

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-03-16 06:45:50 +00:00
724debfdcd [#81] node: Add basic read/write benchmarks for substorages
Signed-off-by: Alejandro Lopez <a.lopez@yadro.com>
2023-03-15 16:37:04 +00:00
b1c165a93b [#83] Fix shellcheck pre-commit action
Original shellcheck action requires Docker to run and it's not always
available, especially inside Docker containers. Replacing it with python
wrapper to simplify usage with Docker-based CI systems like Drone and
WoodpeckerCI.

Signed-off-by: Stanislav Bogatyrev <s.bogatyrev@yadro.com>
2023-03-15 12:24:41 +00:00
ac0a278a05 [#85] get-service: Drop unused assemble flag
Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
2023-03-15 09:19:45 +03:00
b8e93d4c08 [#85] get-service: Use assembler to assemble LOB
Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
2023-03-15 09:19:45 +03:00
07de839f18 [#85] get-service: Fix corrupted chain logic
Should return an error in case of a broken LOB reference chain.

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
2023-03-15 09:19:45 +03:00
2886b1581b [#85] get-service: Add unit tests
Add unit tests to cover all assemble statements

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
2023-03-15 09:19:45 +03:00
8b9e40a848 [#85] get-service: Add assembler
Extract assemble logic to assembler

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
2023-03-15 09:19:45 +03:00
b4582239bf [#130] adm: Fix adding of pub key for group.frostfs at init step
Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
2023-03-13 15:05:53 +03:00
4e244686cf [#83] Makefile fixes for pre-commit
Add make targets to simplify pre-commit setup for individual developers.

Signed-off-by: Stanislav Bogatyrev <realloc@realloc.spb.ru>
2023-03-13 11:39:18 +00:00
6cd806f998 [#82] services/tree: Save last synchronized height in a persistent storage
Remember the last synchronized height and use it after service restart.

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-03-13 11:25:44 +00:00
3e6fd4c611 [#82] pilorama: Allow to store last sync height
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-03-13 11:25:44 +00:00
5ae4446280 [#50] ir: Add Health status
Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
2023-03-13 11:24:42 +00:00
5890cd4d7d [#50] ir: Fix config property name for prometheus
Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
2023-03-13 11:24:42 +00:00
365adb4ebd [#133] .github: Restore logo.svg
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-03-13 10:39:12 +03:00
bce5827f64 [#83] pre-commit: Add shellcheck hook
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-03-13 07:07:30 +00:00
05471d3827 [#83] util/autocomplete: Fix deprecated warning
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-03-13 07:07:30 +00:00
8226d49376 [#83] pre-commit: Add gitlint hook
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-03-13 07:07:30 +00:00
0893689c6a [#83] pre-commit: Add golangci-lint hook
Skip deprecated warning for now, adopting new neo-go API will be done in
another task.

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-03-13 07:07:29 +00:00
a4931ea4c7 [#83] .github: Remove CODEOWNERS and actions
Issue templates are still supported by Gitea:
https://docs.gitea.io/en-us/issue-pull-request-templates/ .

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-03-13 07:07:29 +00:00
861e9ab59a [#83] pre-commit: Add initial configuration
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-03-13 07:07:29 +00:00
Leonard Lyubich
24a540caa8 [#132] cli/util: Fix basic ACL rendering
In previous implementation pretty-printer of basic ACL in NeoFS CLI had
mistakes:
 * F-bit was set to `Extendable()` property instead of its inversion
 * B-bits were set to `acl.RoleInnerRing` rights

Make `PrettyPrintTableBACL` to correctly render mentioned bits.

Signed-off-by: Leonard Lyubich <ctulhurider@gmail.com>
2023-03-10 14:55:45 +03:00
6226c3ba86 [#129] policer: Use safer defaults
If `processNodes` exits earlier for some reason, `needLocalCopy` could
be false.
See https://github.com/nspcc-dev/neofs-node/issues/2267

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-03-10 10:59:15 +00:00
f2250a316f [#129] tree: Do not remove tree if the netmap is empty
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-03-10 10:59:15 +00:00
9929dcf50b [#126] adm: Exclude group.frostfs key from output of the dump-hashes
Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
2023-03-09 18:29:36 +03:00
7486c02bbc [#88] adm: Fix method nnsResolveKey
Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
2023-03-09 15:41:28 +03:00
Pavel Karpy
f1f3c80dbf [#32] node: Init write-cache asynchronously
Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
2023-03-09 11:07:33 +00:00
Pavel Karpy
381e363a8b [#32] node: Always close general components after testing
It will prevent test fails with `-race` flag on components that have
background processes and make some actions on test framework.

Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
2023-03-09 11:07:33 +00:00
20de74a505 Rename package name
Due to source code relocation from GitHub.

Signed-off-by: Alex Vanin <a.vanin@yadro.com>
2023-03-07 16:38:26 +03:00
79ba34714a [#79] cli: Fix panic when setting domain for container
Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
2023-03-01 11:11:11 +03:00
6d4f48f37a [TrueCloudLab#78] .github: Fix CODEOWNERS
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-28 16:44:50 +03:00
e9f3c24229 [#65] Use strings.Cut instead of strings.Split* where possible
Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
2023-02-28 13:39:14 +03:00
88e3868f47 [#37] cli: Add nns-name and nns-zone for container create
Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
2023-02-28 13:37:23 +03:00
6925fb4c59 [TrueCloudLab/hrw#2] node: Use typed HRW methods
Update HRW lib and use typed HRW methods to sort shards and nodes

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
2023-02-28 13:36:25 +03:00
c3a7039801 [TrueCloudLab/hrw#2] node: Optimize shard hash
Compute shard hash only once

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
2023-02-28 13:36:25 +03:00
a1ab25b33e [#72] .github: Fix CODEOWNERS
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-22 16:29:58 +03:00
73bb590cb1 [#64] node: Use pool_size_local and separate pool for local puts
Signed-off-by: Alejandro Lopez <a.lopez@yadro.com>
2023-02-22 13:43:19 +03:00
7eaf159a8b [#63] adm: Fix contract wallet creation
Create contract wallet only by init and update-config command.

Close #63

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
2023-02-22 10:08:37 +03:00
cb5468abb8 [#66] node: Replace interface{} with any
Signed-off-by: Alejandro Lopez <a.lopez@yadro.com>
2023-02-21 16:47:07 +03:00
3d873237d5 [#44] Update Changelog
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
2023-02-21 10:00:28 +03:00
633c5a35de [#44] adm: Support multiple configs
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
2023-02-21 10:00:28 +03:00
5f06232d34 [#44] cli: Support multiple configs
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
2023-02-21 10:00:28 +03:00
bed5a36235 [#44] ir: Support multiple configs
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
2023-02-21 10:00:28 +03:00
87e69b9349 [#44] node: Support multiple configs
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
2023-02-21 10:00:28 +03:00
Pavel Karpy
337049b2ce [#56] node: Allow reading expired locked object
Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
2023-02-21 09:56:57 +03:00
Pavel Karpy
3beef10f89 [#61] node: Do not fetch missing objects
If an object is missing in a `meta`, shard should not look for it in
a `blobstor`.

Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
2023-02-20 14:47:38 +03:00
5303736acd [#62] Fix CHANGELOG.md
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
2023-02-20 14:25:21 +03:00
22f3c7d080 [#1868] Reload config for pprof and metrics on SIGHUP
Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
2023-02-20 13:53:27 +03:00
2b755ddb12 [#2260] node: Use a separate client cache for PUT service
Currently, under a mixed load one failed PUT can lead to closing
connection for all concurrent GETs. For PUT it does no harm: we have
many other nodes to choose from. For GET we are limited by `REP N`
factor, so in case of failover we can close the connection with the only
node posessing an object, which leads to failing the whole operation.

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-20 13:53:27 +03:00
0b61a3c961 [#2260] network/cache: Ignore clients only on Dial errors
The problem is that accidental timeout errors can make us to ignore
other nodes for some time. The primary purpose of the whole ignore
mechanism is not to degrade in case of failover. For this case,
closing connection and limiting the amount of dials is enough.

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-20 13:53:27 +03:00
bf1e59bb83 [#2260] network/cache: Ignore context cancelled errors
Timeouts on client side should node affect inter-node communication.

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-20 13:53:27 +03:00
2567f8020e [#2260] services/object: Do not assemble object with TTL=1
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-20 13:53:27 +03:00
d1d123d180 [#2234] writecache: Fix possible panic in initFlushMarks
In case we have many small objects in the write-cache, `indices` should
not be reused between iterations.

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-20 13:53:27 +03:00
315141dc2c [#2252] fstree: Allow concurrent writes
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-20 13:53:27 +03:00
Pavel Karpy
b422ac9f94 [#2164] node: Fix multi-client error reporting
Missing `ReportError` method did not allow casing multi-client interface to
`errorReporter` interface and dropping broken connections.
`replicationClient` embeds that interface, and it is widely used across
node's code. Embedded interface does not allow casting its parent structure
to `errorReporter` and breaks multi client error reporting logic.
Multi-client scheme is extremely hard to maintain, it makes unpredictable
casts and does not allow tracking code flow, so it will be refactored in the
future anyway.

Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
2023-02-20 13:53:27 +03:00
Pavel Karpy
95ee905861 [#2244] node: Fix subscriptions lock
Subscribing without async listening could lead to a dead-lock in the
`neo-go` client.

Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
2023-02-20 13:53:27 +03:00
Pavel Karpy
07ec51ea60 [#2244] node: Add object address to WC's operations
Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
2023-02-20 13:53:27 +03:00
Pavel Karpy
dbbbef9ddb [#2244] node: Update expired storage ID by WC
Previously, node could get an "infinite" small object: it could be expired
and thus could not be flushed (update its storage ID) to metabase => could
not be marked as flushed => node never removes such object and repeat all
the cycle one more time. If object exists and is not marked with GC (meta
returns `ErrObjectIsExpired`, not `ObjectNotFound` and not
`ObjectAlreadyRemoved`), its ID is safe to update _in the same_ bbolt
transaction.

Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
2023-02-20 13:53:27 +03:00
351fdd9fa2 [#2246] node: Allow to configure tombsone lifetime
Currently, DELETE service sets tombstone expiration epoch to
`current epoch + 5`. This works less than ideal in private networks
where an epoch can be e.g. 10 minutes. In this case, after a node is
unavailable for more than 1 hour, already deleted objects have a chance
to reappear.

After this commit tombstone lifetime can be configured.

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-20 13:53:27 +03:00
6fd88a036f [#2241] metrics: Fix request count metrics names
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-20 13:53:27 +03:00
2272c55c4d [#2238] engine: Add test for component initialization failures
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-20 13:53:27 +03:00
5cb2c5ae62 [#2238] engine: Add test for component initialization failures
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-20 13:53:27 +03:00
59748b7ae8 [#2238] neofs-node: Gracefully handle shard initialization errors
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-20 13:53:27 +03:00
427fe276f2 [#2238] shard: Try closing all components
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-20 13:53:27 +03:00
c53903ccd0 [#2238] engine: Make Open and Init similar
1. Both could initialize shards in parallel.
2. Both should close shards after an error.

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-20 13:53:27 +03:00
e0309e398c [#2239] writecache: Fix possible deadlock
LRU `Peek`/`Contains` take LRU mutex _inside_ of a `View` transaction.
`View` transaction itself takes `mmapLock` [1], which is lifted after tx
finishes (in `tx.Commit()` -> `tx.close()` -> `tx.db.removeTx`)

When we evict items from LRU cache mutex order is different:
first we take LRU mutex and then execute `Batch` which _does_ take
`mmapLock` in case we need to remap. Thus the deadlock.

[1] 8f4a7e1f92/db.go (L708)

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-20 13:53:27 +03:00
58367e4df6 [#2232] pilorama: Merge in-queue batches
To achieve high performance we must choose proper values for both
batch size and delay. For user operations we want to set low delay.
However it would prevent tree synchronization operations to form big
enough batches. For these operations, batching gives the most benefit
not only in terms of on-CPU execution cost, but also by speeding up
transaction persist (`fsync`).
In this commit we try merging batches that are already
_triggered_, but not yet _started to execute_. This way we can still
query batches for execution after the provided delay while also allowing
multiple formed batches to execute faster.

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-20 13:53:27 +03:00
236c4af615 [#2224] adm: Use native neo-go sessions in dump-hashes
If we had lots of domains in one zone, `dump-hashes` for all others
can miss some domains, because we need to restrict ourselves with _some_
number.
In this commit we use neo-go sessions by default, with a proper
failback to in-script iterator unwrapping.

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-20 13:53:27 +03:00
Pavel Karpy
40822adb51 [#2213] node: Do not return object expired object
"Object is expired" means that object is presented in `meta` but it is not
`ObjectNotFound` error. Previous implementation made `shard` search for an
object without `meta` which was an error.

Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
2023-02-20 13:53:27 +03:00
Roman Khimov
ad93d4db7c CHANGELOG: add more fancy glyphs
How could you forget adding it?

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-02-20 13:53:27 +03:00
Roman Khimov
a6f071d66f CHANGELOG: fix whitespacing errors
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-02-20 13:53:27 +03:00
9afe86ba3e [#2212] morph: Fix subscription restoration
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-20 13:53:27 +03:00
c43b2dbac9 [#1465] Add log entry for morph components shutdown action
Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
2023-02-17 12:13:00 +03:00
85cf1f47ac [#1465] node: Prevent process from killing by systemd when shutting down
Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
2023-02-17 12:13:00 +03:00
362f24953a [#47] shard: Switch container size metric from physical to logical capacity
Signed-off-by: Artem Tataurov <a.tataurov@yadro.com>
2023-02-17 12:03:42 +03:00
Pavel Karpy
901d62567d [#57] node: Broadcast link objects
It boosts object assembling by an _average_ container node.

Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
2023-02-17 11:58:27 +03:00
Aleksey Pastukhov
269a4e9b50 [#53] Fix dirty in version
Signed-off-by: Aleksey Pastukhov <a.pastukhov@yadro.com>
2023-02-16 11:10:43 +03:00
3e5bc394b5 [#48] adm: Add initialize test for 1 node
Single node is used in dev-env, worth testing.

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-16 09:07:18 +03:00
1d3669232e [#48] adm: Allow using nonzero magic with local client
neo-go actor API uses `getVersion` call which returned incorrect magic.

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-16 09:07:18 +03:00
204cd3a11c [#31] fstree: Optimize treePath
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-10 12:49:31 +03:00
dee4498c1e [#31] fstree: Do not check for a file existence twice
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-10 12:49:31 +03:00
abbecf49d6 [#31] fstree: Speedup string-to-address conversion
```
name                  old time/op    new time/op    delta
_addressFromString-8    1.25µs ±30%    1.02µs ± 6%  -18.49%  (p=0.000 n=9+9)

name                  old alloc/op   new alloc/op   delta
_addressFromString-8      352B ± 0%      256B ± 0%  -27.27%  (p=0.000 n=9+10)

name                  old allocs/op  new allocs/op  delta
_addressFromString-8      6.00 ± 0%      4.00 ± 0%  -33.33%  (p=0.000
n=10+10)
```

Also, assure compiler that `s` doesn't escape:
Before this commit:
```
./fstree.go:74:24: leaking param: s
./fstree.go:90:6: moved to heap: addr
```

After this commit:
```
./fstree.go:74:24: s does not escape
```

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-02-10 12:49:31 +03:00
ab21d90cfb [#1794] shard: Add increasing case for the payload size metric
Signed-off-by: Artem Tataurov <a.tataurov@yadro.com>
2023-02-09 13:30:23 +03:00
5ffa826897 [#1] Update Changelog
Signed-off-by: Stanislav Bogatyrev <s.bogatyrev@yadro.com>
2023-02-06 17:41:14 +03:00
cb016d53a6 [#1] Fix comments and error messages
Signed-off-by: Stanislav Bogatyrev <s.bogatyrev@yadro.com>
2023-02-06 17:41:14 +03:00
c761a95eef [#1] Fix project name in control service
Signed-off-by: Stanislav Bogatyrev <s.bogatyrev@yadro.com>
2023-02-06 17:41:14 +03:00
f825cfac78 [#1] Fix project name in comments here and there
Signed-off-by: Stanislav Bogatyrev <s.bogatyrev@yadro.com>
2023-02-06 17:41:14 +03:00
c6645ef775 [#1] Documentation rebranding
Signed-off-by: Stanislav Bogatyrev <s.bogatyrev@yadro.com>
2023-02-06 17:41:14 +03:00
488eece25f [#1] Fix Debian package references to old upstream
Signed-off-by: Stanislav Bogatyrev <s.bogatyrev@yadro.com>
2023-02-06 17:41:14 +03:00
1cedd446bb [#1] Fix sample configs
- Update sample configs to match unit tests
- Remove Docker container for N3 testnet
  Will return with updates when FrostFS enters N3

Signed-off-by: Stanislav Bogatyrev <s.bogatyrev@yadro.com>
2023-02-06 17:41:14 +03:00
1858f11146 [#1] Fix viper env prefix in cli tools
Changing env prefix and corresponding example config files.

Signed-off-by: Stanislav Bogatyrev <s.bogatyrev@yadro.com>
2023-02-06 17:41:14 +03:00
Pavel Karpy
73bc1b0b68 [#38] node: Fix linter warnings
Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
2023-02-06 17:27:54 +03:00
515c60bdf4 [#1889] adm: Add command morph netmap-candidates
Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
2023-02-06 17:26:34 +03:00
ee24815748 [#1889] Move flag --config in cmd/frostfs-adm/internal/commonflags/flags.go
Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
2023-02-06 17:26:34 +03:00
2b09564355 [#1889] Move netmap.go and exit.go from cli to cmd/internal/common
Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
2023-02-06 17:26:34 +03:00
5a9d6a09d8 [#8] cli: Set flag mode required for control shards set-mode
Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
2023-02-06 16:45:03 +03:00
2540598779 [#36] Packaging: allow any version
Also updated changelog

Signed-off-by: Dmitriy Zabolotskiy <d.zabolotskiy@yadro.com>
2023-01-31 16:33:32 +03:00
5d64a354cb [#1] Fix naming in FrostFS Adm help output
Signed-off-by: Alex Vanin <a.vanin@yadro.com>
2023-01-31 11:24:50 +03:00
d7e9e2ef9e [#1] Fix naming in FrostFS Lens help output
Signed-off-by: Alex Vanin <a.vanin@yadro.com>
2023-01-31 11:24:50 +03:00
d31d8c5335 [#1] Fix naming in FrostFS CLI help output
Signed-off-by: Alex Vanin <a.vanin@yadro.com>
2023-01-31 11:24:50 +03:00
406ff1360f [#1] Fix version output for all compiled binaries
Signed-off-by: Alex Vanin <a.vanin@yadro.com>
2023-01-31 11:24:50 +03:00
Pavel Karpy
89a0266f5e [#1794] metrics: Track physical object capacity per shard
Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
2023-01-26 20:06:28 +03:00
Evgenii Stratonikov
9513f163aa [#2116] metrics: Track physical object capacity in the container
Currently we track based on `PayloadSize`, because it is already stored
in the metabase and it is easier to calculate without slowing down the
whole system.

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
2023-01-26 20:06:28 +03:00
945 changed files with 8493 additions and 5333 deletions

25
.docker/Dockerfile.ci Normal file
View file

@ -0,0 +1,25 @@
FROM golang:1.19
WORKDIR /tmp
# Install apt packages
RUN apt-get update && apt-get install --no-install-recommends -y \
pip \
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
&& rm -rf /var/lib/apt/lists/*
# Dash → Bash
RUN echo "dash dash/sh boolean false" | debconf-set-selections
RUN DEBIAN_FRONTEND=noninteractive dpkg-reconfigure dash
RUN useradd -u 1234 -d /home/ci -m ci
USER ci
ENV PATH="$PATH:/home/ci/.local/bin"
COPY .pre-commit-config.yaml .
RUN pip install "pre-commit==3.1.1" \
&& git init . \
&& pre-commit install-hooks \
&& rm -rf /tmp/*

View file

@ -5,4 +5,5 @@ docker-compose.yml
Dockerfile Dockerfile
temp temp
.dockerignore .dockerignore
docker docker
.cache

1
.github/CODEOWNERS vendored
View file

@ -1 +0,0 @@
* @carpawell @fyrchik @acid-ant

View file

@ -1,29 +0,0 @@
name: CHANGELOG check
on:
pull_request:
branches:
- master
- support/**
jobs:
build:
runs-on: ubuntu-latest
name: Check for updates
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Get changed CHANGELOG
id: changelog-diff
uses: tj-actions/changed-files@v29
with:
files: CHANGELOG.md
- name: Fail if changelog not updated
if: steps.changelog-diff.outputs.any_changed == 'false'
uses: actions/github-script@v3
with:
script: |
core.setFailed('CHANGELOG.md has not been updated')

View file

@ -1,37 +0,0 @@
name: Configuration check
on:
pull_request:
branches:
- master
- support/**
jobs:
build:
runs-on: ubuntu-latest
name: config-check
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Get changed config-related files
id: config-diff
uses: tj-actions/changed-files@v29
with:
files: |
config/**
cmd/neofs-node/config/**
- name: Get changed doc files
id: docs-diff
uses: tj-actions/changed-files@v29
with:
files: docs/**
- name: Fail if config files are changed but the documentation is not updated
if: steps.config-diff.outputs.any_changed == 'true' && steps.docs-diff.outputs.any_changed == 'false'
uses: actions/github-script@v3
with:
script: |
core.setFailed('Documentation has not been updated')

View file

@ -1,22 +0,0 @@
name: DCO check
on:
pull_request:
branches:
- master
- support/**
jobs:
commits_check_job:
runs-on: ubuntu-latest
name: Commits Check
steps:
- name: Get PR Commits
id: 'get-pr-commits'
uses: tim-actions/get-pr-commits@master
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: DCO Check
uses: tim-actions/dco@master
with:
commits: ${{ steps.get-pr-commits.outputs.commits }}

View file

@ -1,60 +0,0 @@
name: frostfs-node tests
on:
push:
branches:
- master
- support/**
paths-ignore:
- '*.md'
pull_request:
branches:
- master
- support/**
paths-ignore:
- '*.md'
jobs:
test:
runs-on: ubuntu-20.04
strategy:
matrix:
go: [ '1.18.x', '1.19.x' ]
steps:
- name: Setup go
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go }}
- name: Check out code
uses: actions/checkout@v3
- name: Cache go mod
uses: actions/cache@v3
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ matrix.go }}-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-${{ matrix.go }}-
- name: Run go test
run: go test -coverprofile=coverage.txt -covermode=atomic ./...
- name: Codecov
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
run: bash <(curl -s https://codecov.io/bash)
lint:
runs-on: ubuntu-20.04
steps:
- uses: actions/setup-go@v3
with:
go-version: 1.19
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.50.0
args: --timeout=5m
only-new-issues: true

20
.gitignore vendored
View file

@ -30,4 +30,22 @@ testfile
.neofs-cli.yml .neofs-cli.yml
# debhelpers # debhelpers
**/.debhelper debian/*debhelper*
# logfiles
debian/*.log
# .substvars
debian/*.substvars
# .bash-completion
debian/*.bash-completion
# Install folders and files
debian/frostfs-cli/
debian/frostfs-ir/
debian/files
debian/frostfs-storage/
debian/changelog
man/
debs/

11
.gitlint Normal file
View file

@ -0,0 +1,11 @@
[general]
fail-without-commits=true
regex-style-search=true
contrib=CC1
[title-match-regex]
regex=^\[\#[0-9X]+\]\s
[ignore-by-title]
regex=^Release(.*)
ignore=title-match-regex

View file

@ -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: 5m timeout: 10m
# include test files or not, default is true # include test files or not, default is true
tests: false tests: false
@ -24,6 +24,13 @@ 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:
@ -51,6 +58,9 @@ linters:
- predeclared - predeclared
- reassign - reassign
- whitespace - whitespace
- containedctx
- funlen
- gocognit
- contextcheck
disable-all: true disable-all: true
fast: false fast: false

35
.pre-commit-config.yaml Normal file
View file

@ -0,0 +1,35 @@
ci:
autofix_prs: false
repos:
- repo: https://github.com/jorisroovers/gitlint
rev: v0.19.1
hooks:
- id: gitlint
stages: [commit-msg]
- 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

View file

@ -0,0 +1,17 @@
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
unit:
image: git.frostfs.info/truecloudlab/frostfs-ci:v0.36
commands:
- export HOME="$(getent passwd $(id -u) | cut '-d:' -f6)"
- make test

View file

@ -4,18 +4,52 @@ Changelog for FrostFS Node
## [Unreleased] ## [Unreleased]
### Added ### Added
- Add GAS pouring mechanism for a configurable list of wallets (#128)
- Separate batching for replicated operations over the same container in pilorama (#1621) - Separate batching for replicated operations over the same container in pilorama (#1621)
- Doc for extended headers (#2128) - Doc for extended headers (#2128)
- New `frostfs_node_object_container_size` metric for tracking size of reqular objects in a container (#2116)
- New `frostfs_node_object_payload_size` metric for tracking size of reqular objects on a single shard (#1794)
- Add command `frostfs-adm morph netmap-candidates` (#1889)
- `object.delete.tombstone_lifetime` config parameter to set tombstone lifetime in the DELETE service (#2246)
- Reload config for pprof and metrics on SIGHUP in `neofs-node` (#1868)
- Multiple configs support (#44)
- Parameters `nns-name` and `nns-zone` for command `frostfs-cli container create` (#37)
- Tree service now saves the last synchronization height which persists across restarts (#82)
### Changed ### Changed
- Change `frostfs_node_engine_container_size` to counting sizes of logical objects
- `common.PrintVerbose` prints via `cobra.Command.Printf` (#1962) - `common.PrintVerbose` prints via `cobra.Command.Printf` (#1962)
- Env prefix in configuration changed to `FROSTFS_*` (#43)
- Link object is broadcast throughout the whole container now (#57)
- Pilorama now can merge multiple batches into one (#2231)
- Storage engine now can start even when some shard components are unavailable (#2238)
- `neofs-cli` buffer for object put increased from 4 KiB to 3 MiB (#2243)
- Expired locked object is available for reading (#56)
- Initialize write-cache asynchronously (#32)
### Fixed ### Fixed
- Increase payload size metric on shards' `put` operation (#1794)
- Big object removal with non-local parts (#1978) - Big object removal with non-local parts (#1978)
- Disable pilorama when moving to degraded mode (#2197) - Disable pilorama when moving to degraded mode (#2197)
- Fetching blobovnicza objects that not found in write-cache (#2206) - Fetching blobovnicza objects that not found in write-cache (#2206)
- Do not search for the small objects in FSTree (#2206) - Do not search for the small objects in FSTree (#2206)
- Correct status error for expired session token (#2207) - Correct status error for expired session token (#2207)
- Set flag `mode` required for `frostfs-cli control shards set-mode` (#8)
- Fix `dirty` suffix in debian package version (#53)
- Prevent node process from killing by systemd when shutting down (#1465)
- Restore subscriptions correctly on morph client switch (#2212)
- Expired objects could be returned if not marked with GC yet (#2213)
- `neofs-adm morph dump-hashes` now properly iterates over custom domain (#2224)
- Possible deadlock in write-cache (#2239)
- Fix `*_req_count` and `*_req_count_success` metric values (#2241)
- Storage ID update by write-cache (#2244)
- `neo-go` client deadlock on subscription restoration (#2244)
- Possible panic during write-cache initialization (#2234)
- Do not fetch an object if `meta` is missing it (#61)
- Create contract wallet only by `init` and `update-config` command (#63)
- Actually use `object.put.pool_size_local` and independent pool for local puts (#64).
- Pretty printer of basic ACL in the NeoFS CLI (#2259)
- Adding of public key for nns group `group.frostfs` at init step (#130)
### Removed ### Removed
### Updated ### Updated
@ -25,11 +59,17 @@ Changelog for FrostFS Node
- `golang.org/x/term` to `v0.3.0` - `golang.org/x/term` to `v0.3.0`
- `google.golang.org/grpc` to `v1.51.0` - `google.golang.org/grpc` to `v1.51.0`
- `github.com/nats-io/nats.go` to `v1.22.1` - `github.com/nats-io/nats.go` to `v1.22.1`
- `github.com/TrueCloudLab/hrw` to `v.1.1.1`
- Minimum go version to v1.18 - Minimum go version to v1.18
### Updating from v0.35.0 ### Updating from v0.35.0
## [0.35.0] - 2022-12-28 - Sindo (신도) You need to change configuration environment variables to `FROSTFS_*` if you use any.
New config field `object.delete.tombstone_lifetime` allows to set tombstone lifetime
more appropriate for a specific deployment.
## [0.35.0] - 2022-12-28 - Sindo (신도, 信島)
### Added ### Added
- `morph list-containers` in `neofs-adm` (#1689) - `morph list-containers` in `neofs-adm` (#1689)
@ -113,7 +153,6 @@ Changelog for FrostFS Node
- `spf13/viper` to `v1.8.0` - `spf13/viper` to `v1.8.0`
- `google.golang.org/grpc` to `v1.50.1` - `google.golang.org/grpc` to `v1.50.1`
### Updating from v0.34.0 ### Updating from v0.34.0
Pass CID and OID parameters via the `--cid` and `--oid` flags, not as the command arguments. Pass CID and OID parameters via the `--cid` and `--oid` flags, not as the command arguments.
@ -127,9 +166,9 @@ to match the container owner. Use `--force` (`-f`) flag to bypass this requireme
Tree service network replication can now be fine-tuned with `tree.replication_timeout` config field. Tree service network replication can now be fine-tuned with `tree.replication_timeout` config field.
## [0.34.0] - 2022-10-31 - Marado (마라도, 馬羅島) ## [0.34.0] - 2022-10-31 - Marado (마라도, 馬羅島)
# ## Added ### Added
- `--timeout` flag in `neofs-cli control` commands (#1917) - `--timeout` flag in `neofs-cli control` commands (#1917)
- Document shard modes of operation (#1909) - Document shard modes of operation (#1909)
- `tree list` CLI command (#1332) - `tree list` CLI command (#1332)
@ -163,7 +202,7 @@ Tree service network replication can now be fine-tuned with `tree.replication_ti
- `neo-go` to `v0.99.4` - `neo-go` to `v0.99.4`
- `protoc` to `v3.21.7` - `protoc` to `v3.21.7`
- `neofs-sdk` to `v1.0.0-rc.7` - `neofs-sdk` to `v1.0.0-rc.7`
### Updating from v0.33.0 ### Updating from v0.33.0
Now storage node serves Control API `SetNemapStatus` request with `MAINTENANCE` Now storage node serves Control API `SetNemapStatus` request with `MAINTENANCE`
status only if the mode is allowed in the network settings. To force starting the local status only if the mode is allowed in the network settings. To force starting the local
@ -201,7 +240,7 @@ command.
- Policer marks nodes under maintenance as OK without requests (#1680) - Policer marks nodes under maintenance as OK without requests (#1680)
- Unify help messages in CLI (#1854) - Unify help messages in CLI (#1854)
- `evacuate`, `set-mode` and `flush-cache` control subcommands now accept a list of shard ids (#1867) - `evacuate`, `set-mode` and `flush-cache` control subcommands now accept a list of shard ids (#1867)
- Reading `object` commands of NeoFS CLI don't open remote sessions (#1865) - Reading `object` commands of NeoFS CLI don't open remote sessions (#1865)
- Use hex format to print storage node ID (#1765) - Use hex format to print storage node ID (#1765)
### Fixed ### Fixed
@ -229,7 +268,7 @@ command.
- `neofs-contract` to `v0.16.0` - `neofs-contract` to `v0.16.0`
- `neofs-api-go` to `v2.14.0` - `neofs-api-go` to `v2.14.0`
### Updating from v0.32.0 ### Updating from v0.32.0
Replace using the `control netmap-snapshot` command with `netmap snapshot` one in NeoFS CLI. Replace using the `control netmap-snapshot` command with `netmap snapshot` one in NeoFS CLI.
Node can now specify additional addresses in `ExternalAddr` attribute. To allow a node to dial Node can now specify additional addresses in `ExternalAddr` attribute. To allow a node to dial
other nodes external address, use `apiclient.allow_external` config setting. other nodes external address, use `apiclient.allow_external` config setting.
@ -239,7 +278,7 @@ Pass `maintenance` state to `neofs-cli control set-status` to enter maintenance
If network allows maintenance state (*), it will be reflected in the network map. If network allows maintenance state (*), it will be reflected in the network map.
Storage nodes under maintenance are not excluded from the network map, but don't Storage nodes under maintenance are not excluded from the network map, but don't
serve object operations. (*) can be fetched from network configuration via serve object operations. (*) can be fetched from network configuration via
`neofs-cli netmap netinfo` command. `neofs-cli netmap netinfo` command.
To allow maintenance mode during neofs-adm deployments, set To allow maintenance mode during neofs-adm deployments, set
`network.maintenance_mode_allowed` parameter in config. `network.maintenance_mode_allowed` parameter in config.
@ -534,15 +573,15 @@ Clean up all metabases and re-sync them using `resync_metabase` config flag.
- Reduced amount of slices with pointers (#1239) - Reduced amount of slices with pointers (#1239)
### Updating from v0.28.0-rc.2 ### Updating from v0.28.0-rc.2
Remove `NEOFS_IR_MAINNET_ENDPOINT_NOTIFICATION`, Remove `NEOFS_IR_MAINNET_ENDPOINT_NOTIFICATION`,
`NEOFS_IR_MORPH_ENDPOINT_NOTIFICATION`, and `NEOFS_MORPH_NOTIFICATION_ENDPOINT` `NEOFS_IR_MORPH_ENDPOINT_NOTIFICATION`, and `NEOFS_MORPH_NOTIFICATION_ENDPOINT`
from Inner Ring and Storage configurations. from Inner Ring and Storage configurations.
Specify _WebSocket_ endpoints in `NEOFS_IR_MAINNET_ENDPOINT_CLIENT`, Specify _WebSocket_ endpoints in `NEOFS_IR_MAINNET_ENDPOINT_CLIENT`,
`NEOFS_IR_MORPH_ENDPOINT_CLIENT`, and `NEOFS_MORPH_RPC_ENDPOINT` at Inner Ring `NEOFS_IR_MORPH_ENDPOINT_CLIENT`, and `NEOFS_MORPH_RPC_ENDPOINT` at Inner Ring
and Storage configurations. and Storage configurations.
Specify path to persistent session token db in Storage configuration with Specify path to persistent session token db in Storage configuration with
`NEOFS_NODE_PERSISTENT_SESSIONS_PATH`. `NEOFS_NODE_PERSISTENT_SESSIONS_PATH`.
## [0.28.0-rc.2] - 2022-03-24 ## [0.28.0-rc.2] - 2022-03-24
@ -558,7 +597,7 @@ Specify path to persistent session token db in Storage configuration with
## [0.28.0-rc.1] - 2022-03-18 ## [0.28.0-rc.1] - 2022-03-18
Native RFC-6979 signatures of messages and tokens, LOCK object types, Native RFC-6979 signatures of messages and tokens, LOCK object types,
experimental notifications over NATS with NeoFS API v2.12 support experimental notifications over NATS with NeoFS API v2.12 support
### Fixed ### Fixed
@ -594,8 +633,8 @@ experimental notifications over NATS with NeoFS API v2.12 support
- Deprecated structures from SDK v1.0.0 rc (#1181) - Deprecated structures from SDK v1.0.0 rc (#1181)
### Updating from neofs-node v0.27.5 ### Updating from neofs-node v0.27.5
Set shard error threshold for read-only mode switch with Set shard error threshold for read-only mode switch with
`NEOFS_STORAGE_SHARD_RO_ERROR_THRESHOLD` (default: 0, deactivated). `NEOFS_STORAGE_SHARD_RO_ERROR_THRESHOLD` (default: 0, deactivated).
Set NATS configuration for notifications in `NEOFS_NODE_NOTIFICATION` section. Set NATS configuration for notifications in `NEOFS_NODE_NOTIFICATION` section.
See example config for more details. See example config for more details.
@ -661,7 +700,7 @@ See example config for more details.
Use `--wallet` key in CLI to provide WIF or binary key file instead of `--wif` Use `--wallet` key in CLI to provide WIF or binary key file instead of `--wif`
and `--binary-key`. and `--binary-key`.
Replace `NEOFS_STORAGE_SHARD_N_USE_WRITE_CACHE` with Replace `NEOFS_STORAGE_SHARD_N_USE_WRITE_CACHE` with
`NEOFS_STORAGE_SHARD_N_WRITECACHE_ENABLED` in Storage node config. `NEOFS_STORAGE_SHARD_N_WRITECACHE_ENABLED` in Storage node config.
Specify `password: xxx` in config file for NeoFS CLI to avoid password input. Specify `password: xxx` in config file for NeoFS CLI to avoid password input.
@ -738,7 +777,7 @@ NeoFS API v2.11.0 support with response status codes and storage subnetworks.
- CLI now opens LOCODE database in read-only mode for listing command (#958) - CLI now opens LOCODE database in read-only mode for listing command (#958)
- Tombstone owner now is always set (#842) - Tombstone owner now is always set (#842)
- Node in relay mode does not require shard config anymore (#969) - Node in relay mode does not require shard config anymore (#969)
- Alphabet nodes now ignore notary notifications with non-HALT main tx (#976) - Alphabet nodes now ignore notary notifications with non-HALT main tx (#976)
- neofs-adm now prints version of NNS contract (#1014) - neofs-adm now prints version of NNS contract (#1014)
- Possible NPE in blobovnicza (#1007) - Possible NPE in blobovnicza (#1007)
- More precise calculation of blobovnicza size (#915) - More precise calculation of blobovnicza size (#915)
@ -755,13 +794,13 @@ NeoFS API v2.11.0 support with response status codes and storage subnetworks.
- Alphabet nodes resign `AddPeer` request if it updates Storage node info (#938) - Alphabet nodes resign `AddPeer` request if it updates Storage node info (#938)
- All applications now use client from neofs-sdk-go library (#966) - All applications now use client from neofs-sdk-go library (#966)
- Some shard configuration records were renamed, see upgrading section (#859) - Some shard configuration records were renamed, see upgrading section (#859)
- `Nonce` and `VUB` values of notary transactions generated from notification - `Nonce` and `VUB` values of notary transactions generated from notification
hash (#844) hash (#844)
- Non alphabet notary invocations now have 4 witnesses (#975) - Non alphabet notary invocations now have 4 witnesses (#975)
- Object replication is now async and continuous (#965) - Object replication is now async and continuous (#965)
- NeoFS ADM updated for the neofs-contract v0.13.0 deploy (#984) - NeoFS ADM updated for the neofs-contract v0.13.0 deploy (#984)
- Minimal TLS version is set to v1.2 (#878) - Minimal TLS version is set to v1.2 (#878)
- Alphabet nodes now invoke `netmap.Register` to add node to the network map - Alphabet nodes now invoke `netmap.Register` to add node to the network map
candidates in notary enabled environment (#1008) candidates in notary enabled environment (#1008)
### Upgrading from v0.26.1 ### Upgrading from v0.26.1
@ -791,7 +830,7 @@ with `NEOFS_IR_FEE_NAMED_CONTAINER_REGISTER`.
### Fixed ### Fixed
- Storage Node handles requests before its initialization is finished (#934) - Storage Node handles requests before its initialization is finished (#934)
- Release worker pools gracefully (#901) - Release worker pools gracefully (#901)
- Metabase ignored containers of storage group and tombstone objects - Metabase ignored containers of storage group and tombstone objects
in listing (#945) in listing (#945)
- CLI missed endpoint flag in `control netmap-snapshot` command (#942) - CLI missed endpoint flag in `control netmap-snapshot` command (#942)
- Write cache object persisting (#866) - Write cache object persisting (#866)
@ -805,16 +844,16 @@ with `NEOFS_IR_FEE_NAMED_CONTAINER_REGISTER`.
### Changed ### Changed
- Use FSTree counter in write cache (#821) - Use FSTree counter in write cache (#821)
- Calculate notary deposit `till` parameter depending on available - Calculate notary deposit `till` parameter depending on available
deposit (#910) deposit (#910)
- Storage node returns session token error if attached token's private key - Storage node returns session token error if attached token's private key
is not available (#943) is not available (#943)
- Refactor of NeoFS API client in inner ring (#946) - Refactor of NeoFS API client in inner ring (#946)
- LOCODE generator tries to find the closest continent if there are - LOCODE generator tries to find the closest continent if there are
no exact match (#955) no exact match (#955)
### Upgrading from v0.26.0 ### Upgrading from v0.26.0
You can specify default section in storage engine configuration. You can specify default section in storage engine configuration.
See [example](./config/example/node.yaml) for more details. See [example](./config/example/node.yaml) for more details.
## [0.26.0] - 2021-10-19 - Udo (우도, 牛島) ## [0.26.0] - 2021-10-19 - Udo (우도, 牛島)
@ -824,7 +863,7 @@ NeoFS API v2.10 support
### Fixed ### Fixed
- Check remote node public key in every response message (#645) - Check remote node public key in every response message (#645)
- Do not lose local container size estimations (#872) - Do not lose local container size estimations (#872)
- Compressed and uncompressed objects are always available for reading - Compressed and uncompressed objects are always available for reading
regardless of compression configuration (#868) regardless of compression configuration (#868)
- Use request session token in ACL check of object.Put (#881) - Use request session token in ACL check of object.Put (#881)
- Parse URI in neofs-cli properly (#883) - Parse URI in neofs-cli properly (#883)
@ -878,7 +917,7 @@ instead.
### Added ### Added
- Support of multiple Neo RPC endpoints in Inner Ring node (#792) - Support of multiple Neo RPC endpoints in Inner Ring node (#792)
`mainchain` section of storage node config is left unused by the application. `mainchain` section of storage node config is left unused by the application.
## [0.25.0] - 2021-09-27 - Mungapdo (문갑도, 文甲島) ## [0.25.0] - 2021-09-27 - Mungapdo (문갑도, 文甲島)
@ -886,7 +925,7 @@ instead.
- Work of a storage node with one Neo RPC endpoint instead of a list (#746) - Work of a storage node with one Neo RPC endpoint instead of a list (#746)
- Lack of support for HEAD operation on the object write cache (#762) - Lack of support for HEAD operation on the object write cache (#762)
- Storage node attribute parsing is stable now (#787) - Storage node attribute parsing is stable now (#787)
- Inner Ring node now logs transaction hashes of Deposit and Withdraw events - Inner Ring node now logs transaction hashes of Deposit and Withdraw events
in LittleEndian encoding (#794) in LittleEndian encoding (#794)
- Storage node uses public keys of the remote nodes in placement traverser - Storage node uses public keys of the remote nodes in placement traverser
checks (#645) checks (#645)
@ -894,7 +933,7 @@ instead.
(#816) (#816)
- neofs-adm supports update and deploy of neofs-contract v0.11.0 (#834, #836) - neofs-adm supports update and deploy of neofs-contract v0.11.0 (#834, #836)
- Possible NPE in public key conversion (#848) - Possible NPE in public key conversion (#848)
- Object assembly routine do not forward existing request instead of creating - Object assembly routine do not forward existing request instead of creating
new one (#839) new one (#839)
- Shard now returns only physical stored objects for replication (#840) - Shard now returns only physical stored objects for replication (#840)
@ -903,7 +942,7 @@ instead.
- Smart contract address auto negotiation with NNS contract (#736) - Smart contract address auto negotiation with NNS contract (#736)
- Detailed logs for all data writing operations in storage engine (#790) - Detailed logs for all data writing operations in storage engine (#790)
- Docker build and release targets in Makefile (#785) - Docker build and release targets in Makefile (#785)
- Metabase restore option in the shard config (#789) - Metabase restore option in the shard config (#789)
- Write cache used size limit in bytes (#776) - Write cache used size limit in bytes (#776)
### Changed ### Changed
@ -938,7 +977,7 @@ Added `NEOFS_STORAGE_SHARD_<N>_WRITECACHE_SIZE_LIMIT` where `<N>` is shard ID.
This is the size limit for the all write cache storages combined in bytes. Default This is the size limit for the all write cache storages combined in bytes. Default
size limit is 1 GiB. size limit is 1 GiB.
Added `NEOFS_STORAGE_SHARD_<N>_REFILL_METABASE` bool flag where `<N>` is shard Added `NEOFS_STORAGE_SHARD_<N>_REFILL_METABASE` bool flag where `<N>` is shard
ID. This flag purges metabase instance at the application start and reinitialize ID. This flag purges metabase instance at the application start and reinitialize
it with available objects from the blobstor. it with available objects from the blobstor.
@ -947,12 +986,12 @@ Object service pool size now split into `NEOFS_OBJECT_PUT_POOL_SIZE_REMOTE` and
## [0.24.1] - 2021-09-07 ## [0.24.1] - 2021-09-07
### Fixed ### Fixed
- Storage and Inner Ring will not start until Neo RPC node will have the height - Storage and Inner Ring will not start until Neo RPC node will have the height
of the latest processed block by the nodes (#795) of the latest processed block by the nodes (#795)
### Upgrading from v0.24.0 ### Upgrading from v0.24.0
Specify path to the local state DB in Inner Ring node config with Specify path to the local state DB in Inner Ring node config with
`NEOFS_IR_NODE_PERSISTENT_STATE_PATH`. Specify path to the local state DB in `NEOFS_IR_NODE_PERSISTENT_STATE_PATH`. Specify path to the local state DB in
Storage node config with `NEOFS_NODE_PERSISTENT_STATE_PATH`. Storage node config with `NEOFS_NODE_PERSISTENT_STATE_PATH`.
@ -971,7 +1010,7 @@ Storage node config with `NEOFS_NODE_PERSISTENT_STATE_PATH`.
- Contract update support in `neofs-adm` utility (#748) - Contract update support in `neofs-adm` utility (#748)
- Container transferring support in `neofs-adm` utility (#755) - Container transferring support in `neofs-adm` utility (#755)
- Storage Node's balance refilling support in `neofs-adm` utility (#758) - Storage Node's balance refilling support in `neofs-adm` utility (#758)
- Support `COMMON_PREFIX` filter for object attributes in storage engine and `neofs-cli` (#760) - Support `COMMON_PREFIX` filter for object attributes in storage engine and `neofs-cli` (#760)
- Node's and IR's notary status debug message on startup (#758) - Node's and IR's notary status debug message on startup (#758)
- Go `1.17` unit tests in CI (#766) - Go `1.17` unit tests in CI (#766)
- Supporting all eACL filter fields from the specification (#768) - Supporting all eACL filter fields from the specification (#768)
@ -1033,7 +1072,7 @@ Improved stability for notary disabled environment.
- Storage Node configuration example contains usable parameters (#699) - Storage Node configuration example contains usable parameters (#699)
### Fixed ### Fixed
- Do not use side chain RoleManagement contract as source of Inner Ring list - Do not use side chain RoleManagement contract as source of Inner Ring list
when notary disabled in side chain (#672) when notary disabled in side chain (#672)
- Alphabet list transition is even more effective (#697) - Alphabet list transition is even more effective (#697)
- Inner Ring node does not require proxy and processing contracts if notary - Inner Ring node does not require proxy and processing contracts if notary
@ -1100,9 +1139,9 @@ Storage nodes with a group of network endpoints.
- Control service with healthcheck RPC in IR and CLI support ([#414](https://github.com/nspcc-dev/neofs-node/issues/414)). - Control service with healthcheck RPC in IR and CLI support ([#414](https://github.com/nspcc-dev/neofs-node/issues/414)).
### Fixed ### Fixed
- Approval of objects with with duplicate attribute keys or empty values ([#633](https://github.com/nspcc-dev/neofs-node/issues/633)). - Approval of objects with with duplicate attribute keys or empty values ([#633](https://github.com/nspcc-dev/neofs-node/issues/633)).
- Approval of containers with with duplicate attribute keys or empty values ([#634](https://github.com/nspcc-dev/neofs-node/issues/634)). - Approval of containers with with duplicate attribute keys or empty values ([#634](https://github.com/nspcc-dev/neofs-node/issues/634)).
- Default path for CLI config ([#626](https://github.com/nspcc-dev/neofs-node/issues/626)). - Default path for CLI config ([#626](https://github.com/nspcc-dev/neofs-node/issues/626)).
### Changed ### Changed
- `version` command replaced with `--version` flag in CLI ([#571](https://github.com/nspcc-dev/neofs-node/issues/571)). - `version` command replaced with `--version` flag in CLI ([#571](https://github.com/nspcc-dev/neofs-node/issues/571)).
@ -1130,7 +1169,7 @@ Storage nodes with a group of network endpoints.
- grpc: [v1.38.0](https://github.com/grpc/grpc-go/releases/tag/v1.38.0). - grpc: [v1.38.0](https://github.com/grpc/grpc-go/releases/tag/v1.38.0).
- cast: [v1.3.1](https://github.com/spf13/cast/releases/tag/v1.3.1). - cast: [v1.3.1](https://github.com/spf13/cast/releases/tag/v1.3.1).
- cobra: [1.1.3](https://github.com/spf13/cobra/releases/tag/v1.1.3). - cobra: [1.1.3](https://github.com/spf13/cobra/releases/tag/v1.1.3).
- viper: [v1.8.1](https://github.com/spf13/viper/releases/tag/v1.8.1). - viper: [v1.8.1](https://github.com/spf13/viper/releases/tag/v1.8.1).
## [0.21.1] - 2021-06-10 ## [0.21.1] - 2021-06-10
@ -1150,7 +1189,7 @@ Session token support in container service, refactored config in storage node,
TLS support on gRPC servers. TLS support on gRPC servers.
### Fixed ### Fixed
- ACL service traverses over all RequestMetaHeader chain to find - ACL service traverses over all RequestMetaHeader chain to find
bearer and session tokens (#548). bearer and session tokens (#548).
- Object service correctly resends complete objects without attached - Object service correctly resends complete objects without attached
session token (#501). session token (#501).
@ -1158,7 +1197,7 @@ TLS support on gRPC servers.
- Client cache now gracefully closes all available connections (#567). - Client cache now gracefully closes all available connections (#567).
### Added ### Added
- Session token support in container service for `container.Put`, - Session token support in container service for `container.Put`,
`container.Delete` and `container.SetEACL` operations. `container.Delete` and `container.SetEACL` operations.
- Session token support in container and sign command of NeoFS CLI. - Session token support in container and sign command of NeoFS CLI.
- TLS encryption support of gRPC service in storage node. - TLS encryption support of gRPC service in storage node.
@ -1168,8 +1207,8 @@ TLS support on gRPC servers.
update earlier. update earlier.
- Inner ring processes extended ACL changes. - Inner ring processes extended ACL changes.
- Inner ring makes signature checks of containers and extended ACLs. - Inner ring makes signature checks of containers and extended ACLs.
- Refactored config of storage node. - Refactored config of storage node.
- Static clients from `morph/client` do not process notary invocations - Static clients from `morph/client` do not process notary invocations
explicitly anymore. Now notary support specified at static client creation. explicitly anymore. Now notary support specified at static client creation.
- Updated neo-go to v0.95.1 release. - Updated neo-go to v0.95.1 release.
- Updated neofs-api-go to v1.27.0 release. - Updated neofs-api-go to v1.27.0 release.
@ -1180,7 +1219,7 @@ TLS support on gRPC servers.
## [0.20.0] - 2021-05-21 - Dolsando (돌산도, 突山島) ## [0.20.0] - 2021-05-21 - Dolsando (돌산도, 突山島)
NeoFS is N3 RC2 compatible. NeoFS is N3 RC2 compatible.
### Fixed ### Fixed
- Calculations in EigenTrust algorithm (#527). - Calculations in EigenTrust algorithm (#527).
@ -1193,7 +1232,7 @@ NeoFS is N3 RC2 compatible.
- Client for NeoFSID contract. - Client for NeoFSID contract.
### Changed ### Changed
- Reorganized and removed plenty of application configuration records - Reorganized and removed plenty of application configuration records
(#510, #511, #512, #514). (#510, #511, #512, #514).
- Nodes do not resolve remote addresses manually. - Nodes do not resolve remote addresses manually.
- Presets for basic ACL in CLI are `private` ,`public-read` and - Presets for basic ACL in CLI are `private` ,`public-read` and
@ -1211,11 +1250,11 @@ NeoFS is N3 RC2 compatible.
Storage nodes exchange, calculate, aggregate and store reputation information Storage nodes exchange, calculate, aggregate and store reputation information
in reputation contract. Inner ring nodes support workflows with and without in reputation contract. Inner ring nodes support workflows with and without
notary subsystem in chains. notary subsystem in chains.
### Fixed ### Fixed
- Build with go1.16. - Build with go1.16.
- Notary deposits last more blocks. - Notary deposits last more blocks.
- TX hashes now prints in little endian in logs. - TX hashes now prints in little endian in logs.
- Metabase deletes graves regardless of the presence of objects. - Metabase deletes graves regardless of the presence of objects.
- SplitInfo error created from all shards instead of first matched shard. - SplitInfo error created from all shards instead of first matched shard.
@ -1223,7 +1262,7 @@ notary subsystem in chains.
- Storage node does not send rebootstrap messages after it went offline. - Storage node does not send rebootstrap messages after it went offline.
### Added ### Added
- Reputation subsystem that includes reputation collection, exchange, - Reputation subsystem that includes reputation collection, exchange,
calculation and storage components. calculation and storage components.
- Notary and non notary workflows in inner ring. - Notary and non notary workflows in inner ring.
- Audit fee transfer for inner ring nodes that performed audit. - Audit fee transfer for inner ring nodes that performed audit.
@ -1233,7 +1272,7 @@ calculation and storage components.
### Changed ### Changed
- Metabase puts data in batches. - Metabase puts data in batches.
- Network related new epoch handlers in storage node executed asynchronously. - Network related new epoch handlers in storage node executed asynchronously.
- Storage node gets epoch duration from global config. - Storage node gets epoch duration from global config.
- Storage node resign and resend Search, Range, Head, Get requests of object - Storage node resign and resend Search, Range, Head, Get requests of object
service without modification. service without modification.
@ -1250,7 +1289,7 @@ alphabet keys are synchronized with main chain.
### Fixed ### Fixed
- Metabase does not store object payloads anymore. - Metabase does not store object payloads anymore.
- TTLNetCache now always evict data after a timeout. - TTLNetCache now always evict data after a timeout.
- NeoFS CLI keyer could misinterpret hex value as base58. - NeoFS CLI keyer could misinterpret hex value as base58.
### Added ### Added
- Local trust controller in storage node. - Local trust controller in storage node.
@ -1262,7 +1301,7 @@ alphabet keys are synchronized with main chain.
## [0.17.0] - 2021-03-22 - Jebudo (제부도, 濟扶島) ## [0.17.0] - 2021-03-22 - Jebudo (제부도, 濟扶島)
Notary contract support, updated neofs-api-go with raw client, some performance Notary contract support, updated neofs-api-go with raw client, some performance
tweaks with extra caches and enhanced metrics. tweaks with extra caches and enhanced metrics.
### Added ### Added
@ -1281,7 +1320,7 @@ tweaks with extra caches and enhanced metrics.
Garbage collector is now running inside storage engine. It is accessed Garbage collector is now running inside storage engine. It is accessed
via Control API, from `policer` component and through object expiration via Control API, from `policer` component and through object expiration
scrubbers. scrubbers.
Inner ring configuration now supports single chain mode with any number of Inner ring configuration now supports single chain mode with any number of
alphabet contracts. alphabet contracts.
@ -1312,39 +1351,39 @@ Storage node now supports NetworkInfo method in netmap service.
## [0.15.0] - 2021-02-12 - Seonyudo (선유도, 仙遊島) ## [0.15.0] - 2021-02-12 - Seonyudo (선유도, 仙遊島)
NeoFS nodes are now preview5-compatible. NeoFS nodes are now preview5-compatible.
IR nodes are now engaged in the distribution of funds to the storage nodes: IR nodes are now engaged in the distribution of funds to the storage nodes:
for the passed audit and for the amount of stored information. All timers for the passed audit and for the amount of stored information. All timers
of the IR nodes related to the generation and processing of global system of the IR nodes related to the generation and processing of global system
events are decoupled from astronomical time, and are measured in the number events are decoupled from astronomical time, and are measured in the number
of blockchain blocks. of blockchain blocks.
For the geographic positioning of storage nodes, a global NeoFS location For the geographic positioning of storage nodes, a global NeoFS location
database is now used, the key in which is a UN/LOCODE, and the base itself database is now used, the key in which is a UN/LOCODE, and the base itself
is generated on the basis of the UN/LOCODE and OpenFlights databases. is generated on the basis of the UN/LOCODE and OpenFlights databases.
### Added ### Added
- Timers with time in blocks of the chain. - Timers with time in blocks of the chain.
- Subscriptions to new blocks in blockchain event `Listener`. - Subscriptions to new blocks in blockchain event `Listener`.
- Tracking the volume of stored information by containers in the - Tracking the volume of stored information by containers in the
storage engine and an external interface for obtaining this data. storage engine and an external interface for obtaining this data.
- `TransferX` operation in sidechain client. - `TransferX` operation in sidechain client.
- Calculators of audit and basic settlements. - Calculators of audit and basic settlements.
- Distribution of funds to storage nodes for audit and for the amount - Distribution of funds to storage nodes for audit and for the amount
of stored information (settlement processors of IR). of stored information (settlement processors of IR).
- NeoFS API `Container.AnnounceUsedSpace` RPC service. - NeoFS API `Container.AnnounceUsedSpace` RPC service.
- Exchange of information about container volumes between storage nodes - Exchange of information about container volumes between storage nodes
controlled by IR through sidechain notifications. controlled by IR through sidechain notifications.
- Support of new search matchers (`STRING_NOT_EQUAL`, `NOT_PRESENT`). - Support of new search matchers (`STRING_NOT_EQUAL`, `NOT_PRESENT`).
- Functional for the formation of NeoFS location database. - Functional for the formation of NeoFS location database.
- CLI commands for generating and reading the location database. - CLI commands for generating and reading the location database.
- Checking the locode attribute and generating geographic attributes - Checking the locode attribute and generating geographic attributes
for candidates for a network map on IR side. for candidates for a network map on IR side.
- Verification of the eACL signature when checking Object ACL rules. - Verification of the eACL signature when checking Object ACL rules.
### Fixed ### Fixed
- Overwriting the local configuration of node attributes when updating - Overwriting the local configuration of node attributes when updating
the network map. the network map.
- Ignoring the X-headers CLI `storagegroup` commands. - Ignoring the X-headers CLI `storagegroup` commands.
- Inability to attach bearer token in CLI `storagegroup` commands. - Inability to attach bearer token in CLI `storagegroup` commands.
@ -1362,7 +1401,7 @@ is generated on the basis of the UN/LOCODE and OpenFlights databases.
### Fixed ### Fixed
- Upload of objects bigger than single gRPC message. - Upload of objects bigger than single gRPC message.
- Inconsistent placement issues (#347, #349). - Inconsistent placement issues (#347, #349).
- Bug when ACL request classifier failed to classify `RoleOthers` in - Bug when ACL request classifier failed to classify `RoleOthers` in
first epoch. first epoch.
### Added ### Added
@ -1376,13 +1415,13 @@ is generated on the basis of the UN/LOCODE and OpenFlights databases.
Testnet4 related bugfixes. Testnet4 related bugfixes.
### Fixed ### Fixed
- Default values for blobovnicza object size limit and blobstor small object - Default values for blobovnicza object size limit and blobstor small object
size are not zero. size are not zero.
- Various storage engine log messages. - Various storage engine log messages.
- Bug when inner ring node ignored bootstrap messages from restarted storage - Bug when inner ring node ignored bootstrap messages from restarted storage
nodes. nodes.
### Added ### Added
- Timeout for reading boltDB files at storage node initialization. - Timeout for reading boltDB files at storage node initialization.

View file

@ -38,7 +38,7 @@ $ git clone https://github.com/TrueCloudLab/frostfs-node
### Set up git remote as ``upstream`` ### Set up git remote as ``upstream``
```sh ```sh
$ cd neofs-node $ cd frostfs-node
$ git remote add upstream https://github.com/TrueCloudLab/frostfs-node $ git remote add upstream https://github.com/TrueCloudLab/frostfs-node
$ git fetch upstream $ git fetch upstream
$ git merge upstream/master $ git merge upstream/master

View file

@ -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

17
Makefile Normal file → Executable file
View file

@ -16,7 +16,7 @@ RELEASE = release
DIRS = $(BIN) $(RELEASE) DIRS = $(BIN) $(RELEASE)
# List of binaries to build. # List of binaries to build.
CMDS = $(notdir $(basename $(wildcard cmd/*))) CMDS = $(notdir $(basename $(wildcard cmd/frostfs-*)))
BINS = $(addprefix $(BIN)/, $(CMDS)) BINS = $(addprefix $(BIN)/, $(CMDS))
# .deb package versioning # .deb package versioning
@ -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 prepare-release debpackage pre-commit unpre-commit
# 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 github.com/TrueCloudLab/frostfs-api-go/v2/util/protogen @GOBIN=$(abspath $(BIN)) go install -mod=mod -v git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/protogen
# Protoc generate # 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 "; \
@ -140,10 +140,19 @@ 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
@ -152,7 +161,7 @@ clean:
# Package for Debian # Package for Debian
debpackage: debpackage:
dch --package frostfs-node \ dch -b --package frostfs-node \
--controlmaint \ --controlmaint \
--newversion $(PKG_VERSION) \ --newversion $(PKG_VERSION) \
--distribution $(OS_RELEASE) \ --distribution $(OS_RELEASE) \

View file

@ -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://github.com/TrueCloudLab/frostfs-api) and has FrostFS has a native [gRPC API](https://git.frostfs.info/TrueCloudLab/frostfs-api) and has
protocol gateways for popular protocols such as [AWS 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),

View file

@ -3,23 +3,22 @@
## 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://github.com/TrueCloudLab/frostfs-contract/releases). [frostfs-contract repository](https://git.frostfs.info/TrueCloudLab/frostfs-contract/releases).
## Commands ## Commands
@ -27,7 +26,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:
@ -58,14 +57,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
@ -75,7 +74,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.
@ -87,7 +86,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.

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,14 @@
package commonflags
const (
ConfigFlag = "config"
ConfigFlagShorthand = "c"
ConfigFlagUsage = "Config file"
ConfigDirFlag = "config-dir"
ConfigDirFlagUsage = "Config directory"
Verbose = "verbose"
VerboseShorthand = "v"
VerboseUsage = "Verbose output"
)

View file

@ -7,7 +7,7 @@ import (
"path/filepath" "path/filepath"
"text/template" "text/template"
"github.com/TrueCloudLab/frostfs-node/pkg/innerring" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
"github.com/nspcc-dev/neo-go/cli/input" "github.com/nspcc-dev/neo-go/cli/input"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"

View file

@ -5,7 +5,7 @@ import (
"path/filepath" "path/filepath"
"testing" "testing"
"github.com/TrueCloudLab/frostfs-node/pkg/innerring" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
"github.com/spf13/viper" "github.com/spf13/viper"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )

View file

@ -6,8 +6,8 @@ import (
"fmt" "fmt"
"math/big" "math/big"
"github.com/TrueCloudLab/frostfs-contract/nns" "git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
"github.com/TrueCloudLab/frostfs-sdk-go/netmap" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
"github.com/nspcc-dev/neo-go/pkg/core/native/noderoles" "github.com/nspcc-dev/neo-go/pkg/core/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"
@ -44,6 +44,7 @@ const (
notaryEnabled = true notaryEnabled = true
) )
// nolint: funlen, gocognit
func dumpBalances(cmd *cobra.Command, _ []string) error { func dumpBalances(cmd *cobra.Command, _ []string) error {
var ( var (
dumpStorage, _ = cmd.Flags().GetBool(dumpBalancesStorageFlag) dumpStorage, _ = cmd.Flags().GetBool(dumpBalancesStorageFlag)

View file

@ -140,14 +140,14 @@ func setConfigCmd(cmd *cobra.Command, args []string) error {
return wCtx.awaitTx() return wCtx.awaitTx()
} }
func parseConfigPair(kvStr string, force bool) (key string, val interface{}, err error) { func parseConfigPair(kvStr string, force bool) (key string, val any, err error) {
kv := strings.SplitN(kvStr, "=", 2) k, v, found := strings.Cut(kvStr, "=")
if len(kv) != 2 { if !found {
return "", nil, fmt.Errorf("invalid parameter format: must be 'key=val', got: %s", kvStr) return "", nil, fmt.Errorf("invalid parameter format: must be 'key=val', got: %s", kvStr)
} }
key = kv[0] key = k
valRaw := kv[1] valRaw := v
switch key { switch key {
case netmapAuditFeeKey, netmapBasicIncomeRateKey, case netmapAuditFeeKey, netmapBasicIncomeRateKey,
@ -162,7 +162,7 @@ func parseConfigPair(kvStr string, force bool) (key string, val interface{}, err
case netmapEigenTrustAlphaKey: case netmapEigenTrustAlphaKey:
// just check that it could // just check that it could
// be parsed correctly // be parsed correctly
_, err = strconv.ParseFloat(kv[1], 64) _, err = strconv.ParseFloat(v, 64)
if err != nil { if err != nil {
err = fmt.Errorf("could not parse %s's value '%s' as float: %w", key, valRaw, err) err = fmt.Errorf("could not parse %s's value '%s' as float: %w", key, valRaw, err)
} }

View file

@ -7,7 +7,7 @@ import (
"os" "os"
"sort" "sort"
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/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"
@ -152,6 +152,7 @@ func listContainers(cmd *cobra.Command, _ []string) error {
return nil return nil
} }
// nolint: funlen
func restoreContainers(cmd *cobra.Command, _ []string) error { func restoreContainers(cmd *cobra.Command, _ []string) error {
filename, err := cmd.Flags().GetString(containerDumpFlag) filename, err := cmd.Flags().GetString(containerDumpFlag)
if err != nil { if err != nil {

View file

@ -6,7 +6,7 @@ import (
"os" "os"
"strings" "strings"
"github.com/TrueCloudLab/frostfs-contract/nns" "git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
"github.com/nspcc-dev/neo-go/cli/cmdargs" "github.com/nspcc-dev/neo-go/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"
@ -57,6 +57,7 @@ func init() {
ff.String(customZoneFlag, "frostfs", "Custom zone for NNS") ff.String(customZoneFlag, "frostfs", "Custom zone for NNS")
} }
// nolint: funlen
func deployContractCmd(cmd *cobra.Command, args []string) error { func deployContractCmd(cmd *cobra.Command, args []string) error {
v := viper.GetViper() v := viper.GetViper()
c, err := newInitializeContext(cmd, v) c, err := newInitializeContext(cmd, v)

View file

@ -2,11 +2,13 @@ package morph
import ( import (
"bytes" "bytes"
"errors"
"fmt" "fmt"
"strings" "strings"
"text/tabwriter" "text/tabwriter"
"github.com/TrueCloudLab/frostfs-contract/nns" "git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
morphClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/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"
@ -107,31 +109,30 @@ func dumpContractHashes(cmd *cobra.Command, _ []string) error {
func dumpCustomZoneHashes(cmd *cobra.Command, nnsHash util.Uint160, zone string, c Client) error { func dumpCustomZoneHashes(cmd *cobra.Command, nnsHash util.Uint160, zone string, c Client) error {
const nnsMaxTokens = 100 const nnsMaxTokens = 100
inv := invoker.New(c, nil)
arr, err := unwrap.Array(inv.CallAndExpandIterator(nnsHash, "tokens", nnsMaxTokens)) inv := invoker.New(c, nil)
if err != nil {
return fmt.Errorf("can't get a list of NNS domains: %w", err)
}
if !strings.HasPrefix(zone, ".") { if !strings.HasPrefix(zone, ".") {
zone = "." + zone zone = "." + zone
} }
var infos []contractDumpInfo var infos []contractDumpInfo
for i := range arr { processItem := func(item stackitem.Item) {
bs, err := arr[i].TryBytes() bs, err := item.TryBytes()
if err != nil { if err != nil {
continue cmd.PrintErrf("Invalid NNS record: %v\n", err)
return
} }
if !bytes.HasSuffix(bs, []byte(zone)) { if !bytes.HasSuffix(bs, []byte(zone)) || bytes.HasPrefix(bs, []byte(morphClient.NNSGroupKeyName)) {
continue // Related https://github.com/nspcc-dev/neofs-contract/issues/316.
return
} }
h, err := nnsResolveHash(inv, nnsHash, string(bs)) h, err := nnsResolveHash(inv, nnsHash, string(bs))
if err != nil { if err != nil {
continue cmd.PrintErrf("Could not resolve name %s: %v\n", string(bs), err)
return
} }
infos = append(infos, contractDumpInfo{ infos = append(infos, contractDumpInfo{
@ -140,6 +141,39 @@ func dumpCustomZoneHashes(cmd *cobra.Command, nnsHash util.Uint160, zone string,
}) })
} }
sessionID, iter, err := unwrap.SessionIterator(inv.Call(nnsHash, "tokens"))
if err != nil {
if errors.Is(err, unwrap.ErrNoSessionID) {
items, err := unwrap.Array(inv.CallAndExpandIterator(nnsHash, "tokens", nnsMaxTokens))
if err != nil {
return fmt.Errorf("can't get a list of NNS domains: %w", err)
}
if len(items) == nnsMaxTokens {
cmd.PrintErrln("Provided RPC endpoint doesn't support sessions, some hashes might be lost.")
}
for i := range items {
processItem(items[i])
}
} else {
return err
}
} else {
defer func() {
_ = inv.TerminateSession(sessionID)
}()
items, err := inv.TraverseIterator(sessionID, &iter, nnsMaxTokens)
for err == nil && len(items) != 0 {
for i := range items {
processItem(items[i])
}
items, err = inv.TraverseIterator(sessionID, &iter, nnsMaxTokens)
}
if err != nil {
return fmt.Errorf("error during NNS domains iteration: %w", err)
}
}
fillContractVersion(cmd, c, infos) fillContractVersion(cmd, c, infos)
printContractInfo(cmd, infos) printContractInfo(cmd, infos)

View file

@ -6,8 +6,8 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
"github.com/TrueCloudLab/frostfs-node/pkg/innerring" "git.frostfs.info/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"

View file

@ -9,7 +9,7 @@ import (
"strconv" "strconv"
"testing" "testing"
"github.com/TrueCloudLab/frostfs-node/pkg/innerring" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
"github.com/nspcc-dev/neo-go/cli/input" "github.com/nspcc-dev/neo-go/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"

View file

@ -6,7 +6,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/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"

View file

@ -7,9 +7,9 @@ import (
"path/filepath" "path/filepath"
"time" "time"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
"github.com/TrueCloudLab/frostfs-node/pkg/innerring" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
morphClient "github.com/TrueCloudLab/frostfs-node/pkg/morph/client" morphClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames" "github.com/nspcc-dev/neo-go/pkg/core/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"
@ -108,6 +108,7 @@ func (c *initializeContext) close() {
} }
} }
// nolint: funlen
func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContext, error) { func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContext, error) {
walletDir := config.ResolveHomePath(viper.GetString(alphabetWalletsFlag)) walletDir := config.ResolveHomePath(viper.GetString(alphabetWalletsFlag))
wallets, err := openAlphabetWallets(v, walletDir) wallets, err := openAlphabetWallets(v, walletDir)
@ -115,8 +116,10 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex
return nil, err return nil, err
} }
needContracts := cmd.Name() == "update-contracts" || cmd.Name() == "init"
var w *wallet.Wallet var w *wallet.Wallet
if cmd.Name() != "deploy" { if needContracts {
w, err = openContractWallet(v, cmd, walletDir) w, err = openContractWallet(v, cmd, walletDir)
if err != nil { if err != nil {
return nil, err return nil, err
@ -157,7 +160,6 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex
} }
} }
needContracts := cmd.Name() == "update-contracts" || cmd.Name() == "init"
if needContracts { if needContracts {
ctrPath, err = cmd.Flags().GetString(contractsInitFlag) ctrPath, err = cmd.Flags().GetString(contractsInitFlag)
if err != nil { if err != nil {

View file

@ -12,10 +12,10 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/TrueCloudLab/frostfs-contract/common" "git.frostfs.info/TrueCloudLab/frostfs-contract/common"
"github.com/TrueCloudLab/frostfs-contract/nns" "git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
"github.com/TrueCloudLab/frostfs-node/pkg/innerring" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
morphClient "github.com/TrueCloudLab/frostfs-node/pkg/morph/client" morphClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
"github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/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"
@ -156,6 +156,7 @@ func (c *initializeContext) deployNNS(method string) error {
return c.awaitTx() return c.awaitTx()
} }
// nolint: funlen
func (c *initializeContext) updateContracts() error { func (c *initializeContext) updateContracts() error {
alphaCs := c.getContract(alphabetContract) alphaCs := c.getContract(alphabetContract)
@ -167,7 +168,7 @@ func (c *initializeContext) updateContracts() error {
w := io2.NewBufBinWriter() w := io2.NewBufBinWriter()
var keysParam []interface{} 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.
@ -299,7 +300,7 @@ func (c *initializeContext) updateContracts() error {
func (c *initializeContext) deployContracts() error { func (c *initializeContext) deployContracts() error {
alphaCs := c.getContract(alphabetContract) alphaCs := c.getContract(alphabetContract)
var keysParam []interface{} var keysParam []any
baseGroups := alphaCs.Manifest.Groups baseGroups := alphaCs.Manifest.Groups
@ -510,12 +511,12 @@ func readContractsFromArchive(file io.Reader, names []string) (map[string]*contr
return m, nil return m, nil
} }
func getContractDeployParameters(cs *contractState, deployData []interface{}) []interface{} { func getContractDeployParameters(cs *contractState, deployData []any) []any {
return []interface{}{cs.RawNEF, cs.RawManifest, deployData} return []any{cs.RawNEF, cs.RawManifest, deployData}
} }
func (c *initializeContext) getContractDeployData(ctrName string, keysParam []interface{}) []interface{} { func (c *initializeContext) getContractDeployData(ctrName string, keysParam []any) []any {
items := make([]interface{}, 1, 6) items := make([]any, 1, 6)
items[0] = false // notaryDisabled is false items[0] = false // notaryDisabled is false
switch ctrName { switch ctrName {
@ -551,7 +552,7 @@ func (c *initializeContext) getContractDeployData(ctrName string, keysParam []in
c.Contracts[netmapContract].Hash, c.Contracts[netmapContract].Hash,
c.Contracts[containerContract].Hash) c.Contracts[containerContract].Hash)
case netmapContract: case netmapContract:
configParam := []interface{}{ configParam := []any{
netmapEpochKey, viper.GetInt64(epochDurationInitFlag), netmapEpochKey, viper.GetInt64(epochDurationInitFlag),
netmapMaxObjectSizeKey, viper.GetInt64(maxObjectSizeInitFlag), netmapMaxObjectSizeKey, viper.GetInt64(maxObjectSizeInitFlag),
netmapAuditFeeKey, viper.GetInt64(auditFeeInitFlag), netmapAuditFeeKey, viper.GetInt64(auditFeeInitFlag),
@ -580,8 +581,8 @@ func (c *initializeContext) getContractDeployData(ctrName string, keysParam []in
return items return items
} }
func (c *initializeContext) getAlphabetDeployItems(i, n int) []interface{} { func (c *initializeContext) getAlphabetDeployItems(i, n int) []any {
items := make([]interface{}, 6) items := make([]any, 6)
items[0] = false items[0] = false
items[1] = c.Contracts[netmapContract].Hash items[1] = c.Contracts[netmapContract].Hash
items[2] = c.Contracts[proxyContract].Hash items[2] = c.Contracts[proxyContract].Hash

View file

@ -7,8 +7,8 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/TrueCloudLab/frostfs-contract/nns" "git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
morphClient "github.com/TrueCloudLab/frostfs-node/pkg/morph/client" morphClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
"github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/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"
@ -82,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()
needUpdate, needRegister, err := c.emitUpdateNNSGroupScript(bw, nnsHash, pub) keyAlreadyAdded, domainRegCodeEmitted, err := c.emitUpdateNNSGroupScript(bw, nnsHash, pub)
if !needUpdate || err != nil { if keyAlreadyAdded || err != nil {
return err return err
} }
script := bw.Bytes() script := bw.Bytes()
if needRegister { if domainRegCodeEmitted {
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)
@ -228,20 +228,27 @@ func nnsResolve(inv *invoker.Invoker, nnsHash util.Uint160, domain string) (stac
} }
func nnsResolveKey(inv *invoker.Invoker, nnsHash util.Uint160, domain string) (*keys.PublicKey, error) { func nnsResolveKey(inv *invoker.Invoker, nnsHash util.Uint160, domain string) (*keys.PublicKey, error) {
item, err := nnsResolve(inv, nnsHash, domain) res, err := nnsResolve(inv, nnsHash, domain)
if err != nil { if err != nil {
return nil, err return nil, err
} }
v, ok := item.Value().(stackitem.Null) if _, ok := res.Value().(stackitem.Null); ok {
if ok {
return nil, errors.New("NNS record is missing") return nil, errors.New("NNS record is missing")
} }
bs, err := v.TryBytes() arr, ok := res.Value().([]stackitem.Item)
if err != nil { if !ok {
return nil, errors.New("malformed response") return nil, errors.New("API of the NNS contract method `resolve` has changed")
} }
for i := range arr {
var bs []byte
bs, err = arr[i].TryBytes()
if err != nil {
continue
}
return keys.NewPublicKeyFromString(string(bs)) return keys.NewPublicKeyFromString(string(bs))
}
return nil, errors.New("no valid keys are found")
} }
// parseNNSResolveResult parses the result of resolving NNS record. // parseNNSResolveResult parses the result of resolving NNS record.
@ -281,7 +288,7 @@ func nnsIsAvailable(c Client, nnsHash util.Uint160, name string) (bool, error) {
case *rpcclient.Client: case *rpcclient.Client:
return ct.NNSIsAvailable(nnsHash, name) return ct.NNSIsAvailable(nnsHash, name)
default: default:
b, err := unwrap.Bool(invokeFunction(c, nnsHash, "isAvailable", []interface{}{name}, nil)) b, err := unwrap.Bool(invokeFunction(c, nnsHash, "isAvailable", []any{name}, nil))
if err != nil { if err != nil {
return false, fmt.Errorf("`isAvailable`: invalid response: %w", err) return false, fmt.Errorf("`isAvailable`: invalid response: %w", err)
} }

View file

@ -16,7 +16,7 @@ func (c *initializeContext) setNotaryAndAlphabetNodes() error {
return err return err
} }
var pubs []interface{} var pubs []any
for _, acc := range c.Accounts { for _, acc := range c.Accounts {
pubs = append(pubs, acc.PrivateKey().PublicKey().Bytes()) pubs = append(pubs, acc.PrivateKey().PublicKey().Bytes())
} }

View file

@ -7,7 +7,7 @@ import (
"strconv" "strconv"
"testing" "testing"
"github.com/TrueCloudLab/frostfs-node/pkg/innerring" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
"github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/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"
@ -27,6 +27,9 @@ func TestInitialize(t *testing.T) {
// It is here for performing local testing after the changes. // It is here for performing local testing after the changes.
t.Skip() t.Skip()
t.Run("1 nodes", func(t *testing.T) {
testInitialize(t, 1)
})
t.Run("4 nodes", func(t *testing.T) { t.Run("4 nodes", func(t *testing.T) {
testInitialize(t, 4) testInitialize(t, 4)
}) })
@ -96,6 +99,7 @@ func generateTestData(t *testing.T, dir string, size int) {
} }
cfg := config.Config{} cfg := config.Config{}
cfg.ProtocolConfiguration.Magic = 12345
cfg.ProtocolConfiguration.ValidatorsCount = size cfg.ProtocolConfiguration.ValidatorsCount = size
cfg.ProtocolConfiguration.SecondsPerBlock = 1 cfg.ProtocolConfiguration.SecondsPerBlock = 1
cfg.ProtocolConfiguration.StandbyCommittee = pubs // sorted by glagolic letters cfg.ProtocolConfiguration.StandbyCommittee = pubs // sorted by glagolic letters

View file

@ -2,7 +2,7 @@ syntax = "proto3";
package neo.fs.v2.refs; package neo.fs.v2.refs;
option go_package = "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/internal"; option go_package = "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/internal";
// Client group identifier in the FrostFS subnet. // Client group identifier in the FrostFS subnet.
// //

View file

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"os" "os"
"sort" "sort"
"time"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/config"
@ -20,6 +21,7 @@ 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/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"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/fixedn" "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/neorpc/result" "github.com/nspcc-dev/neo-go/pkg/neorpc/result"
@ -188,7 +190,7 @@ func (l *localClient) GetCommittee() (keys.PublicKeys, error) {
func (l *localClient) InvokeFunction(h util.Uint160, method string, sPrm []smartcontract.Parameter, ss []transaction.Signer) (*result.Invoke, error) { func (l *localClient) InvokeFunction(h util.Uint160, method string, sPrm []smartcontract.Parameter, ss []transaction.Signer) (*result.Invoke, error) {
var err error var err error
pp := make([]interface{}, len(sPrm)) pp := make([]any, len(sPrm))
for i, p := range sPrm { for i, p := range sPrm {
pp[i], err = smartcontract.ExpandParameterToEmitable(p) pp[i], err = smartcontract.ExpandParameterToEmitable(p)
if err != nil { if err != nil {
@ -226,7 +228,24 @@ func (l *localClient) TraverseIterator(_, _ uuid.UUID, _ int) ([]stackitem.Item,
// GetVersion return default version. // GetVersion return default version.
func (l *localClient) GetVersion() (*result.Version, error) { func (l *localClient) GetVersion() (*result.Version, error) {
return &result.Version{}, nil c := l.bc.GetConfig()
return &result.Version{
Protocol: result.Protocol{
AddressVersion: address.NEO3Prefix,
Network: c.Magic,
MillisecondsPerBlock: int(c.TimePerBlock / time.Millisecond),
MaxTraceableBlocks: c.MaxTraceableBlocks,
MaxValidUntilBlockIncrement: c.MaxValidUntilBlockIncrement,
MaxTransactionsPerBlock: c.MaxTransactionsPerBlock,
MemoryPoolMaxTransactions: c.MemPoolSize,
ValidatorsCount: byte(c.ValidatorsCount),
InitialGasDistribution: c.InitialGASSupply,
CommitteeHistory: c.CommitteeHistory,
P2PSigExtensions: c.P2PSigExtensions,
StateRootInHeader: c.StateRootInHeader,
ValidatorsHistory: c.ValidatorsHistory,
},
}, nil
} }
func (l *localClient) InvokeContractVerify(contract util.Uint160, params []smartcontract.Parameter, signers []transaction.Signer, witnesses ...transaction.Witness) (*result.Invoke, error) { func (l *localClient) InvokeContractVerify(contract util.Uint160, params []smartcontract.Parameter, signers []transaction.Signer, witnesses ...transaction.Witness) (*result.Invoke, error) {
@ -327,7 +346,7 @@ func getSigners(sender *wallet.Account, cosigners []rpcclient.SignerAccount) ([]
} }
func (l *localClient) NEP17BalanceOf(h util.Uint160, acc util.Uint160) (int64, error) { func (l *localClient) NEP17BalanceOf(h util.Uint160, acc util.Uint160) (int64, error) {
res, err := invokeFunction(l, h, "balanceOf", []interface{}{acc}, nil) res, err := invokeFunction(l, h, "balanceOf", []any{acc}, nil)
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -432,7 +451,7 @@ func (l *localClient) putTransactions() error {
return l.bc.AddBlock(b) return l.bc.AddBlock(b)
} }
func invokeFunction(c Client, h util.Uint160, method string, parameters []interface{}, signers []transaction.Signer) (*result.Invoke, error) { func invokeFunction(c Client, h util.Uint160, method string, parameters []any, signers []transaction.Signer) (*result.Invoke, error) {
w := io.NewBufBinWriter() w := io.NewBufBinWriter()
emit.Array(w.BinWriter, parameters...) emit.Array(w.BinWriter, parameters...)
emit.AppCallNoArgs(w.BinWriter, h, method, callflag.All) emit.AppCallNoArgs(w.BinWriter, h, method, callflag.All)

View file

@ -0,0 +1,29 @@
package morph
import (
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
func listNetmapCandidatesNodes(cmd *cobra.Command, _ []string) {
c, err := getN3Client(viper.GetViper())
commonCmd.ExitOnErr(cmd, "can't create N3 client: %w", err)
inv := invoker.New(c, nil)
cs, err := c.GetContractStateByID(1)
commonCmd.ExitOnErr(cmd, "can't get NNS contract info: %w", err)
nmHash, err := nnsResolveHash(inv, cs.Hash, netmapContract+".frostfs")
commonCmd.ExitOnErr(cmd, "can't get netmap contract hash: %w", err)
res, err := inv.Call(nmHash, "netmapCandidates")
commonCmd.ExitOnErr(cmd, "can't fetch list of network config keys from the netmap contract", err)
nm, err := netmap.DecodeNetMap(res.Stack)
commonCmd.ExitOnErr(cmd, "unable to decode netmap: %w", err)
commonCmd.PrettyPrintNetMap(cmd, *nm, !viper.GetBool(commonflags.Verbose))
}

View file

@ -22,6 +22,7 @@ import (
// https://github.com/nspcc-dev/neo-go/blob/master/pkg/core/native/notary.go#L48 // https://github.com/nspcc-dev/neo-go/blob/master/pkg/core/native/notary.go#L48
const defaultNotaryDepositLifetime = 5760 const defaultNotaryDepositLifetime = 5760
// nolint: funlen
func depositNotary(cmd *cobra.Command, _ []string) error { func depositNotary(cmd *cobra.Command, _ []string) error {
p, err := cmd.Flags().GetString(storageWalletFlag) p, err := cmd.Flags().GetString(storageWalletFlag)
if err != nil { if err != nil {
@ -111,7 +112,7 @@ func depositNotary(cmd *cobra.Command, _ []string) error {
accHash, accHash,
notary.Hash, notary.Hash,
big.NewInt(int64(gasAmount)), big.NewInt(int64(gasAmount)),
[]interface{}{nil, int64(height) + till}, []any{nil, int64(height) + till},
) )
if err != nil { if err != nil {
return fmt.Errorf("could not send tx: %w", err) return fmt.Errorf("could not send tx: %w", err)

View file

@ -27,23 +27,23 @@ func setPolicyCmd(cmd *cobra.Command, args []string) error {
bw := io.NewBufBinWriter() bw := io.NewBufBinWriter()
for i := range args { for i := range args {
kv := strings.SplitN(args[i], "=", 2) k, v, found := strings.Cut(args[i], "=")
if len(kv) != 2 { if !found {
return fmt.Errorf("invalid parameter format, must be Parameter=Value") return fmt.Errorf("invalid parameter format, must be Parameter=Value")
} }
switch kv[0] { switch k {
case execFeeParam, storagePriceParam, setFeeParam: case execFeeParam, storagePriceParam, setFeeParam:
default: default:
return fmt.Errorf("parameter must be one of %s, %s and %s", execFeeParam, storagePriceParam, setFeeParam) return fmt.Errorf("parameter must be one of %s, %s and %s", execFeeParam, storagePriceParam, setFeeParam)
} }
value, err := strconv.ParseUint(kv[1], 10, 32) value, err := strconv.ParseUint(v, 10, 32)
if err != nil { if err != nil {
return fmt.Errorf("can't parse parameter value '%s': %w", args[1], err) return fmt.Errorf("can't parse parameter value '%s': %w", args[1], err)
} }
emit.AppCall(bw.BinWriter, policy.Hash, "set"+kv[0], callflag.All, int64(value)) emit.AppCall(bw.BinWriter, policy.Hash, "set"+k, callflag.All, int64(value))
} }
if err := wCtx.sendCommitteeTx(bw.Bytes(), false); err != nil { if err := wCtx.sendCommitteeTx(bw.Bytes(), false); err != nil {

View file

@ -4,7 +4,7 @@ import (
"errors" "errors"
"fmt" "fmt"
netmapcontract "github.com/TrueCloudLab/frostfs-contract/netmap" netmapcontract "git.frostfs.info/TrueCloudLab/frostfs-contract/netmap"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/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"

View file

@ -108,7 +108,7 @@ var (
forceNewEpoch = &cobra.Command{ forceNewEpoch = &cobra.Command{
Use: "force-new-epoch", Use: "force-new-epoch",
Short: "Create new NeoFS epoch event in the side chain", Short: "Create new FrostFS epoch event in the side chain",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
@ -130,7 +130,7 @@ var (
setConfig = &cobra.Command{ setConfig = &cobra.Command{
Use: "set-config key1=val1 [key2=val2 ...]", Use: "set-config key1=val1 [key2=val2 ...]",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: "Add/update global config value in the NeoFS network", Short: "Add/update global config value in the FrostFS network",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
@ -164,7 +164,7 @@ var (
dumpNetworkConfigCmd = &cobra.Command{ dumpNetworkConfigCmd = &cobra.Command{
Use: "dump-config", Use: "dump-config",
Short: "Dump NeoFS network config", Short: "Dump FrostFS network config",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
}, },
@ -182,7 +182,7 @@ var (
updateContractsCmd = &cobra.Command{ updateContractsCmd = &cobra.Command{
Use: "update-contracts", Use: "update-contracts",
Short: "Update NeoFS contracts", Short: "Update FrostFS contracts",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
@ -192,7 +192,7 @@ var (
dumpContainersCmd = &cobra.Command{ dumpContainersCmd = &cobra.Command{
Use: "dump-containers", Use: "dump-containers",
Short: "Dump NeoFS containers to file", Short: "Dump FrostFS containers to file",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
}, },
@ -201,7 +201,7 @@ var (
restoreContainersCmd = &cobra.Command{ restoreContainersCmd = &cobra.Command{
Use: "restore-containers", Use: "restore-containers",
Short: "Restore NeoFS containers from file", Short: "Restore FrostFS containers from file",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
@ -211,7 +211,7 @@ var (
listContainersCmd = &cobra.Command{ listContainersCmd = &cobra.Command{
Use: "list-containers", Use: "list-containers",
Short: "List NeoFS containers", Short: "List FrostFS containers",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
}, },
@ -226,8 +226,19 @@ var (
}, },
RunE: depositNotary, RunE: depositNotary,
} }
netmapCandidatesCmd = &cobra.Command{
Use: "netmap-candidates",
Short: "List netmap candidates nodes",
PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
},
Run: listNetmapCandidatesNodes,
}
) )
// nolint: funlen
func init() { func init() {
RootCmd.AddCommand(generateAlphabetCmd) RootCmd.AddCommand(generateAlphabetCmd)
generateAlphabetCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir") generateAlphabetCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
@ -236,8 +247,8 @@ func init() {
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")
initCmd.Flags().String(contractsInitFlag, "", "Path to archive with compiled NeoFS contracts (default fetched from latest github release)") initCmd.Flags().String(contractsInitFlag, "", "Path to archive with compiled FrostFS contracts (default fetched from latest github release)")
initCmd.Flags().Uint(epochDurationCLIFlag, 240, "Amount of side chain blocks in one NeoFS epoch") initCmd.Flags().Uint(epochDurationCLIFlag, 240, "Amount of side chain blocks in one FrostFS epoch")
initCmd.Flags().Uint(maxObjectSizeCLIFlag, 67108864, "Max single object size in bytes") initCmd.Flags().Uint(maxObjectSizeCLIFlag, 67108864, "Max single object size in bytes")
initCmd.Flags().Bool(homomorphicHashDisabledCLIFlag, false, "Disable object homomorphic hashing") initCmd.Flags().Bool(homomorphicHashDisabledCLIFlag, false, "Disable object homomorphic hashing")
// Defaults are taken from neo-preodolenie. // Defaults are taken from neo-preodolenie.
@ -289,7 +300,7 @@ func init() {
RootCmd.AddCommand(updateContractsCmd) RootCmd.AddCommand(updateContractsCmd)
updateContractsCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir") updateContractsCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
updateContractsCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint") updateContractsCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
updateContractsCmd.Flags().String(contractsInitFlag, "", "Path to archive with compiled NeoFS contracts (default fetched from latest github release)") updateContractsCmd.Flags().String(contractsInitFlag, "", "Path to archive with compiled FrostFS contracts (default fetched from latest github release)")
RootCmd.AddCommand(dumpContainersCmd) RootCmd.AddCommand(dumpContainersCmd)
dumpContainersCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint") dumpContainersCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
@ -323,4 +334,7 @@ func init() {
depositNotaryCmd.Flags().String(walletAccountFlag, "", "Wallet account address") depositNotaryCmd.Flags().String(walletAccountFlag, "", "Wallet account address")
depositNotaryCmd.Flags().String(refillGasAmountFlag, "", "Amount of GAS to deposit") depositNotaryCmd.Flags().String(refillGasAmountFlag, "", "Amount of GAS to deposit")
depositNotaryCmd.Flags().String(notaryDepositTillFlag, "", "Notary deposit duration in blocks") depositNotaryCmd.Flags().String(notaryDepositTillFlag, "", "Notary deposit duration in blocks")
RootCmd.AddCommand(netmapCandidatesCmd)
netmapCandidatesCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
} }

View file

@ -5,12 +5,12 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/internal" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/internal"
"github.com/TrueCloudLab/frostfs-node/pkg/morph/client" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
"github.com/TrueCloudLab/frostfs-node/pkg/util/rand" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/rand"
"github.com/TrueCloudLab/frostfs-sdk-go/subnet" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/subnet"
subnetid "github.com/TrueCloudLab/frostfs-sdk-go/subnet/id" subnetid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/subnet/id"
"github.com/TrueCloudLab/frostfs-sdk-go/user" "git.frostfs.info/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"
@ -39,7 +39,7 @@ func viperBindFlags(cmd *cobra.Command, flags ...string) {
// subnet command section. // subnet command section.
var cmdSubnet = &cobra.Command{ var cmdSubnet = &cobra.Command{
Use: "subnet", Use: "subnet",
Short: "NeoFS subnet management", Short: "FrostFS subnet management",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
viperBindFlags(cmd, viperBindFlags(cmd,
endpointFlag, endpointFlag,
@ -112,7 +112,7 @@ func readSubnetKey(key *keys.PrivateKey) error {
// create subnet command. // create subnet command.
var cmdSubnetCreate = &cobra.Command{ var cmdSubnetCreate = &cobra.Command{
Use: "create", Use: "create",
Short: "Create NeoFS subnet", Short: "Create FrostFS subnet",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
viperBindFlags(cmd, viperBindFlags(cmd,
flagSubnetWallet, flagSubnetWallet,
@ -177,7 +177,7 @@ var errZeroSubnet = errors.New("zero subnet")
// remove subnet command. // remove subnet command.
var cmdSubnetRemove = &cobra.Command{ var cmdSubnetRemove = &cobra.Command{
Use: "remove", Use: "remove",
Short: "Remove NeoFS subnet", Short: "Remove FrostFS subnet",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
viperBindFlags(cmd, viperBindFlags(cmd,
flagSubnetWallet, flagSubnetWallet,
@ -226,7 +226,7 @@ const (
// get subnet command. // get subnet command.
var cmdSubnetGet = &cobra.Command{ var cmdSubnetGet = &cobra.Command{
Use: "get", Use: "get",
Short: "Read information about the NeoFS subnet", Short: "Read information about the FrostFS subnet",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
viperBindFlags(cmd, viperBindFlags(cmd,
flagSubnetGetID, flagSubnetGetID,
@ -290,7 +290,7 @@ const (
// command to manage subnet admins. // command to manage subnet admins.
var cmdSubnetAdmin = &cobra.Command{ var cmdSubnetAdmin = &cobra.Command{
Use: "admin", Use: "admin",
Short: "Manage administrators of the NeoFS subnet", Short: "Manage administrators of the FrostFS subnet",
PreRun: func(cmd *cobra.Command, args []string) { PreRun: func(cmd *cobra.Command, args []string) {
viperBindFlags(cmd, viperBindFlags(cmd,
flagSubnetWallet, flagSubnetWallet,
@ -307,6 +307,8 @@ const (
) )
// common executor cmdSubnetAdminAdd and cmdSubnetAdminRemove commands. // common executor cmdSubnetAdminAdd and cmdSubnetAdminRemove commands.
//
// nolint: funlen
func manageSubnetAdmins(cmd *cobra.Command, rm bool) error { func manageSubnetAdmins(cmd *cobra.Command, rm bool) error {
// read private key // read private key
var key keys.PrivateKey var key keys.PrivateKey
@ -340,7 +342,7 @@ func manageSubnetAdmins(cmd *cobra.Command, rm bool) error {
} }
// prepare call parameters // prepare call parameters
prm := make([]interface{}, 0, 3) prm := make([]any, 0, 3)
prm = append(prm, id.Marshal()) prm = append(prm, id.Marshal())
var method string var method string
@ -397,7 +399,7 @@ func manageSubnetAdmins(cmd *cobra.Command, rm bool) error {
// command to add subnet admin. // command to add subnet admin.
var cmdSubnetAdminAdd = &cobra.Command{ var cmdSubnetAdminAdd = &cobra.Command{
Use: "add", Use: "add",
Short: "Add admin to the NeoFS subnet", Short: "Add admin to the FrostFS subnet",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
viperBindFlags(cmd, viperBindFlags(cmd,
flagSubnetAdminAddGroup, flagSubnetAdminAddGroup,
@ -412,7 +414,7 @@ var cmdSubnetAdminAdd = &cobra.Command{
// command to remove subnet admin. // command to remove subnet admin.
var cmdSubnetAdminRemove = &cobra.Command{ var cmdSubnetAdminRemove = &cobra.Command{
Use: "remove", Use: "remove",
Short: "Remove admin of the NeoFS subnet", Short: "Remove admin of the FrostFS subnet",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
viperBindFlags(cmd, viperBindFlags(cmd,
flagSubnetAdminClient, flagSubnetAdminClient,
@ -433,7 +435,7 @@ const (
// command to manage subnet clients. // command to manage subnet clients.
var cmdSubnetClient = &cobra.Command{ var cmdSubnetClient = &cobra.Command{
Use: "client", Use: "client",
Short: "Manage clients of the NeoFS subnet", Short: "Manage clients of the FrostFS subnet",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
viperBindFlags(cmd, viperBindFlags(cmd,
flagSubnetWallet, flagSubnetWallet,
@ -516,7 +518,7 @@ func manageSubnetClients(cmd *cobra.Command, rm bool) error {
// command to add subnet client. // command to add subnet client.
var cmdSubnetClientAdd = &cobra.Command{ var cmdSubnetClientAdd = &cobra.Command{
Use: "add", Use: "add",
Short: "Add client to the NeoFS subnet", Short: "Add client to the FrostFS subnet",
RunE: func(cmd *cobra.Command, _ []string) error { RunE: func(cmd *cobra.Command, _ []string) error {
return manageSubnetClients(cmd, false) return manageSubnetClients(cmd, false)
}, },
@ -525,7 +527,7 @@ var cmdSubnetClientAdd = &cobra.Command{
// command to remove subnet client. // command to remove subnet client.
var cmdSubnetClientRemove = &cobra.Command{ var cmdSubnetClientRemove = &cobra.Command{
Use: "remove", Use: "remove",
Short: "Remove client of the NeoFS subnet", Short: "Remove client of the FrostFS subnet",
RunE: func(cmd *cobra.Command, _ []string) error { RunE: func(cmd *cobra.Command, _ []string) error {
return manageSubnetClients(cmd, true) return manageSubnetClients(cmd, true)
}, },
@ -598,7 +600,7 @@ func manageSubnetNodes(cmd *cobra.Command, rm bool) error {
// command to manage subnet nodes. // command to manage subnet nodes.
var cmdSubnetNode = &cobra.Command{ var cmdSubnetNode = &cobra.Command{
Use: "node", Use: "node",
Short: "Manage nodes of the NeoFS subnet", Short: "Manage nodes of the FrostFS subnet",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
viperBindFlags(cmd, viperBindFlags(cmd,
flagSubnetWallet, flagSubnetWallet,
@ -611,7 +613,7 @@ var cmdSubnetNode = &cobra.Command{
// command to add subnet node. // command to add subnet node.
var cmdSubnetNodeAdd = &cobra.Command{ var cmdSubnetNodeAdd = &cobra.Command{
Use: "add", Use: "add",
Short: "Add node to the NeoFS subnet", Short: "Add node to the FrostFS subnet",
RunE: func(cmd *cobra.Command, _ []string) error { RunE: func(cmd *cobra.Command, _ []string) error {
return manageSubnetNodes(cmd, false) return manageSubnetNodes(cmd, false)
}, },
@ -620,7 +622,7 @@ var cmdSubnetNodeAdd = &cobra.Command{
// command to remove subnet node. // command to remove subnet node.
var cmdSubnetNodeRemove = &cobra.Command{ var cmdSubnetNodeRemove = &cobra.Command{
Use: "remove", Use: "remove",
Short: "Remove node from the NeoFS subnet", Short: "Remove node from the FrostFS subnet",
RunE: func(cmd *cobra.Command, _ []string) error { RunE: func(cmd *cobra.Command, _ []string) error {
return manageSubnetNodes(cmd, true) return manageSubnetNodes(cmd, true)
}, },
@ -651,6 +653,8 @@ 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.
//
// nolint: funlen
func init() { func init() {
cmdSubnetCreate.Flags().StringP(flagSubnetWallet, "w", "", "Path to file with wallet") cmdSubnetCreate.Flags().StringP(flagSubnetWallet, "w", "", "Path to file with wallet")
_ = cmdSubnetCreate.MarkFlagRequired(flagSubnetWallet) _ = cmdSubnetCreate.MarkFlagRequired(flagSubnetWallet)
@ -693,7 +697,7 @@ func init() {
_ = cmdSubnetClient.MarkFlagRequired(flagSubnetClientSubnet) _ = cmdSubnetClient.MarkFlagRequired(flagSubnetClientSubnet)
clientFlags.String(flagSubnetClientGroup, "", "ID of the client group to work with") clientFlags.String(flagSubnetClientGroup, "", "ID of the client group to work with")
_ = cmdSubnetClient.MarkFlagRequired(flagSubnetClientGroup) _ = cmdSubnetClient.MarkFlagRequired(flagSubnetClientGroup)
clientFlags.String(flagSubnetClientID, "", "Client's user ID in NeoFS system in text format") clientFlags.String(flagSubnetClientID, "", "Client's user ID in FrostFS system in text format")
_ = cmdSubnetClient.MarkFlagRequired(flagSubnetClientID) _ = cmdSubnetClient.MarkFlagRequired(flagSubnetClientID)
clientFlags.StringP(flagSubnetWallet, "w", "", "Path to file with wallet") clientFlags.StringP(flagSubnetWallet, "w", "", "Path to file with wallet")
_ = cmdSubnetClient.MarkFlagRequired(flagSubnetWallet) _ = cmdSubnetClient.MarkFlagRequired(flagSubnetWallet)
@ -742,7 +746,7 @@ func init() {
) )
} }
func testInvokeMethod(key keys.PrivateKey, method string, args ...interface{}) ([]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 {
return nil, fmt.Errorf("morph client creation: %w", err) return nil, fmt.Errorf("morph client creation: %w", err)
@ -780,7 +784,7 @@ func testInvokeMethod(key keys.PrivateKey, method string, args ...interface{}) (
return res.Stack, nil return res.Stack, nil
} }
func invokeMethod(key keys.PrivateKey, tryNotary bool, method string, args ...interface{}) error { func invokeMethod(key keys.PrivateKey, tryNotary bool, method string, args ...any) error {
c, err := getN3Client(viper.GetViper()) c, err := getN3Client(viper.GetViper())
if err != nil { if err != nil {
return fmt.Errorf("morph client creation: %w", err) return fmt.Errorf("morph client creation: %w", err)
@ -821,7 +825,7 @@ func invokeMethod(key keys.PrivateKey, tryNotary bool, method string, args ...in
return nil return nil
} }
func invokeNonNotary(c Client, key keys.PrivateKey, method string, args ...interface{}) error { func invokeNonNotary(c Client, key keys.PrivateKey, method string, args ...any) error {
nnsCs, err := c.GetContractStateByID(1) nnsCs, err := c.GetContractStateByID(1)
if err != nil { if err != nil {
return fmt.Errorf("NNS contract resolving: %w", err) return fmt.Errorf("NNS contract resolving: %w", err)
@ -868,7 +872,8 @@ func invokeNonNotary(c Client, key keys.PrivateKey, method string, args ...inter
return nil return nil
} }
func invokeNotary(c Client, key keys.PrivateKey, method string, notaryHash util.Uint160, args ...interface{}) error { // nolint: funlen
func invokeNotary(c Client, key keys.PrivateKey, method string, notaryHash util.Uint160, args ...any) error {
nnsCs, err := c.GetContractStateByID(1) nnsCs, err := c.GetContractStateByID(1)
if err != nil { if err != nil {
return fmt.Errorf("NNS contract resolving: %w", err) return fmt.Errorf("NNS contract resolving: %w", err)

View file

@ -3,12 +3,14 @@ package modules
import ( import (
"os" "os"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/storagecfg" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph"
"github.com/TrueCloudLab/frostfs-node/misc" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/storagecfg"
"github.com/TrueCloudLab/frostfs-node/pkg/util/autocomplete" "git.frostfs.info/TrueCloudLab/frostfs-node/misc"
"github.com/TrueCloudLab/frostfs-node/pkg/util/gendoc" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/autocomplete"
utilConfig "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/config"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/gendoc"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@ -16,14 +18,12 @@ import (
var ( var (
rootCmd = &cobra.Command{ rootCmd = &cobra.Command{
Use: "frostfs-adm", Use: "frostfs-adm",
Short: "NeoFS Administrative Tool", Short: "FrostFS Administrative Tool",
Long: `NeoFS Administrative Tool provides functions to setup and Long: `FrostFS Administrative Tool provides functions to setup and
manage NeoFS network deployment.`, manage FrostFS network deployment.`,
RunE: entryPoint, RunE: entryPoint,
SilenceUsage: true, SilenceUsage: true,
} }
configFlag = "config"
) )
func init() { func init() {
@ -34,7 +34,10 @@ func init() {
// use stdout as default output for cmd.Print() // use stdout as default output for cmd.Print()
rootCmd.SetOut(os.Stdout) rootCmd.SetOut(os.Stdout)
rootCmd.PersistentFlags().StringP(configFlag, "c", "", "Config file") rootCmd.PersistentFlags().StringP(commonflags.ConfigFlag, commonflags.ConfigFlagShorthand, "", commonflags.ConfigFlagUsage)
rootCmd.PersistentFlags().String(commonflags.ConfigDirFlag, "", commonflags.ConfigDirFlagUsage)
rootCmd.PersistentFlags().BoolP(commonflags.Verbose, commonflags.VerboseShorthand, false, commonflags.VerboseUsage)
_ = viper.BindPFlag(commonflags.Verbose, rootCmd.PersistentFlags().Lookup(commonflags.Verbose))
rootCmd.Flags().Bool("version", false, "Application version") rootCmd.Flags().Bool("version", false, "Application version")
rootCmd.AddCommand(config.RootCmd) rootCmd.AddCommand(config.RootCmd)
@ -52,7 +55,7 @@ func Execute() error {
func entryPoint(cmd *cobra.Command, args []string) error { func entryPoint(cmd *cobra.Command, args []string) error {
printVersion, _ := cmd.Flags().GetBool("version") printVersion, _ := cmd.Flags().GetBool("version")
if printVersion { if printVersion {
cmd.Print(misc.BuildInfo("NeoFS Adm")) cmd.Print(misc.BuildInfo("FrostFS Adm"))
return nil return nil
} }
@ -60,12 +63,23 @@ func entryPoint(cmd *cobra.Command, args []string) error {
} }
func initConfig(cmd *cobra.Command) { func initConfig(cmd *cobra.Command) {
configFile, err := cmd.Flags().GetString(configFlag) configFile, err := cmd.Flags().GetString(commonflags.ConfigFlag)
if err != nil || configFile == "" { if err != nil {
return return
} }
viper.SetConfigType("yml") if configFile != "" {
viper.SetConfigFile(configFile) viper.SetConfigType("yml")
_ = viper.ReadInConfig() // if config file is set but unavailable, ignore it viper.SetConfigFile(configFile)
_ = viper.ReadInConfig() // if config file is set but unavailable, ignore it
}
configDir, err := cmd.Flags().GetString(commonflags.ConfigDirFlag)
if err != nil {
return
}
if configDir != "" {
_ = utilConfig.ReadConfigDir(viper.GetViper(), configDir) // if config files cannot be read, ignore it
}
} }

View file

@ -14,7 +14,7 @@ node:
relay: {{ .Relay }} # start Storage node in relay mode without bootstrapping into the Network map relay: {{ .Relay }} # start Storage node in relay mode without bootstrapping into the Network map
subnet: subnet:
exit_zero: false # toggle entrance to zero subnet (overrides corresponding attribute and occurrence in entries) exit_zero: false # toggle entrance to zero subnet (overrides corresponding attribute and occurrence in entries)
entries: [] # list of IDs of subnets to enter in a text format of NeoFS API protocol (overrides corresponding attributes) entries: [] # list of IDs of subnets to enter in a text format of FrostFS API protocol (overrides corresponding attributes)
grpc: grpc:
num: 1 # total number of listener endpoints num: 1 # total number of listener endpoints

View file

@ -16,7 +16,7 @@ import (
"text/template" "text/template"
"time" "time"
netutil "github.com/TrueCloudLab/frostfs-node/pkg/network" netutil "git.frostfs.info/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"
@ -79,6 +79,7 @@ type config struct {
MetabasePath string MetabasePath string
} }
// nolint: funlen
func storageConfig(cmd *cobra.Command, args []string) { func storageConfig(cmd *cobra.Command, args []string) {
var outPath string var outPath string
if len(args) != 0 { if len(args) != 0 {
@ -153,7 +154,7 @@ func storageConfig(cmd *cobra.Command, args []string) {
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://github.com/TrueCloudLab/frostfs-node/blob/master/pkg/network/address.go for details.") cmd.Println("Incorrect address format. See https://git.frostfs.info/TrueCloudLab/frostfs-node/src/branch/master/pkg/network/address.go for details.")
continue continue
} }
uriAddr, err := url.Parse(validator.URIAddr()) uriAddr, err := url.Parse(validator.URIAddr())

View file

@ -3,7 +3,7 @@ package main
import ( import (
"os" "os"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules"
) )
func main() { func main() {

View file

@ -1,8 +1,8 @@
# How NeoFS CLI uses session mechanism of the NeoFS # How FrostFS CLI uses session mechanism of the FrostFS
## Overview ## Overview
NeoFS sessions implement a mechanism for issuing a power of attorney by one FrostFS sessions implement a mechanism for issuing a power of attorney by one
party to another. A trusted party can provide a so-called session token as party to another. A trusted party can provide a so-called session token as
proof of the right to act on behalf of another member of the network. The proof of the right to act on behalf of another member of the network. The
client of operations carried out with such a token will be the user who opened client of operations carried out with such a token will be the user who opened
@ -15,7 +15,7 @@ attached session token is treated as performed by the original client.
## Types ## Types
NeoFS CLI supports two ways to execute operation within a session depending on FrostFS CLI supports two ways to execute operation within a session depending on
whether the user of the command application is an original user (1) or a trusted whether the user of the command application is an original user (1) or a trusted
one (2). one (2).

View file

@ -2,26 +2,26 @@
## Overview ## Overview
Extended headers are used for request/response. They may contain any user-defined headers Extended headers are used for request/response. They may contain any
to be interpreted on application level. user-defined headers to be interpreted on application level. Key name must be a
Key name must be a unique valid UTF-8 string. Value can't be empty. Requests or unique valid UTF-8 string. Value can't be empty. Requests or Responses with
Responses with duplicated header names or headers with empty values are duplicated header names or headers with empty values are considered invalid.
considered invalid.
## Existing headers ## Existing headers
There are some "well-known" headers starting with `__NEOFS__` prefix that There are some "well-known" headers starting with `__FROSTFS__` prefix that
affect system behaviour: affect system behaviour. For backward compatibility, the same set of
"well-known" headers may also use `__NEOFS__` prefix:
* `__NEOFS__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.
* `__NEOFS__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 `__NEOFS__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.
## `neofs-cli` commands with `--xhdr` ## `frostfs-cli` commands with `--xhdr`
List of commands with support of extended headers: List of commands with support of extended headers:
* `container list-objects` * `container list-objects`
@ -30,5 +30,5 @@ List of commands with support of extended headers:
Example: Example:
```shell ```shell
$ neofs-cli object put -r s01.neofs.devenv:8080 -w wallet.json --cid CID --file FILE --xhdr "__NEOFS__NETMAP_EPOCH=777" $ frostfs-cli object put -r s01.frostfs.devenv:8080 -w wallet.json --cid CID --file FILE --xhdr "__FROSTFS__NETMAP_EPOCH=777"
``` ```

View file

@ -7,15 +7,15 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/TrueCloudLab/frostfs-sdk-go/accounting" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/accounting"
"github.com/TrueCloudLab/frostfs-sdk-go/client" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
containerSDK "github.com/TrueCloudLab/frostfs-sdk-go/container" containerSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
"github.com/TrueCloudLab/frostfs-sdk-go/eacl" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
"github.com/TrueCloudLab/frostfs-sdk-go/netmap" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
"github.com/TrueCloudLab/frostfs-sdk-go/object" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id" oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
"github.com/TrueCloudLab/frostfs-sdk-go/version" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version"
) )
// BalanceOfPrm groups parameters of BalanceOf operation. // BalanceOfPrm groups parameters of BalanceOf operation.
@ -34,7 +34,7 @@ func (x BalanceOfRes) Balance() accounting.Decimal {
return x.cliRes.Amount() return x.cliRes.Amount()
} }
// BalanceOf requests the current balance of a NeoFS user. // BalanceOf requests the current balance of a FrostFS user.
// //
// Returns any error which prevented the operation from completing correctly in error return. // Returns any error which prevented the operation from completing correctly in error return.
func BalanceOf(prm BalanceOfPrm) (res BalanceOfRes, err error) { func BalanceOf(prm BalanceOfPrm) (res BalanceOfRes, err error) {
@ -59,7 +59,7 @@ func (x ListContainersRes) IDList() []cid.ID {
return x.cliRes.Containers() return x.cliRes.Containers()
} }
// ListContainers requests a list of NeoFS user's containers. // ListContainers requests a list of FrostFS user's containers.
// //
// Returns any error which prevented the operation from completing correctly in error return. // Returns any error which prevented the operation from completing correctly in error return.
func ListContainers(prm ListContainersPrm) (res ListContainersRes, err error) { func ListContainers(prm ListContainersPrm) (res ListContainersRes, err error) {
@ -84,7 +84,7 @@ func (x PutContainerRes) ID() cid.ID {
return x.cnr return x.cnr
} }
// PutContainer sends a request to save the container in NeoFS. // PutContainer sends a request to save the container in FrostFS.
// //
// Operation is asynchronous and not guaranteed even in the absence of errors. // Operation is asynchronous and not guaranteed even in the absence of errors.
// The required time is also not predictable. // The required time is also not predictable.
@ -122,7 +122,7 @@ func (x GetContainerRes) Container() containerSDK.Container {
return x.cliRes.Container() return x.cliRes.Container()
} }
// GetContainer reads a container from NeoFS by ID. // GetContainer reads a container from FrostFS by ID.
// //
// Returns any error which prevented the operation from completing correctly in error return. // Returns any error which prevented the operation from completing correctly in error return.
func GetContainer(prm GetContainerPrm) (res GetContainerRes, err error) { func GetContainer(prm GetContainerPrm) (res GetContainerRes, err error) {
@ -140,7 +140,7 @@ func IsACLExtendable(c *client.Client, cnr cid.ID) (bool, error) {
res, err := GetContainer(prm) res, err := GetContainer(prm)
if err != nil { if err != nil {
return false, fmt.Errorf("get container from the NeoFS: %w", err) return false, fmt.Errorf("get container from the FrostFS: %w", err)
} }
return res.Container().BasicACL().Extendable(), nil return res.Container().BasicACL().Extendable(), nil
@ -155,7 +155,7 @@ type DeleteContainerPrm struct {
// DeleteContainerRes groups the resulting values of DeleteContainer operation. // DeleteContainerRes groups the resulting values of DeleteContainer operation.
type DeleteContainerRes struct{} type DeleteContainerRes struct{}
// DeleteContainer sends a request to remove a container from NeoFS by ID. // DeleteContainer sends a request to remove a container from FrostFS by ID.
// //
// Operation is asynchronous and not guaranteed even in the absence of errors. // Operation is asynchronous and not guaranteed even in the absence of errors.
// The required time is also not predictable. // The required time is also not predictable.
@ -185,7 +185,7 @@ func (x EACLRes) EACL() eacl.Table {
return x.cliRes.Table() return x.cliRes.Table()
} }
// EACL reads eACL table from NeoFS by container ID. // EACL reads eACL table from FrostFS by container ID.
// //
// Returns any error which prevented the operation from completing correctly in error return. // Returns any error which prevented the operation from completing correctly in error return.
func EACL(prm EACLPrm) (res EACLRes, err error) { func EACL(prm EACLPrm) (res EACLRes, err error) {
@ -203,7 +203,7 @@ type SetEACLPrm struct {
// SetEACLRes groups the resulting values of SetEACL operation. // SetEACLRes groups the resulting values of SetEACL operation.
type SetEACLRes struct{} type SetEACLRes struct{}
// SetEACL requests to save an eACL table in NeoFS. // SetEACL requests to save an eACL table in FrostFS.
// //
// Operation is asynchronous and no guaranteed even in the absence of errors. // Operation is asynchronous and no guaranteed even in the absence of errors.
// The required time is also not predictable. // The required time is also not predictable.
@ -228,12 +228,12 @@ type NetworkInfoRes struct {
cliRes *client.ResNetworkInfo cliRes *client.ResNetworkInfo
} }
// NetworkInfo returns structured information about the NeoFS network. // NetworkInfo returns structured information about the FrostFS network.
func (x NetworkInfoRes) NetworkInfo() netmap.NetworkInfo { func (x NetworkInfoRes) NetworkInfo() netmap.NetworkInfo {
return x.cliRes.Info() return x.cliRes.Info()
} }
// NetworkInfo reads information about the NeoFS network. // NetworkInfo reads information about the FrostFS network.
// //
// Returns any error which prevented the operation from completing correctly in error return. // Returns any error which prevented the operation from completing correctly in error return.
func NetworkInfo(prm NetworkInfoPrm) (res NetworkInfoRes, err error) { func NetworkInfo(prm NetworkInfoPrm) (res NetworkInfoRes, err error) {
@ -258,12 +258,12 @@ func (x NodeInfoRes) NodeInfo() netmap.NodeInfo {
return x.cliRes.NodeInfo() return x.cliRes.NodeInfo()
} }
// LatestVersion returns the latest NeoFS API version in use. // LatestVersion returns the latest FrostFS API version in use.
func (x NodeInfoRes) LatestVersion() version.Version { func (x NodeInfoRes) LatestVersion() version.Version {
return x.cliRes.LatestVersion() return x.cliRes.LatestVersion()
} }
// NodeInfo requests information about the remote server from NeoFS netmap. // NodeInfo requests information about the remote server from FrostFS netmap.
// //
// Returns any error which prevented the operation from completing correctly in error return. // Returns any error which prevented the operation from completing correctly in error return.
func NodeInfo(prm NodeInfoPrm) (res NodeInfoRes, err error) { func NodeInfo(prm NodeInfoPrm) (res NodeInfoRes, err error) {
@ -282,7 +282,7 @@ type NetMapSnapshotRes struct {
cliRes *client.ResNetMapSnapshot cliRes *client.ResNetMapSnapshot
} }
// NetMap returns current local snapshot of the NeoFS network map. // NetMap returns current local snapshot of the FrostFS network map.
func (x NetMapSnapshotRes) NetMap() netmap.NetMap { func (x NetMapSnapshotRes) NetMap() netmap.NetMap {
return x.cliRes.NetMap() return x.cliRes.NetMap()
} }
@ -362,7 +362,7 @@ func (x PutObjectRes) ID() oid.ID {
return x.id return x.id
} }
// PutObject saves the object in NeoFS network. // PutObject saves the object in FrostFS network.
// //
// Returns any error which prevented the operation from completing correctly in error return. // Returns any error which prevented the operation from completing correctly in error return.
func PutObject(prm PutObjectPrm) (*PutObjectRes, error) { func PutObject(prm PutObjectPrm) (*PutObjectRes, error) {
@ -404,8 +404,7 @@ func PutObject(prm PutObjectPrm) (*PutObjectRes, error) {
} }
if prm.rdr != nil { if prm.rdr != nil {
// TODO: (neofs-node#1198) explore better values or configure it const defaultBufferSizePut = 3 << 20 // Maximum chunk size is 3 MiB in the SDK.
const defaultBufferSizePut = 4096
if sz == 0 || sz > defaultBufferSizePut { if sz == 0 || sz > defaultBufferSizePut {
sz = defaultBufferSizePut sz = defaultBufferSizePut
@ -460,7 +459,7 @@ func (x DeleteObjectRes) Tombstone() oid.ID {
return x.tomb return x.tomb
} }
// DeleteObject marks an object to be removed from NeoFS through tombstone placement. // DeleteObject marks an object to be removed from FrostFS through tombstone placement.
// //
// Returns any error which prevented the operation from completing correctly in error return. // Returns any error which prevented the operation from completing correctly in error return.
func DeleteObject(prm DeleteObjectPrm) (*DeleteObjectRes, error) { func DeleteObject(prm DeleteObjectPrm) (*DeleteObjectRes, error) {
@ -576,7 +575,7 @@ type HeadObjectPrm struct {
mainOnly bool mainOnly bool
} }
// SetMainOnlyFlag sets flag to get only main fields of an object header in terms of NeoFS API. // SetMainOnlyFlag sets flag to get only main fields of an object header in terms of FrostFS API.
func (x *HeadObjectPrm) SetMainOnlyFlag(v bool) { func (x *HeadObjectPrm) SetMainOnlyFlag(v bool) {
x.mainOnly = v x.mainOnly = v
} }
@ -812,7 +811,7 @@ func (x *PayloadRangePrm) SetRange(rng *object.Range) {
// PayloadRangeRes groups the resulting values of PayloadRange operation. // PayloadRangeRes groups the resulting values of PayloadRange operation.
type PayloadRangeRes struct{} type PayloadRangeRes struct{}
// PayloadRange reads object payload range from NeoFS and writes it to the specified writer. // PayloadRange reads object payload range from FrostFS and writes it to the specified writer.
// //
// Interrupts on any writer error. // Interrupts on any writer error.
// //
@ -872,7 +871,7 @@ func (s *SyncContainerPrm) SetContainer(c *containerSDK.Container) {
// operation. // operation.
type SyncContainerRes struct{} type SyncContainerRes struct{}
// SyncContainerSettings reads global network config from NeoFS and // SyncContainerSettings reads global network config from FrostFS and
// syncs container settings with it. // syncs container settings with it.
// //
// Interrupts on any writer error. // Interrupts on any writer error.

View file

@ -1,12 +1,15 @@
// Package internal provides functionality for NeoFS CLI application communication with NeoFS network. // Package internal provides functionality for FrostFS CLI application
// communication with FrostFS network.
// //
// The base client for accessing remote nodes via NeoFS API is a NeoFS SDK Go API client. // The base client for accessing remote nodes via FrostFS API is a FrostFS SDK
// However, although it encapsulates a useful piece of business logic (e.g. the signature mechanism), // Go API client. However, although it encapsulates a useful piece of business
// the NeoFS CLI application does not fully use the client's flexible interface. // logic (e.g. the signature mechanism), the FrostFS CLI application does not
// fully use the client's flexible interface.
// //
// In this regard, this package provides functions over base API client necessary for the application. // In this regard, this package provides functions over base API client
// This allows you to concentrate the entire spectrum of the client's use in one place (this will be convenient // necessary for the application. This allows you to concentrate the entire
// both when updating the base client and for evaluating the UX of SDK library). So it is expected that all // spectrum of the client's use in one place (this will be convenient both when
// application packages will be limited to this package for the development of functionality requiring // updating the base client and for evaluating the UX of SDK library). So it is
// NeoFS API communication. // expected that all application packages will be limited to this package for
// the development of functionality requiring FrostFS API communication.
package internal package internal

View file

@ -3,11 +3,11 @@ package internal
import ( import (
"io" "io"
"github.com/TrueCloudLab/frostfs-sdk-go/bearer" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
"github.com/TrueCloudLab/frostfs-sdk-go/client" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id" oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
"github.com/TrueCloudLab/frostfs-sdk-go/session" "git.frostfs.info/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
@ -16,7 +16,7 @@ type commonPrm struct {
cli *client.Client cli *client.Client
} }
// SetClient sets the base client for NeoFS API communication. // SetClient sets the base client for FrostFS API communication.
func (x *commonPrm) SetClient(cli *client.Client) { func (x *commonPrm) SetClient(cli *client.Client) {
x.cli = cli x.cli = cli
} }

View file

@ -8,10 +8,11 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
"github.com/TrueCloudLab/frostfs-node/pkg/network" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"github.com/TrueCloudLab/frostfs-sdk-go/client" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/network"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@ -23,7 +24,7 @@ var errInvalidEndpoint = errors.New("provided RPC endpoint is incorrect")
func GetSDKClientByFlag(cmd *cobra.Command, key *ecdsa.PrivateKey, endpointFlag string) *client.Client { func GetSDKClientByFlag(cmd *cobra.Command, key *ecdsa.PrivateKey, endpointFlag string) *client.Client {
cli, err := getSDKClientByFlag(cmd, key, endpointFlag) cli, err := getSDKClientByFlag(cmd, key, endpointFlag)
if err != nil { if err != nil {
common.ExitOnErr(cmd, "can't create API client: %w", err) commonCmd.ExitOnErr(cmd, "can't create API client: %w", err)
} }
return cli return cli
} }
@ -47,7 +48,7 @@ func GetSDKClient(cmd *cobra.Command, key *ecdsa.PrivateKey, addr network.Addres
) )
prmInit.SetDefaultPrivateKey(*key) prmInit.SetDefaultPrivateKey(*key)
prmInit.ResolveNeoFSFailures() prmInit.ResolveFrostFSFailures()
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.

View file

@ -4,9 +4,10 @@ import (
"errors" "errors"
"os" "os"
"github.com/TrueCloudLab/frostfs-node/pkg/core/version" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"github.com/TrueCloudLab/frostfs-sdk-go/eacl" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/version"
versionSDK "github.com/TrueCloudLab/frostfs-sdk-go/version" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
versionSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -16,13 +17,13 @@ var errUnsupportedEACLFormat = errors.New("unsupported eACL format")
func ReadEACL(cmd *cobra.Command, eaclPath string) *eacl.Table { func ReadEACL(cmd *cobra.Command, eaclPath string) *eacl.Table {
_, err := os.Stat(eaclPath) // check if `eaclPath` is an existing file _, err := os.Stat(eaclPath) // check if `eaclPath` is an existing file
if err != nil { if err != nil {
ExitOnErr(cmd, "", errors.New("incorrect path to file with EACL")) commonCmd.ExitOnErr(cmd, "", errors.New("incorrect path to file with EACL"))
} }
PrintVerbose(cmd, "Reading EACL from file: %s", eaclPath) PrintVerbose(cmd, "Reading EACL from file: %s", eaclPath)
data, err := os.ReadFile(eaclPath) data, err := os.ReadFile(eaclPath)
ExitOnErr(cmd, "can't read file with EACL: %w", err) commonCmd.ExitOnErr(cmd, "can't read file with EACL: %w", err)
table := eacl.NewTable() table := eacl.NewTable()
@ -38,7 +39,7 @@ func ReadEACL(cmd *cobra.Command, eaclPath string) *eacl.Table {
return table return table
} }
ExitOnErr(cmd, "", errUnsupportedEACLFormat) commonCmd.ExitOnErr(cmd, "", errUnsupportedEACLFormat)
return nil return nil
} }

View file

@ -6,14 +6,15 @@ import (
"fmt" "fmt"
"os" "os"
"github.com/TrueCloudLab/frostfs-sdk-go/bearer" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
// ReadBearerToken reads bearer token from the path provided in a specified flag. // ReadBearerToken reads bearer token from the path provided in a specified flag.
func ReadBearerToken(cmd *cobra.Command, flagname string) *bearer.Token { func ReadBearerToken(cmd *cobra.Command, flagname string) *bearer.Token {
path, err := cmd.Flags().GetString(flagname) path, err := cmd.Flags().GetString(flagname)
ExitOnErr(cmd, "", err) commonCmd.ExitOnErr(cmd, "", err)
if len(path) == 0 { if len(path) == 0 {
return nil return nil
@ -24,13 +25,13 @@ func ReadBearerToken(cmd *cobra.Command, flagname string) *bearer.Token {
var tok bearer.Token var tok bearer.Token
err = ReadBinaryOrJSON(cmd, &tok, path) err = ReadBinaryOrJSON(cmd, &tok, path)
ExitOnErr(cmd, "invalid bearer token: %v", err) commonCmd.ExitOnErr(cmd, "invalid bearer token: %v", err)
return &tok return &tok
} }
// BinaryOrJSON is an interface of entities which provide json.Unmarshaler // BinaryOrJSON is an interface of entities which provide json.Unmarshaler
// and NeoFS binary decoder. // and FrostFS binary decoder.
type BinaryOrJSON interface { type BinaryOrJSON interface {
Unmarshal([]byte) error Unmarshal([]byte) error
json.Unmarshaler json.Unmarshaler

View file

@ -5,14 +5,14 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
"github.com/TrueCloudLab/frostfs-sdk-go/checksum" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/checksum"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
// PrintVerbose prints to the stdout if the commonflags.Verbose flag is on. // PrintVerbose prints to the stdout if the commonflags.Verbose flag is on.
func PrintVerbose(cmd *cobra.Command, format string, a ...interface{}) { func PrintVerbose(cmd *cobra.Command, format string, a ...any) {
if viper.GetBool(commonflags.Verbose) { if viper.GetBool(commonflags.Verbose) {
cmd.Printf(format+"\n", a...) cmd.Printf(format+"\n", a...)
} }

View file

@ -8,8 +8,8 @@ import (
const SessionToken = "session" const SessionToken = "session"
// InitSession registers SessionToken flag representing filepath to the token // InitSession registers SessionToken flag representing file path to the token of
// of the session with the given name. Supports NeoFS-binary and JSON files. // the session with the given name. Supports FrostFS-binary and JSON files.
func InitSession(cmd *cobra.Command, name string) { func InitSession(cmd *cobra.Command, name string) {
cmd.Flags().String( cmd.Flags().String(
SessionToken, SessionToken,

View file

@ -7,7 +7,7 @@ import (
"path/filepath" "path/filepath"
"testing" "testing"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
"github.com/nspcc-dev/neo-go/cli/input" "github.com/nspcc-dev/neo-go/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"

View file

@ -6,8 +6,8 @@ import (
"fmt" "fmt"
"os" "os"
"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"
"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"
@ -21,7 +21,7 @@ var errCantGenerateKey = errors.New("can't generate new private key")
// This function assumes that all flags were bind to viper in a `PersistentPreRun`. // This function assumes that all flags were bind to viper in a `PersistentPreRun`.
func Get(cmd *cobra.Command) *ecdsa.PrivateKey { func Get(cmd *cobra.Command) *ecdsa.PrivateKey {
pk, err := get(cmd) pk, err := get(cmd)
common.ExitOnErr(cmd, "can't fetch private key: %w", err) commonCmd.ExitOnErr(cmd, "can't fetch private key: %w", err)
return pk return pk
} }
@ -46,7 +46,7 @@ func get(cmd *cobra.Command) (*ecdsa.PrivateKey, error) {
// GetOrGenerate is similar to get but generates a new key if commonflags.GenerateKey is set. // GetOrGenerate is similar to get but generates a new key if commonflags.GenerateKey is set.
func GetOrGenerate(cmd *cobra.Command) *ecdsa.PrivateKey { func GetOrGenerate(cmd *cobra.Command) *ecdsa.PrivateKey {
pk, err := getOrGenerate(cmd) pk, err := getOrGenerate(cmd)
common.ExitOnErr(cmd, "can't fetch private key: %w", err) commonCmd.ExitOnErr(cmd, "can't fetch private key: %w", err)
return pk return pk
} }

View file

@ -4,7 +4,7 @@ import (
"crypto/ecdsa" "crypto/ecdsa"
"errors" "errors"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
"github.com/nspcc-dev/neo-go/cli/flags" "github.com/nspcc-dev/neo-go/cli/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"

View file

@ -1,6 +1,6 @@
package main package main
import cmd "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules" import cmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules"
func main() { func main() {
cmd.Execute() cmd.Execute()

View file

@ -3,13 +3,13 @@ package accounting
import ( import (
"math/big" "math/big"
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
"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"
"github.com/TrueCloudLab/frostfs-node/pkg/util/precision" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/precision"
"github.com/TrueCloudLab/frostfs-sdk-go/accounting" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/accounting"
"github.com/TrueCloudLab/frostfs-sdk-go/user" "git.frostfs.info/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"
@ -21,8 +21,8 @@ const (
var accountingBalanceCmd = &cobra.Command{ var accountingBalanceCmd = &cobra.Command{
Use: "balance", Use: "balance",
Short: "Get internal balance of NeoFS account", Short: "Get internal balance of FrostFS account",
Long: `Get internal balance of NeoFS account`, Long: `Get internal balance of FrostFS account`,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
var idUser user.ID var idUser user.ID
@ -32,7 +32,7 @@ var accountingBalanceCmd = &cobra.Command{
if balanceOwner == "" { if balanceOwner == "" {
user.IDFromKey(&idUser, pk.PublicKey) user.IDFromKey(&idUser, pk.PublicKey)
} else { } else {
common.ExitOnErr(cmd, "can't decode owner ID wallet address: %w", idUser.DecodeString(balanceOwner)) commonCmd.ExitOnErr(cmd, "can't decode owner ID wallet address: %w", idUser.DecodeString(balanceOwner))
} }
cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC) cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC)
@ -42,7 +42,7 @@ var accountingBalanceCmd = &cobra.Command{
prm.SetAccount(idUser) prm.SetAccount(idUser)
res, err := internalclient.BalanceOf(prm) res, err := internalclient.BalanceOf(prm)
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
// print to stdout // print to stdout
prettyPrintDecimal(cmd, res.Balance()) prettyPrintDecimal(cmd, res.Balance())

View file

@ -1,7 +1,7 @@
package accounting package accounting
import ( import (
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
) )

View file

@ -1,9 +1,9 @@
package basic package basic
import ( import (
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "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"
"github.com/TrueCloudLab/frostfs-sdk-go/container/acl" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -23,6 +23,6 @@ InnerRing members are allowed to data audit ops only:
func printACL(cmd *cobra.Command, args []string) { func printACL(cmd *cobra.Command, args []string) {
var bacl acl.Basic var bacl acl.Basic
common.ExitOnErr(cmd, "unable to parse basic acl: %w", bacl.DecodeString(args[0])) commonCmd.ExitOnErr(cmd, "unable to parse basic acl: %w", bacl.DecodeString(args[0]))
util.PrettyPrintTableBACL(cmd, &bacl) util.PrettyPrintTableBACL(cmd, &bacl)
} }

View file

@ -6,11 +6,11 @@ import (
"os" "os"
"strings" "strings"
"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/modules/util"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
"github.com/TrueCloudLab/frostfs-sdk-go/eacl" "git.frostfs.info/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 github.com/TrueCloudLab/frostfs-api/blob/master/proto-docs/acl.md#message-eaclrecordfilter Read more about filter keys at git.frostfs.info.com/TrueCloudLab/frostfs-api/src/branch/master/proto-docs/acl.md#message-eaclrecordfilter
Match is '=' for matching and '!=' for non-matching filter. 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.
@ -84,7 +84,7 @@ func createEACL(cmd *cobra.Command, _ []string) {
} }
tb := eacl.NewTable() tb := eacl.NewTable()
common.ExitOnErr(cmd, "unable to parse provided rules: %w", util.ParseEACLRules(tb, rules)) commonCmd.ExitOnErr(cmd, "unable to parse provided rules: %w", util.ParseEACLRules(tb, rules))
tb.SetCID(containerID) tb.SetCID(containerID)

View file

@ -3,8 +3,8 @@ package extended
import ( import (
"testing" "testing"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
"github.com/TrueCloudLab/frostfs-sdk-go/eacl" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )

View file

@ -4,9 +4,9 @@ import (
"os" "os"
"strings" "strings"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "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"
"github.com/TrueCloudLab/frostfs-sdk-go/eacl" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -27,12 +27,12 @@ func printEACL(cmd *cobra.Command, _ []string) {
file, _ := cmd.Flags().GetString("file") file, _ := cmd.Flags().GetString("file")
eaclTable := new(eacl.Table) eaclTable := new(eacl.Table)
data, err := os.ReadFile(file) data, err := os.ReadFile(file)
common.ExitOnErr(cmd, "can't read file with EACL: %w", err) commonCmd.ExitOnErr(cmd, "can't read file with EACL: %w", err)
if strings.HasSuffix(file, ".json") { if strings.HasSuffix(file, ".json") {
common.ExitOnErr(cmd, "unable to parse json: %w", eaclTable.UnmarshalJSON(data)) commonCmd.ExitOnErr(cmd, "unable to parse json: %w", eaclTable.UnmarshalJSON(data))
} else { } else {
rules := strings.Split(strings.TrimSpace(string(data)), "\n") rules := strings.Split(strings.TrimSpace(string(data)), "\n")
common.ExitOnErr(cmd, "can't parse file with EACL: %w", util.ParseEACLRules(eaclTable, rules)) commonCmd.ExitOnErr(cmd, "can't parse file with EACL: %w", util.ParseEACLRules(eaclTable, rules))
} }
util.PrettyPrintTableEACL(cmd, eaclTable) util.PrettyPrintTableEACL(cmd, eaclTable)
} }

View file

@ -1,8 +1,8 @@
package acl package acl
import ( import (
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/acl/basic" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/acl/basic"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/acl/extended" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/acl/extended"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View file

@ -7,12 +7,13 @@ import (
"os" "os"
"time" "time"
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
"github.com/TrueCloudLab/frostfs-sdk-go/bearer" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
eaclSDK "github.com/TrueCloudLab/frostfs-sdk-go/eacl" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
"github.com/TrueCloudLab/frostfs-sdk-go/user" eaclSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -58,13 +59,13 @@ func init() {
func createToken(cmd *cobra.Command, _ []string) { func createToken(cmd *cobra.Command, _ []string) {
iat, iatRelative, err := common.ParseEpoch(cmd, issuedAtFlag) iat, iatRelative, err := common.ParseEpoch(cmd, issuedAtFlag)
common.ExitOnErr(cmd, "can't parse --"+issuedAtFlag+" flag: %w", err) commonCmd.ExitOnErr(cmd, "can't parse --"+issuedAtFlag+" flag: %w", err)
exp, expRelative, err := common.ParseEpoch(cmd, commonflags.ExpireAt) exp, expRelative, err := common.ParseEpoch(cmd, commonflags.ExpireAt)
common.ExitOnErr(cmd, "can't parse --"+commonflags.ExpireAt+" flag: %w", err) commonCmd.ExitOnErr(cmd, "can't parse --"+commonflags.ExpireAt+" flag: %w", err)
nvb, nvbRelative, err := common.ParseEpoch(cmd, notValidBeforeFlag) nvb, nvbRelative, err := common.ParseEpoch(cmd, notValidBeforeFlag)
common.ExitOnErr(cmd, "can't parse --"+notValidBeforeFlag+" flag: %w", err) commonCmd.ExitOnErr(cmd, "can't parse --"+notValidBeforeFlag+" flag: %w", err)
if iatRelative || expRelative || nvbRelative { if iatRelative || expRelative || nvbRelative {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
@ -72,7 +73,7 @@ func createToken(cmd *cobra.Command, _ []string) {
endpoint, _ := cmd.Flags().GetString(commonflags.RPC) endpoint, _ := cmd.Flags().GetString(commonflags.RPC)
currEpoch, err := internalclient.GetCurrentEpoch(ctx, cmd, endpoint) currEpoch, err := internalclient.GetCurrentEpoch(ctx, cmd, endpoint)
common.ExitOnErr(cmd, "can't fetch current epoch: %w", err) commonCmd.ExitOnErr(cmd, "can't fetch current epoch: %w", err)
if iatRelative { if iatRelative {
iat += currEpoch iat += currEpoch
@ -85,14 +86,14 @@ func createToken(cmd *cobra.Command, _ []string) {
} }
} }
if exp < nvb { if exp < nvb {
common.ExitOnErr(cmd, "", commonCmd.ExitOnErr(cmd, "",
fmt.Errorf("expiration epoch is less than not-valid-before epoch: %d < %d", exp, nvb)) fmt.Errorf("expiration epoch is less than not-valid-before epoch: %d < %d", exp, nvb))
} }
ownerStr, _ := cmd.Flags().GetString(ownerFlag) ownerStr, _ := cmd.Flags().GetString(ownerFlag)
var ownerID user.ID var ownerID user.ID
common.ExitOnErr(cmd, "can't parse recipient: %w", ownerID.DecodeString(ownerStr)) commonCmd.ExitOnErr(cmd, "can't parse recipient: %w", ownerID.DecodeString(ownerStr))
var b bearer.Token var b bearer.Token
b.SetExp(exp) b.SetExp(exp)
@ -104,8 +105,8 @@ func createToken(cmd *cobra.Command, _ []string) {
if eaclPath != "" { if eaclPath != "" {
table := eaclSDK.NewTable() table := eaclSDK.NewTable()
raw, err := os.ReadFile(eaclPath) raw, err := os.ReadFile(eaclPath)
common.ExitOnErr(cmd, "can't read extended ACL file: %w", err) commonCmd.ExitOnErr(cmd, "can't read extended ACL file: %w", err)
common.ExitOnErr(cmd, "can't parse extended ACL: %w", json.Unmarshal(raw, table)) commonCmd.ExitOnErr(cmd, "can't parse extended ACL: %w", json.Unmarshal(raw, table))
b.SetEACLTable(*table) b.SetEACLTable(*table)
} }
@ -114,12 +115,12 @@ func createToken(cmd *cobra.Command, _ []string) {
toJSON, _ := cmd.Flags().GetBool(jsonFlag) toJSON, _ := cmd.Flags().GetBool(jsonFlag)
if toJSON { if toJSON {
data, err = json.Marshal(b) data, err = json.Marshal(b)
common.ExitOnErr(cmd, "can't mashal token to JSON: %w", err) commonCmd.ExitOnErr(cmd, "can't mashal token to JSON: %w", err)
} else { } else {
data = b.Marshal() data = b.Marshal()
} }
out, _ := cmd.Flags().GetString(outFlag) out, _ := cmd.Flags().GetString(outFlag)
err = os.WriteFile(out, data, 0644) err = os.WriteFile(out, data, 0644)
common.ExitOnErr(cmd, "can't write token to file: %w", err) commonCmd.ExitOnErr(cmd, "can't write token to file: %w", err)
} }

View file

@ -1,7 +1,7 @@
package cmd package cmd
import ( import (
"github.com/TrueCloudLab/frostfs-node/pkg/util/autocomplete" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/autocomplete"
) )
func init() { func init() {

View file

@ -7,15 +7,17 @@ import (
"strings" "strings"
"time" "time"
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" containerApi "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
"github.com/TrueCloudLab/frostfs-sdk-go/container" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
"github.com/TrueCloudLab/frostfs-sdk-go/container/acl" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"github.com/TrueCloudLab/frostfs-sdk-go/netmap" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
subnetid "github.com/TrueCloudLab/frostfs-sdk-go/subnet/id" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
"github.com/TrueCloudLab/frostfs-sdk-go/user" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
subnetid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/subnet/id"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -25,6 +27,8 @@ var (
containerAttributes []string containerAttributes []string
containerAwait bool containerAwait bool
containerName string containerName string
containerNnsName string
containerNnsZone string
containerNoTimestamp bool containerNoTimestamp bool
containerSubnet string containerSubnet string
force bool force bool
@ -33,11 +37,11 @@ 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 NeoFS. 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)
common.ExitOnErr(cmd, "", err) commonCmd.ExitOnErr(cmd, "", err)
key := key.Get(cmd) key := key.Get(cmd)
cli := internalclient.GetSDKClientByFlag(cmd, key, commonflags.RPC) cli := internalclient.GetSDKClientByFlag(cmd, key, commonflags.RPC)
@ -47,16 +51,16 @@ It will be stored in sidechain when inner ring will accepts it.`,
prm.SetClient(cli) prm.SetClient(cli)
resmap, err := internalclient.NetMapSnapshot(prm) resmap, err := internalclient.NetMapSnapshot(prm)
common.ExitOnErr(cmd, "unable to get netmap snapshot to validate container placement, "+ commonCmd.ExitOnErr(cmd, "unable to get netmap snapshot to validate container placement, "+
"use --force option to skip this check: %w", err) "use --force option to skip this check: %w", err)
nodesByRep, err := resmap.NetMap().ContainerNodes(*placementPolicy, nil) nodesByRep, err := resmap.NetMap().ContainerNodes(*placementPolicy, nil)
common.ExitOnErr(cmd, "could not build container nodes based on given placement policy, "+ commonCmd.ExitOnErr(cmd, "could not build container nodes based on given placement policy, "+
"use --force option to skip this check: %w", err) "use --force option to skip this check: %w", err)
for i, nodes := range nodesByRep { for i, nodes := range nodesByRep {
if placementPolicy.ReplicaNumberByIndex(i) > uint32(len(nodes)) { if placementPolicy.ReplicaNumberByIndex(i) > uint32(len(nodes)) {
common.ExitOnErr(cmd, "", fmt.Errorf( commonCmd.ExitOnErr(cmd, "", fmt.Errorf(
"the number of nodes '%d' in selector is not enough for the number of replicas '%d', "+ "the number of nodes '%d' in selector is not enough for the number of replicas '%d', "+
"use --force option to skip this check", "use --force option to skip this check",
len(nodes), len(nodes),
@ -70,7 +74,7 @@ It will be stored in sidechain when inner ring will accepts it.`,
var subnetID subnetid.ID var subnetID subnetid.ID
err = subnetID.DecodeString(containerSubnet) err = subnetID.DecodeString(containerSubnet)
common.ExitOnErr(cmd, "could not parse subnetID: %w", err) commonCmd.ExitOnErr(cmd, "could not parse subnetID: %w", err)
placementPolicy.RestrictSubnet(subnetID) placementPolicy.RestrictSubnet(subnetID)
} }
@ -79,10 +83,10 @@ It will be stored in sidechain when inner ring will accepts it.`,
cnr.Init() cnr.Init()
err = parseAttributes(&cnr, containerAttributes) err = parseAttributes(&cnr, containerAttributes)
common.ExitOnErr(cmd, "", err) commonCmd.ExitOnErr(cmd, "", err)
var basicACL acl.Basic var basicACL acl.Basic
common.ExitOnErr(cmd, "decode basic ACL string: %w", basicACL.DecodeString(containerACL)) commonCmd.ExitOnErr(cmd, "decode basic ACL string: %w", basicACL.DecodeString(containerACL))
tok := getSession(cmd) tok := getSession(cmd)
@ -104,7 +108,7 @@ It will be stored in sidechain when inner ring will accepts it.`,
syncContainerPrm.SetContainer(&cnr) syncContainerPrm.SetContainer(&cnr)
_, err = internalclient.SyncContainerSettings(syncContainerPrm) _, err = internalclient.SyncContainerSettings(syncContainerPrm)
common.ExitOnErr(cmd, "syncing container's settings rpc error: %w", err) commonCmd.ExitOnErr(cmd, "syncing container's settings rpc error: %w", err)
var putPrm internalclient.PutContainerPrm var putPrm internalclient.PutContainerPrm
putPrm.SetClient(cli) putPrm.SetClient(cli)
@ -115,7 +119,7 @@ It will be stored in sidechain when inner ring will accepts it.`,
} }
res, err := internalclient.PutContainer(putPrm) res, err := internalclient.PutContainer(putPrm)
common.ExitOnErr(cmd, "put container rpc error: %w", err) commonCmd.ExitOnErr(cmd, "put container rpc error: %w", err)
id := res.ID() id := res.ID()
@ -138,7 +142,7 @@ It will be stored in sidechain when inner ring will accepts it.`,
} }
} }
common.ExitOnErr(cmd, "", errCreateTimeout) commonCmd.ExitOnErr(cmd, "", errCreateTimeout)
} }
}, },
} }
@ -159,6 +163,8 @@ func initContainerCreateCmd() {
flags.StringSliceVarP(&containerAttributes, "attributes", "a", nil, "Comma separated pairs of container attributes in form of Key1=Value1,Key2=Value2") flags.StringSliceVarP(&containerAttributes, "attributes", "a", nil, "Comma separated pairs of container attributes in form of Key1=Value1,Key2=Value2")
flags.BoolVar(&containerAwait, "await", false, "Block execution until container is persisted") flags.BoolVar(&containerAwait, "await", false, "Block execution until container is persisted")
flags.StringVar(&containerName, "name", "", "Container name attribute") flags.StringVar(&containerName, "name", "", "Container name attribute")
flags.StringVar(&containerNnsName, "nns-name", "", "Container nns name attribute")
flags.StringVar(&containerNnsZone, "nns-zone", "", "Container nns zone attribute")
flags.BoolVar(&containerNoTimestamp, "disable-timestamp", false, "Disable timestamp container attribute") flags.BoolVar(&containerNoTimestamp, "disable-timestamp", false, "Disable timestamp container attribute")
flags.StringVar(&containerSubnet, "subnet", "", "String representation of container subnetwork") flags.StringVar(&containerSubnet, "subnet", "", "String representation of container subnetwork")
flags.BoolVarP(&force, commonflags.ForceFlag, commonflags.ForceFlagShorthand, false, flags.BoolVarP(&force, commonflags.ForceFlag, commonflags.ForceFlagShorthand, false,
@ -196,12 +202,12 @@ func parseContainerPolicy(cmd *cobra.Command, policyString string) (*netmap.Plac
func parseAttributes(dst *container.Container, attributes []string) error { func parseAttributes(dst *container.Container, attributes []string) error {
for i := range attributes { for i := range attributes {
kvPair := strings.Split(attributes[i], attributeDelimiter) k, v, found := strings.Cut(attributes[i], attributeDelimiter)
if len(kvPair) != 2 { if !found {
return errors.New("invalid container attribute") return errors.New("invalid container attribute")
} }
dst.SetAttribute(kvPair[0], kvPair[1]) dst.SetAttribute(k, v)
} }
if !containerNoTimestamp { if !containerNoTimestamp {
@ -212,5 +218,12 @@ func parseAttributes(dst *container.Container, attributes []string) error {
container.SetName(dst, containerName) container.SetName(dst, containerName)
} }
if containerNnsName != "" {
dst.SetAttribute(containerApi.SysAttributeName, containerNnsName)
}
if containerNnsZone != "" {
dst.SetAttribute(containerApi.SysAttributeZone, containerNnsZone)
}
return nil return nil
} }

View file

@ -4,19 +4,20 @@ import (
"fmt" "fmt"
"time" "time"
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
objectSDK "github.com/TrueCloudLab/frostfs-sdk-go/object" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"github.com/TrueCloudLab/frostfs-sdk-go/user" objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
"git.frostfs.info/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)
@ -34,7 +35,7 @@ Only owner of the container has a permission to remove container.`,
getPrm.SetContainer(id) getPrm.SetContainer(id)
resGet, err := internalclient.GetContainer(getPrm) resGet, err := internalclient.GetContainer(getPrm)
common.ExitOnErr(cmd, "can't get the container: %w", err) commonCmd.ExitOnErr(cmd, "can't get the container: %w", err)
owner := resGet.Container().Owner() owner := resGet.Container().Owner()
@ -42,7 +43,7 @@ Only owner of the container has a permission to remove container.`,
common.PrintVerbose(cmd, "Checking session issuer...") common.PrintVerbose(cmd, "Checking session issuer...")
if !tok.Issuer().Equals(owner) { if !tok.Issuer().Equals(owner) {
common.ExitOnErr(cmd, "", fmt.Errorf("session issuer differs with the container owner: expected %s, has %s", owner, tok.Issuer())) commonCmd.ExitOnErr(cmd, "", fmt.Errorf("session issuer differs with the container owner: expected %s, has %s", owner, tok.Issuer()))
} }
} else { } else {
common.PrintVerbose(cmd, "Checking provided account...") common.PrintVerbose(cmd, "Checking provided account...")
@ -51,7 +52,7 @@ Only owner of the container has a permission to remove container.`,
user.IDFromKey(&acc, pk.PublicKey) user.IDFromKey(&acc, pk.PublicKey)
if !acc.Equals(owner) { if !acc.Equals(owner) {
common.ExitOnErr(cmd, "", fmt.Errorf("provided account differs with the container owner: expected %s, has %s", owner, acc)) commonCmd.ExitOnErr(cmd, "", fmt.Errorf("provided account differs with the container owner: expected %s, has %s", owner, acc))
} }
} }
@ -72,10 +73,10 @@ Only owner of the container has a permission to remove container.`,
common.PrintVerbose(cmd, "Searching for LOCK objects...") common.PrintVerbose(cmd, "Searching for LOCK objects...")
res, err := internalclient.SearchObjects(searchPrm) res, err := internalclient.SearchObjects(searchPrm)
common.ExitOnErr(cmd, "can't search for LOCK objects: %w", err) commonCmd.ExitOnErr(cmd, "can't search for LOCK objects: %w", err)
if len(res.IDList()) != 0 { if len(res.IDList()) != 0 {
common.ExitOnErr(cmd, "", commonCmd.ExitOnErr(cmd, "",
fmt.Errorf("Container wasn't removed because LOCK objects were found.\n"+ 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))
} }
@ -91,7 +92,7 @@ Only owner of the container has a permission to remove container.`,
} }
_, err := internalclient.DeleteContainer(delPrm) _, err := internalclient.DeleteContainer(delPrm)
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
cmd.Println("container delete method invoked") cmd.Println("container delete method invoked")
@ -112,7 +113,7 @@ Only owner of the container has a permission to remove container.`,
} }
} }
common.ExitOnErr(cmd, "", errDeleteTimeout) commonCmd.ExitOnErr(cmd, "", errDeleteTimeout)
} }
}, },
} }

View file

@ -4,14 +4,15 @@ import (
"crypto/ecdsa" "crypto/ecdsa"
"os" "os"
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
"github.com/TrueCloudLab/frostfs-sdk-go/container" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"github.com/TrueCloudLab/frostfs-sdk-go/container/acl" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -44,13 +45,13 @@ var getContainerInfoCmd = &cobra.Command{
if containerJSON { if containerJSON {
data, err = cnr.MarshalJSON() data, err = cnr.MarshalJSON()
common.ExitOnErr(cmd, "can't JSON encode container: %w", err) commonCmd.ExitOnErr(cmd, "can't JSON encode container: %w", err)
} else { } else {
data = cnr.Marshal() data = cnr.Marshal()
} }
err = os.WriteFile(containerPathTo, data, 0644) err = os.WriteFile(containerPathTo, data, 0644)
common.ExitOnErr(cmd, "can't write container to file: %w", err) commonCmd.ExitOnErr(cmd, "can't write container to file: %w", err)
} }
}, },
} }
@ -96,7 +97,7 @@ func prettyPrintContainer(cmd *cobra.Command, cnr container.Container, jsonEncod
}) })
cmd.Println("placement policy:") cmd.Println("placement policy:")
common.ExitOnErr(cmd, "write policy: %w", cnr.PlacementPolicy().WriteStringTo((*stringWriter)(cmd))) commonCmd.ExitOnErr(cmd, "write policy: %w", cnr.PlacementPolicy().WriteStringTo((*stringWriter)(cmd)))
cmd.Println() cmd.Println()
} }
@ -137,10 +138,10 @@ func getContainer(cmd *cobra.Command) (container.Container, *ecdsa.PrivateKey) {
var pk *ecdsa.PrivateKey var pk *ecdsa.PrivateKey
if containerPathFrom != "" { if containerPathFrom != "" {
data, err := os.ReadFile(containerPathFrom) data, err := os.ReadFile(containerPathFrom)
common.ExitOnErr(cmd, "can't read file: %w", err) commonCmd.ExitOnErr(cmd, "can't read file: %w", err)
err = cnr.Unmarshal(data) err = cnr.Unmarshal(data)
common.ExitOnErr(cmd, "can't unmarshal container: %w", err) commonCmd.ExitOnErr(cmd, "can't unmarshal container: %w", err)
} else { } else {
id := parseContainerID(cmd) id := parseContainerID(cmd)
pk = key.GetOrGenerate(cmd) pk = key.GetOrGenerate(cmd)
@ -151,7 +152,7 @@ func getContainer(cmd *cobra.Command) (container.Container, *ecdsa.PrivateKey) {
prm.SetContainer(id) prm.SetContainer(id)
res, err := internalclient.GetContainer(prm) res, err := internalclient.GetContainer(prm)
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
cnr = res.Container() cnr = res.Container()
} }

View file

@ -3,10 +3,11 @@ package container
import ( import (
"os" "os"
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -24,7 +25,7 @@ var getExtendedACLCmd = &cobra.Command{
eaclPrm.SetContainer(id) eaclPrm.SetContainer(id)
res, err := internalclient.EACL(eaclPrm) res, err := internalclient.EACL(eaclPrm)
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
eaclTable := res.EACL() eaclTable := res.EACL()
@ -39,16 +40,16 @@ var getExtendedACLCmd = &cobra.Command{
if containerJSON { if containerJSON {
data, err = eaclTable.MarshalJSON() data, err = eaclTable.MarshalJSON()
common.ExitOnErr(cmd, "can't encode to JSON: %w", err) commonCmd.ExitOnErr(cmd, "can't encode to JSON: %w", err)
} else { } else {
data, err = eaclTable.Marshal() data, err = eaclTable.Marshal()
common.ExitOnErr(cmd, "can't encode to binary: %w", err) commonCmd.ExitOnErr(cmd, "can't encode to binary: %w", err)
} }
cmd.Println("dumping data to file:", containerPathTo) cmd.Println("dumping data to file:", containerPathTo)
err = os.WriteFile(containerPathTo, data, 0644) err = os.WriteFile(containerPathTo, data, 0644)
common.ExitOnErr(cmd, "could not write eACL to file: %w", err) commonCmd.ExitOnErr(cmd, "could not write eACL to file: %w", err)
}, },
} }

View file

@ -3,12 +3,12 @@ package container
import ( import (
"strings" "strings"
"github.com/TrueCloudLab/frostfs-api-go/v2/container" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
"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"
"github.com/TrueCloudLab/frostfs-sdk-go/user" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -37,7 +37,7 @@ var listContainersCmd = &cobra.Command{
user.IDFromKey(&idUser, key.PublicKey) user.IDFromKey(&idUser, key.PublicKey)
} else { } else {
err := idUser.DecodeString(flagVarListContainerOwner) err := idUser.DecodeString(flagVarListContainerOwner)
common.ExitOnErr(cmd, "invalid user ID: %w", err) commonCmd.ExitOnErr(cmd, "invalid user ID: %w", err)
} }
cli := internalclient.GetSDKClientByFlag(cmd, key, commonflags.RPC) cli := internalclient.GetSDKClientByFlag(cmd, key, commonflags.RPC)
@ -47,7 +47,7 @@ var listContainersCmd = &cobra.Command{
prm.SetAccount(idUser) prm.SetAccount(idUser)
res, err := internalclient.ListContainers(prm) res, err := internalclient.ListContainers(prm)
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
var prmGet internalclient.GetContainerPrm var prmGet internalclient.GetContainerPrm
prmGet.SetClient(cli) prmGet.SetClient(cli)

View file

@ -3,14 +3,14 @@ package container
import ( import (
"strings" "strings"
v2object "github.com/TrueCloudLab/frostfs-api-go/v2/object" v2object "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
"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" 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"
"github.com/TrueCloudLab/frostfs-sdk-go/object" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id" oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -52,7 +52,7 @@ var listContainerObjectsCmd = &cobra.Command{
prmSearch.SetFilters(*filters) prmSearch.SetFilters(*filters)
res, err := internalclient.SearchObjects(prmSearch) res, err := internalclient.SearchObjects(prmSearch)
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
objectIDs := res.IDList() objectIDs := res.IDList()

View file

@ -3,13 +3,13 @@ package container
import ( import (
"crypto/sha256" "crypto/sha256"
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
"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"
containerAPI "github.com/TrueCloudLab/frostfs-sdk-go/container" containerAPI "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
"github.com/TrueCloudLab/frostfs-sdk-go/netmap" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -32,7 +32,7 @@ var containerNodesCmd = &cobra.Command{
prm.SetClient(cli) prm.SetClient(cli)
resmap, err := internalclient.NetMapSnapshot(prm) resmap, err := internalclient.NetMapSnapshot(prm)
common.ExitOnErr(cmd, "unable to get netmap snapshot", err) commonCmd.ExitOnErr(cmd, "unable to get netmap snapshot", err)
var id cid.ID var id cid.ID
containerAPI.CalculateID(&id, cnr) containerAPI.CalculateID(&id, cnr)
@ -43,12 +43,12 @@ var containerNodesCmd = &cobra.Command{
var cnrNodes [][]netmap.NodeInfo var cnrNodes [][]netmap.NodeInfo
cnrNodes, err = resmap.NetMap().ContainerNodes(policy, binCnr) cnrNodes, err = resmap.NetMap().ContainerNodes(policy, binCnr)
common.ExitOnErr(cmd, "could not build container nodes for given container: %w", err) commonCmd.ExitOnErr(cmd, "could not build container nodes for given container: %w", err)
for i := range cnrNodes { for i := range cnrNodes {
cmd.Printf("Descriptor #%d, REP %d:\n", i+1, policy.ReplicaNumberByIndex(i)) cmd.Printf("Descriptor #%d, REP %d:\n", i+1, policy.ReplicaNumberByIndex(i))
for j := range cnrNodes[i] { for j := range cnrNodes[i] {
common.PrettyPrintNodeInfo(cmd, cnrNodes[i][j], j, "\t", short) commonCmd.PrettyPrintNodeInfo(cmd, cnrNodes[i][j], j, "\t", short)
} }
} }
}, },

View file

@ -1,7 +1,7 @@
package container package container
import ( import (
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View file

@ -5,10 +5,11 @@ import (
"errors" "errors"
"time" "time"
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -38,10 +39,10 @@ Container ID in EACL table will be substituted with ID from the CLI.`,
cmd.Println("Checking the ability to modify access rights in the container...") cmd.Println("Checking the ability to modify access rights in the container...")
extendable, err := internalclient.IsACLExtendable(cli, id) extendable, err := internalclient.IsACLExtendable(cli, id)
common.ExitOnErr(cmd, "Extensibility check failure: %w", err) commonCmd.ExitOnErr(cmd, "Extensibility check failure: %w", err)
if !extendable { if !extendable {
common.ExitOnErr(cmd, "", errors.New("container ACL is immutable")) commonCmd.ExitOnErr(cmd, "", errors.New("container ACL is immutable"))
} }
cmd.Println("ACL extension is enabled in the container, continue processing.") cmd.Println("ACL extension is enabled in the container, continue processing.")
@ -56,11 +57,11 @@ Container ID in EACL table will be substituted with ID from the CLI.`,
} }
_, err := internalclient.SetEACL(setEACLPrm) _, err := internalclient.SetEACL(setEACLPrm)
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
if containerAwait { if containerAwait {
exp, err := eaclTable.Marshal() exp, err := eaclTable.Marshal()
common.ExitOnErr(cmd, "broken EACL table: %w", err) commonCmd.ExitOnErr(cmd, "broken EACL table: %w", err)
cmd.Println("awaiting...") cmd.Println("awaiting...")
@ -87,7 +88,7 @@ Container ID in EACL table will be substituted with ID from the CLI.`,
} }
} }
common.ExitOnErr(cmd, "", errSetEACLTimeout) commonCmd.ExitOnErr(cmd, "", errSetEACLTimeout)
} }
}, },
} }

View file

@ -3,10 +3,11 @@ package container
import ( import (
"errors" "errors"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"github.com/TrueCloudLab/frostfs-sdk-go/session" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -24,12 +25,12 @@ var (
func parseContainerID(cmd *cobra.Command) cid.ID { func parseContainerID(cmd *cobra.Command) cid.ID {
if containerID == "" { if containerID == "" {
common.ExitOnErr(cmd, "", errors.New("container ID is not set")) commonCmd.ExitOnErr(cmd, "", errors.New("container ID is not set"))
} }
var id cid.ID var id cid.ID
err := id.DecodeString(containerID) err := id.DecodeString(containerID)
common.ExitOnErr(cmd, "can't decode container ID value: %w", err) commonCmd.ExitOnErr(cmd, "can't decode container ID value: %w", err)
return id return id
} }
@ -49,7 +50,7 @@ func getSession(cmd *cobra.Command) *session.Container {
var res session.Container var res session.Container
err := common.ReadBinaryOrJSON(cmd, &res, path) err := common.ReadBinaryOrJSON(cmd, &res, path)
common.ExitOnErr(cmd, "read container session: %v", err) commonCmd.ExitOnErr(cmd, "read container session: %v", err)
common.PrintVerbose(cmd, "Session successfully read.") common.PrintVerbose(cmd, "Session successfully read.")

View file

@ -1,10 +1,10 @@
package control package control
import ( import (
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client" rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "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"
"github.com/TrueCloudLab/frostfs-node/pkg/services/control" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -40,7 +40,7 @@ var dropObjectsCmd = &cobra.Command{
resp, err = control.DropObjects(client, req) resp, err = control.DropObjects(client, req)
return err return err
}) })
common.ExitOnErr(cmd, "", err) commonCmd.ExitOnErr(cmd, "", err)
verifyResponse(cmd, resp.GetSignature(), resp.GetBody()) verifyResponse(cmd, resp.GetSignature(), resp.GetBody())

View file

@ -1,10 +1,10 @@
package control package control
import ( import (
"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "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"
"github.com/TrueCloudLab/frostfs-node/pkg/services/control" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -32,7 +32,7 @@ func evacuateShard(cmd *cobra.Command, _ []string) {
resp, err = control.EvacuateShard(client, req) resp, err = control.EvacuateShard(client, req)
return err return err
}) })
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
cmd.Printf("Objects moved: %d\n", resp.GetBody().GetCount()) cmd.Printf("Objects moved: %d\n", resp.GetBody().GetCount())

View file

@ -1,10 +1,10 @@
package control package control
import ( import (
"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "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"
"github.com/TrueCloudLab/frostfs-node/pkg/services/control" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -31,7 +31,7 @@ func flushCache(cmd *cobra.Command, _ []string) {
resp, err = control.FlushCache(client, req) resp, err = control.FlushCache(client, req)
return err return err
}) })
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
verifyResponse(cmd, resp.GetSignature(), resp.GetBody()) verifyResponse(cmd, resp.GetSignature(), resp.GetBody())

View file

@ -3,13 +3,13 @@ package control
import ( import (
"crypto/ecdsa" "crypto/ecdsa"
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client" rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "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"
"github.com/TrueCloudLab/frostfs-node/pkg/services/control" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
ircontrol "github.com/TrueCloudLab/frostfs-node/pkg/services/control/ir" ircontrol "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir"
ircontrolsrv "github.com/TrueCloudLab/frostfs-node/pkg/services/control/ir/server" ircontrolsrv "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir/server"
"github.com/TrueCloudLab/frostfs-sdk-go/client" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -19,8 +19,8 @@ const (
var healthCheckCmd = &cobra.Command{ var healthCheckCmd = &cobra.Command{
Use: "healthcheck", Use: "healthcheck",
Short: "Health check of the NeoFS node", Short: "Health check of the FrostFS node",
Long: "Health check of the NeoFS node. Checks storage node by default, use --ir flag to work with Inner Ring.", Long: "Health check of the FrostFS node. Checks storage node by default, use --ir flag to work with Inner Ring.",
Run: healthCheck, Run: healthCheck,
} }
@ -52,7 +52,7 @@ func healthCheck(cmd *cobra.Command, _ []string) {
resp, err = control.HealthCheck(client, req) resp, err = control.HealthCheck(client, req)
return err return err
}) })
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
verifyResponse(cmd, resp.GetSignature(), resp.GetBody()) verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
@ -66,14 +66,14 @@ func healthCheckIR(cmd *cobra.Command, key *ecdsa.PrivateKey, c *client.Client)
req.SetBody(new(ircontrol.HealthCheckRequest_Body)) req.SetBody(new(ircontrol.HealthCheckRequest_Body))
err := ircontrolsrv.SignMessage(key, req) err := ircontrolsrv.SignMessage(key, req)
common.ExitOnErr(cmd, "could not sign request: %w", err) commonCmd.ExitOnErr(cmd, "could not sign request: %w", err)
var resp *ircontrol.HealthCheckResponse var resp *ircontrol.HealthCheckResponse
err = c.ExecRaw(func(client *rawclient.Client) error { err = c.ExecRaw(func(client *rawclient.Client) error {
resp, err = ircontrol.HealthCheck(client, req) resp, err = ircontrol.HealthCheck(client, req)
return err return err
}) })
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
verifyResponse(cmd, resp.GetSignature(), resp.GetBody()) verifyResponse(cmd, resp.GetSignature(), resp.GetBody())

View file

@ -1,7 +1,7 @@
package control package control
import ( import (
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
) )

View file

@ -3,11 +3,12 @@ package control
import ( import (
"fmt" "fmt"
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client" rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
"github.com/TrueCloudLab/frostfs-node/pkg/services/control" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -21,8 +22,8 @@ const (
var setNetmapStatusCmd = &cobra.Command{ var setNetmapStatusCmd = &cobra.Command{
Use: "set-status", Use: "set-status",
Short: "Set status of the storage node in NeoFS network map", Short: "Set status of the storage node in FrostFS network map",
Long: "Set status of the storage node in NeoFS network map", Long: "Set status of the storage node in FrostFS network map",
Run: setNetmapStatus, Run: setNetmapStatus,
} }
@ -57,7 +58,7 @@ func setNetmapStatus(cmd *cobra.Command, _ []string) {
switch st, _ := cmd.Flags().GetString(netmapStatusFlag); st { switch st, _ := cmd.Flags().GetString(netmapStatusFlag); st {
default: default:
common.ExitOnErr(cmd, "", fmt.Errorf("unsupported status %s", st)) commonCmd.ExitOnErr(cmd, "", fmt.Errorf("unsupported status %s", st))
case netmapStatusOnline: case netmapStatusOnline:
body.SetStatus(control.NetmapStatus_ONLINE) body.SetStatus(control.NetmapStatus_ONLINE)
printIgnoreForce(control.NetmapStatus_ONLINE) printIgnoreForce(control.NetmapStatus_ONLINE)
@ -86,7 +87,7 @@ func setNetmapStatus(cmd *cobra.Command, _ []string) {
resp, err = control.SetNetmapStatus(client, req) resp, err = control.SetNetmapStatus(client, req)
return err return err
}) })
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
verifyResponse(cmd, resp.GetSignature(), resp.GetBody()) verifyResponse(cmd, resp.GetSignature(), resp.GetBody())

View file

@ -1,10 +1,10 @@
package control package control
import ( import (
"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "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"
"github.com/TrueCloudLab/frostfs-node/pkg/services/control" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -45,7 +45,7 @@ func dumpShard(cmd *cobra.Command, _ []string) {
resp, err = control.DumpShard(client, req) resp, err = control.DumpShard(client, req)
return err return err
}) })
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
verifyResponse(cmd, resp.GetSignature(), resp.GetBody()) verifyResponse(cmd, resp.GetSignature(), resp.GetBody())

View file

@ -6,11 +6,11 @@ import (
"fmt" "fmt"
"strings" "strings"
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client" rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
"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"
"github.com/TrueCloudLab/frostfs-node/pkg/services/control" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
"github.com/mr-tron/base58" "github.com/mr-tron/base58"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -45,7 +45,7 @@ func listShards(cmd *cobra.Command, _ []string) {
resp, err = control.ListShards(client, req) resp, err = control.ListShards(client, req)
return err return err
}) })
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
verifyResponse(cmd, resp.GetSignature(), resp.GetBody()) verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
@ -58,9 +58,9 @@ func listShards(cmd *cobra.Command, _ []string) {
} }
func prettyPrintShardsJSON(cmd *cobra.Command, ii []*control.ShardInfo) { func prettyPrintShardsJSON(cmd *cobra.Command, ii []*control.ShardInfo) {
out := make([]map[string]interface{}, 0, len(ii)) out := make([]map[string]any, 0, len(ii))
for _, i := range ii { for _, i := range ii {
out = append(out, map[string]interface{}{ out = append(out, map[string]any{
"shard_id": base58.Encode(i.Shard_ID), "shard_id": base58.Encode(i.Shard_ID),
"mode": shardModeToString(i.GetMode()), "mode": shardModeToString(i.GetMode()),
"metabase": i.GetMetabasePath(), "metabase": i.GetMetabasePath(),
@ -73,7 +73,7 @@ func prettyPrintShardsJSON(cmd *cobra.Command, ii []*control.ShardInfo) {
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
enc := json.NewEncoder(buf) enc := json.NewEncoder(buf)
enc.SetIndent("", " ") enc.SetIndent("", " ")
common.ExitOnErr(cmd, "cannot shard info to JSON: %w", enc.Encode(out)) commonCmd.ExitOnErr(cmd, "cannot shard info to JSON: %w", enc.Encode(out))
cmd.Print(buf.String()) // pretty printer emits newline, to no need for Println cmd.Print(buf.String()) // pretty printer emits newline, to no need for Println
} }

View file

@ -1,10 +1,10 @@
package control package control
import ( import (
"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "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"
"github.com/TrueCloudLab/frostfs-node/pkg/services/control" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -45,7 +45,7 @@ func restoreShard(cmd *cobra.Command, _ []string) {
resp, err = control.RestoreShard(client, req) resp, err = control.RestoreShard(client, req)
return err return err
}) })
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
verifyResponse(cmd, resp.GetSignature(), resp.GetBody()) verifyResponse(cmd, resp.GetSignature(), resp.GetBody())

View file

@ -4,10 +4,10 @@ import (
"fmt" "fmt"
"strings" "strings"
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client" rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "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"
"github.com/TrueCloudLab/frostfs-node/pkg/services/control" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
"github.com/mr-tron/base58" "github.com/mr-tron/base58"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -93,6 +93,7 @@ func initControlSetShardModeCmd() {
flags.String(shardModeFlag, "", flags.String(shardModeFlag, "",
fmt.Sprintf("New shard mode (%s)", strings.Join(modes, ", ")), fmt.Sprintf("New shard mode (%s)", strings.Join(modes, ", ")),
) )
_ = setShardModeCmd.MarkFlagRequired(shardModeFlag)
flags.Bool(shardClearErrorsFlag, false, "Set shard error count to 0") flags.Bool(shardClearErrorsFlag, false, "Set shard error count to 0")
setShardModeCmd.MarkFlagsMutuallyExclusive(shardIDFlag, shardAllFlag) setShardModeCmd.MarkFlagsMutuallyExclusive(shardIDFlag, shardAllFlag)
@ -105,7 +106,7 @@ func setShardMode(cmd *cobra.Command, _ []string) {
mode, ok := lookUpShardModeFromString(strMode) mode, ok := lookUpShardModeFromString(strMode)
if !ok { if !ok {
common.ExitOnErr(cmd, "", fmt.Errorf("unsupported mode %s", strMode)) commonCmd.ExitOnErr(cmd, "", fmt.Errorf("unsupported mode %s", strMode))
} }
req := new(control.SetShardModeRequest) req := new(control.SetShardModeRequest)
@ -129,7 +130,7 @@ func setShardMode(cmd *cobra.Command, _ []string) {
resp, err = control.SetShardMode(client, req) resp, err = control.SetShardMode(client, req)
return err return err
}) })
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
verifyResponse(cmd, resp.GetSignature(), resp.GetBody()) verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
@ -139,7 +140,7 @@ func setShardMode(cmd *cobra.Command, _ []string) {
func getShardID(cmd *cobra.Command) []byte { func getShardID(cmd *cobra.Command) []byte {
sid, _ := cmd.Flags().GetString(shardIDFlag) sid, _ := cmd.Flags().GetString(shardIDFlag)
raw, err := base58.Decode(sid) raw, err := base58.Decode(sid)
common.ExitOnErr(cmd, "incorrect shard ID encoding: %w", err) commonCmd.ExitOnErr(cmd, "incorrect shard ID encoding: %w", err)
return raw return raw
} }
@ -151,7 +152,7 @@ func getShardIDList(cmd *cobra.Command) [][]byte {
sidList, _ := cmd.Flags().GetStringSlice(shardIDFlag) sidList, _ := cmd.Flags().GetStringSlice(shardIDFlag)
if len(sidList) == 0 { if len(sidList) == 0 {
common.ExitOnErr(cmd, "", fmt.Errorf("either --%s or --%s flag must be provided", shardIDFlag, shardAllFlag)) commonCmd.ExitOnErr(cmd, "", fmt.Errorf("either --%s or --%s flag must be provided", shardIDFlag, shardAllFlag))
} }
// We can sort the ID list and perform this check without additional allocations, // We can sort the ID list and perform this check without additional allocations,
@ -160,7 +161,7 @@ func getShardIDList(cmd *cobra.Command) [][]byte {
seen := make(map[string]struct{}) seen := make(map[string]struct{})
for i := range sidList { for i := range sidList {
if _, ok := seen[sidList[i]]; ok { if _, ok := seen[sidList[i]]; ok {
common.ExitOnErr(cmd, "", fmt.Errorf("duplicated shard IDs: %s", sidList[i])) commonCmd.ExitOnErr(cmd, "", fmt.Errorf("duplicated shard IDs: %s", sidList[i]))
} }
seen[sidList[i]] = struct{}{} seen[sidList[i]] = struct{}{}
} }
@ -168,7 +169,7 @@ func getShardIDList(cmd *cobra.Command) [][]byte {
res := make([][]byte, 0, len(sidList)) res := make([][]byte, 0, len(sidList))
for i := range sidList { for i := range sidList {
raw, err := base58.Decode(sidList[i]) raw, err := base58.Decode(sidList[i])
common.ExitOnErr(cmd, "incorrect shard ID encoding: %w", err) commonCmd.ExitOnErr(cmd, "incorrect shard ID encoding: %w", err)
res = append(res, raw) res = append(res, raw)
} }

View file

@ -4,13 +4,13 @@ import (
"crypto/sha256" "crypto/sha256"
"errors" "errors"
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client" rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
"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"
"github.com/TrueCloudLab/frostfs-node/pkg/services/control" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
controlSvc "github.com/TrueCloudLab/frostfs-node/pkg/services/control/server" controlSvc "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/server"
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -40,11 +40,11 @@ func synchronizeTree(cmd *cobra.Command, _ []string) {
var cnr cid.ID var cnr cid.ID
cidStr, _ := cmd.Flags().GetString(commonflags.CIDFlag) cidStr, _ := cmd.Flags().GetString(commonflags.CIDFlag)
common.ExitOnErr(cmd, "can't decode container ID: %w", cnr.DecodeString(cidStr)) commonCmd.ExitOnErr(cmd, "can't decode container ID: %w", cnr.DecodeString(cidStr))
treeID, _ := cmd.Flags().GetString("tree-id") treeID, _ := cmd.Flags().GetString("tree-id")
if treeID == "" { if treeID == "" {
common.ExitOnErr(cmd, "", errors.New("tree ID must not be empty")) commonCmd.ExitOnErr(cmd, "", errors.New("tree ID must not be empty"))
} }
height, _ := cmd.Flags().GetUint64("height") height, _ := cmd.Flags().GetUint64("height")
@ -61,7 +61,7 @@ func synchronizeTree(cmd *cobra.Command, _ []string) {
} }
err := controlSvc.SignMessage(pk, req) err := controlSvc.SignMessage(pk, req)
common.ExitOnErr(cmd, "could not sign request: %w", err) commonCmd.ExitOnErr(cmd, "could not sign request: %w", err)
cli := getClient(cmd, pk) cli := getClient(cmd, pk)
@ -70,7 +70,7 @@ func synchronizeTree(cmd *cobra.Command, _ []string) {
resp, err = control.SynchronizeTree(client, req) resp, err = control.SynchronizeTree(client, req)
return err return err
}) })
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
verifyResponse(cmd, resp.GetSignature(), resp.GetBody()) verifyResponse(cmd, resp.GetSignature(), resp.GetBody())

View file

@ -4,13 +4,13 @@ import (
"crypto/ecdsa" "crypto/ecdsa"
"errors" "errors"
"github.com/TrueCloudLab/frostfs-api-go/v2/refs" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
"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"
controlSvc "github.com/TrueCloudLab/frostfs-node/pkg/services/control/server" controlSvc "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/server"
"github.com/TrueCloudLab/frostfs-sdk-go/client" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
frostfscrypto "github.com/TrueCloudLab/frostfs-sdk-go/crypto" frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -24,7 +24,7 @@ func initControlFlags(cmd *cobra.Command) {
func signRequest(cmd *cobra.Command, pk *ecdsa.PrivateKey, req controlSvc.SignedMessage) { func signRequest(cmd *cobra.Command, pk *ecdsa.PrivateKey, req controlSvc.SignedMessage) {
err := controlSvc.SignMessage(pk, req) err := controlSvc.SignMessage(pk, req)
common.ExitOnErr(cmd, "could not sign request: %w", err) commonCmd.ExitOnErr(cmd, "could not sign request: %w", err)
} }
func verifyResponse(cmd *cobra.Command, func verifyResponse(cmd *cobra.Command,
@ -37,7 +37,7 @@ func verifyResponse(cmd *cobra.Command,
}, },
) { ) {
if sigControl == nil { if sigControl == nil {
common.ExitOnErr(cmd, "", errors.New("missing response signature")) commonCmd.ExitOnErr(cmd, "", errors.New("missing response signature"))
} }
// TODO(@cthulhu-rider): #1387 use Signature message from NeoFS API to avoid conversion // TODO(@cthulhu-rider): #1387 use Signature message from NeoFS API to avoid conversion
@ -47,10 +47,10 @@ func verifyResponse(cmd *cobra.Command,
sigV2.SetSign(sigControl.GetSign()) sigV2.SetSign(sigControl.GetSign())
var sig frostfscrypto.Signature var sig frostfscrypto.Signature
common.ExitOnErr(cmd, "can't read signature: %w", sig.ReadFromV2(sigV2)) commonCmd.ExitOnErr(cmd, "can't read signature: %w", sig.ReadFromV2(sigV2))
if !sig.Verify(body.StableMarshal(nil)) { if !sig.Verify(body.StableMarshal(nil)) {
common.ExitOnErr(cmd, "", errors.New("invalid response signature")) commonCmd.ExitOnErr(cmd, "", errors.New("invalid response signature"))
} }
} }

View file

@ -1,10 +1,10 @@
package netmap package netmap
import ( import (
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
"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"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -20,7 +20,7 @@ var getEpochCmd = &cobra.Command{
prm.SetClient(cli) prm.SetClient(cli)
res, err := internalclient.NetworkInfo(prm) res, err := internalclient.NetworkInfo(prm)
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
netInfo := res.NetworkInfo() netInfo := res.NetworkInfo()

View file

@ -4,18 +4,18 @@ import (
"encoding/hex" "encoding/hex"
"time" "time"
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
"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"
"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"
) )
var netInfoCmd = &cobra.Command{ var netInfoCmd = &cobra.Command{
Use: "netinfo", Use: "netinfo",
Short: "Get information about NeoFS network", Short: "Get information about FrostFS network",
Long: "Get information about NeoFS network", Long: "Get information about FrostFS network",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
p := key.GetOrGenerate(cmd) p := key.GetOrGenerate(cmd)
cli := internalclient.GetSDKClientByFlag(cmd, p, commonflags.RPC) cli := internalclient.GetSDKClientByFlag(cmd, p, commonflags.RPC)
@ -24,7 +24,7 @@ var netInfoCmd = &cobra.Command{
prm.SetClient(cli) prm.SetClient(cli)
res, err := internalclient.NetworkInfo(prm) res, err := internalclient.NetworkInfo(prm)
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
netInfo := res.NetworkInfo() netInfo := res.NetworkInfo()
@ -37,7 +37,7 @@ var netInfoCmd = &cobra.Command{
const format = " %s: %v\n" const format = " %s: %v\n"
cmd.Println("NeoFS network configuration (system)") cmd.Println("FrostFS network configuration (system)")
cmd.Printf(format, "Audit fee", netInfo.AuditFee()) cmd.Printf(format, "Audit fee", netInfo.AuditFee())
cmd.Printf(format, "Storage price", netInfo.StoragePrice()) cmd.Printf(format, "Storage price", netInfo.StoragePrice())
cmd.Printf(format, "Container fee", netInfo.ContainerFee()) cmd.Printf(format, "Container fee", netInfo.ContainerFee())
@ -50,7 +50,7 @@ var netInfoCmd = &cobra.Command{
cmd.Printf(format, "Homomorphic hashing disabled", netInfo.HomomorphicHashingDisabled()) cmd.Printf(format, "Homomorphic hashing disabled", netInfo.HomomorphicHashingDisabled())
cmd.Printf(format, "Maintenance mode allowed", netInfo.MaintenanceModeAllowed()) cmd.Printf(format, "Maintenance mode allowed", netInfo.MaintenanceModeAllowed())
cmd.Println("NeoFS network configuration (other)") cmd.Println("FrostFS network configuration (other)")
netInfo.IterateRawNetworkParameters(func(name string, value []byte) { netInfo.IterateRawNetworkParameters(func(name string, value []byte) {
cmd.Printf(format, name, hex.EncodeToString(value)) cmd.Printf(format, name, hex.EncodeToString(value))
}) })

View file

@ -3,11 +3,12 @@ package netmap
import ( import (
"encoding/hex" "encoding/hex"
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
"github.com/TrueCloudLab/frostfs-sdk-go/netmap" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -25,7 +26,7 @@ var nodeInfoCmd = &cobra.Command{
prm.SetClient(cli) prm.SetClient(cli)
res, err := internalclient.NodeInfo(prm) res, err := internalclient.NodeInfo(prm)
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
prettyPrintNodeInfo(cmd, res.NodeInfo()) prettyPrintNodeInfo(cmd, res.NodeInfo())
}, },

View file

@ -1,7 +1,7 @@
package netmap package netmap
import ( import (
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View file

@ -1,10 +1,10 @@
package netmap package netmap
import ( import (
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
"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"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -20,9 +20,9 @@ var snapshotCmd = &cobra.Command{
prm.SetClient(cli) prm.SetClient(cli)
res, err := internalclient.NetMapSnapshot(prm) res, err := internalclient.NetMapSnapshot(prm)
common.ExitOnErr(cmd, "rpc error: %w", err) commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
common.PrettyPrintNetMap(cmd, res.NetMap()) commonCmd.PrettyPrintNetMap(cmd, res.NetMap(), false)
}, },
} }

Some files were not shown because too many files have changed in this diff Show more