.
675 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | #!/usr/bin/make -f
2 | SHELL = bash
3 |
4 | # Main environment configuration
5 | include .env
6 |
7 | # Optional variables with secrets
8 | -include .secrets
9 |
10 | # help target
11 | include help.mk
12 |
13 | # update FrostFS global config targets
14 | include frostfs_config.mk
15 |
16 | # Targets to get required artifacts and external resources for each service
17 | include services/*/artifacts.mk
18 |
19 | # Targets helpful to prepare service environment
20 | include services/*/prepare.mk
21 |
22 | # List of services to run
23 | START_SVCS = $(shell cat .services | grep -v '#')
24 | START_BASIC = $(shell cat .basic_services | grep -ve '#')
25 | START_BOOTSTRAP = $(shell cat .bootstrap_services | grep -v '#')
26 | STOP_SVCS = $(shell tac .services | grep -v '#')
27 | STOP_BASIC = $(shell tac .basic_services | grep -v '#')
28 | STOP_BOOTSTRAP = $(shell tac .bootstrap_services | grep -v '#')
29 |
30 | # Enabled services dirs
31 | ENABLED_SVCS_DIRS = $(shell echo "${START_BOOTSTRAP} ${START_BASIC} ${START_SVCS}" | sed 's|[^ ]* *|./services/&|g')
32 |
33 | # Services that require artifacts
34 | GET_SVCS = $(shell grep -Rl "get.*:" ./services/* | sort -u | grep artifacts.mk | xargs -I {} dirname {} | xargs basename -a)
35 |
36 | # Services that require pulling images
37 | PULL_SVCS = $(shell find ${ENABLED_SVCS_DIRS} -type f -name 'docker-compose.yml' | sort -u | xargs -I {} dirname {} | xargs basename -a)
38 |
39 | # List of hosts available in devenv
40 | HOSTS_LINES = $(shell grep -Rl IPV4_PREFIX ./services/* | grep .hosts)
41 |
42 | # Paths to protocol.privnet.yml
43 | MORPH_CHAIN_PROTOCOL = './services/morph_chain/protocol.privnet.yml'
44 |
45 | # List of grepped environment variables from *.env
46 | GREP_DOTENV = $(shell find . -name '*.env' -exec grep -rhv -e '^\#' -e '^$$' {} + | sort -u )
47 |
48 | # Pull all required Docker images
49 | .PHONY: pull
50 | pull:
51 | $(foreach SVC, $(PULL_SVCS), $(shell cd services/$(SVC) && docker-compose pull))
52 | @:
53 |
54 | # Get all services artifacts
55 | .PHONY: get
56 | get: $(foreach SVC, $(GET_SVCS), get.$(SVC))
57 | @:
58 |
59 | # Start environment
60 | .PHONY: up
61 | up: up/basic
62 | @$(foreach SVC, $(START_SVCS), $(shell docker-compose -f services/$(SVC)/docker-compose.yml up -d))
63 | @echo "Full FrostFS Developer Environment is ready"
64 |
65 | # Build up FrostFS
66 | .PHONY: up/basic
67 | up/basic: up/bootstrap
68 | @$(foreach SVC, $(START_BASIC), $(shell docker-compose -f services/$(SVC)/docker-compose.yml up -d))
69 | @./bin/tick.sh
70 | @./bin/config.sh string SystemDNS container
71 | @echo "Basic FrostFS Developer Environment is ready"
72 |
73 | # Start bootstrap services
74 | .PHONY: up/bootstrap
75 | up/bootstrap: get vendor/hosts
76 | @$(foreach SVC, $(START_BOOTSTRAP), $(shell docker-compose -f services/$(SVC)/docker-compose.yml up -d))
77 | @source ./bin/helper.sh
78 | @./vendor/frostfs-adm --config frostfs-adm.yml morph init --alphabet-wallets ./services/ir --contracts vendor/contracts || die "Failed to initialize Alphabet wallets"
79 | @for f in ./services/storage/wallet*.json; do echo "Transfer GAS to wallet $${f}" && ./vendor/frostfs-adm -c frostfs-adm.yml morph refill-gas --storage-wallet $${f} --gas 10.0 --alphabet-wallets services/ir || die "Failed to transfer GAS to alphabet wallets"; done
80 | @echo "FrostFS sidechain environment is deployed"
81 |
82 | # Build up certain service
83 | .PHONY: up/%
84 | up/%: get vendor/hosts
85 | @docker-compose -f services/$*/docker-compose.yml up -d
86 | @echo "Developer Environment for $* service is ready"
87 |
88 | # Stop environment
89 | .PHONY: down
90 | down: down/add down/basic down/bootstrap
91 | @echo "Full FrostFS Developer Environment is down"
92 |
93 | .PHONY: down/add
94 | down/add:
95 | $(foreach SVC, $(STOP_SVCS), $(shell docker-compose -f services/$(SVC)/docker-compose.yml down))
96 |
97 | # Stop basic environment
98 | .PHONY: down/basic
99 | down/basic:
100 | $(foreach SVC, $(STOP_BASIC), $(shell docker-compose -f services/$(SVC)/docker-compose.yml down))
101 |
102 | # Stop bootstrap services
103 | .PHONY: down/bootstrap
104 | down/bootstrap:
105 | $(foreach SVC, $(STOP_BOOTSTRAP), $(shell docker-compose -f services/$(SVC)/docker-compose.yml down))
106 |
107 | # Stop certain service
108 | .PHONY: down/%
109 | down/%:
110 | @docker-compose -f services/$*/docker-compose.yml down
111 |
112 | # Generate changes for /etc/hosts
113 | .PHONY: vendor/hosts
114 | .ONESHELL:
115 | vendor/hosts:
116 | @for file in $(HOSTS_LINES)
117 | do
118 | while read h
119 | do
120 | echo $${h} | \
121 | sed 's|IPV4_PREFIX|$(IPV4_PREFIX)|g' | \
122 | sed 's|LOCAL_DOMAIN|$(LOCAL_DOMAIN)|g'
123 | done < $${file};
124 | done > $@
125 |
126 | # Generate and display changes for /etc/hosts
127 | .PHONY: hosts
128 | hosts: vendor/hosts
129 | @cat vendor/hosts
130 |
131 | # Clean-up the environment
132 | .PHONY: clean
133 | .ONESHELL:
134 | clean:
135 | @rm -rf vendor/* services/storage/s04tls.* services/nats/*.pem
136 | @> .int_test.env
137 | @for svc in $(PULL_SVCS)
138 | do
139 | vols=`docker-compose -f services/$${svc}/docker-compose.yml config --volumes`
140 | if [[ ! -z "$${vols}" ]]; then
141 | for vol in $${vols}; do
142 | docker volume rm -f "$${svc}_$${vol}" 2> /dev/null
143 | done
144 | fi
145 | done
146 |
147 | # Generate environment
148 | .PHONY: env
149 | env:
150 | @$(foreach envvar,$(GREP_DOTENV),echo $(envvar);)
151 | @echo MORPH_BLOCK_TIME=$(shell grep 'SecondsPerBlock' $(MORPH_CHAIN_PROTOCOL) | awk '{print $$2}')s
152 | @echo MORPH_MAGIC=$(shell grep 'Magic' $(MORPH_CHAIN_PROTOCOL) | awk '{print $$2}')
153 |
154 | # Restart storage nodes with clean volumes
155 | .PHONY: restart.storage-clean
156 | restart.storage-clean:
157 | @docker-compose -f ./services/storage/docker-compose.yml down
158 | @$(foreach vol, \
159 | $(shell docker-compose -f services/storage/docker-compose.yml config --volumes),\
160 | docker volume rm storage_$(vol);)
161 | @docker-compose -f ./services/storage/docker-compose.yml up -d
162 |
163 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | FrostFS local Development and Testing environment
6 |
7 |
8 | ---
9 | ## Overview
10 |
11 | Tools to set up local FrostFS network and N3 privnets. Devenv, for short.
12 |
13 | ## Prerequisites
14 |
15 | Make sure you have installed all of the following prerequisites on your machine:
16 | * docker
17 | * docker-compose
18 | * make (`3.82+`)
19 | * expect
20 | * openssl
21 | * jq
22 | * base64 (coreutils)
23 |
24 |
25 | ## Quick Start
26 |
27 | Clone repo:
28 |
29 | ```
30 | $ git clone https://github.com/TrueCloudLab/frostfs-dev-env.git
31 | ```
32 |
33 | Run next commands from project's root:
34 |
35 | ```
36 | $ make get
37 | ```
38 |
39 | This command should be executed for the first run only to execute
40 | `make hosts`. It is part of the `make up` and, if the hosts have
41 | been added already, there is no need to run it separately.
42 |
43 | ```
44 | $ make hosts
45 | 192.168.130.10 bastion.frostfs.devenv
46 | 192.168.130.50 main-chain.frostfs.devenv
47 | 192.168.130.61 ir01.frostfs.devenv
48 | ...
49 | 192.168.130.74 s04.frostfs.devenv
50 | ```
51 |
52 | This command shows addresses and hostnames of components. Add `make hosts`
53 | output to your local `/etc/hosts` file.
54 |
55 | Run all services with command:
56 | ```
57 | $ make up
58 | ```
59 |
60 | When all services are up, you need to make GAS deposit for test wallet to be
61 | able to pay for FrostFS operations. Test wallet is located in
62 | `wallets/wallet.json` with the corresponding key in `wallets/wallet.key`. The
63 | password is empty.
64 |
65 | ```
66 | $ make prepare.ir
67 | password >
68 | fa6ba62bffb04030d303dcc95bda7413e03aa3c7e6ca9c2f999d65db9ec9b82c
69 | ```
70 |
71 | Also, you should add self-signed node (`s04.frostfs.devenv`) certificate to trusted
72 | store (default location might be changed using `CA_CERTS_TRUSTED_STORE`
73 | variable). This step is required for client services (frostfs-http-gw,
74 | frostfs-s3-gw) to interact with the node:
75 |
76 | ```
77 | $ sudo make prepare.storage
78 | ```
79 |
80 | Change FrostFS global configuration values with `make update.*` commands. The
81 | password of inner ring wallet is `one`. See examples in `make help`.
82 |
83 | ```
84 | $ make update.epoch_duration val=30
85 | Changing EpochDuration configration value to 30
86 | Enter account NNudMSGzEoktFzdYGYoNb3bzHzbmM1genF password >
87 | Sent invocation transaction dbb8c1145b6d10f150135630e13bb0dc282023163f5956c6945a60db0cb45cb0
88 | Updating FrostFS epoch to 2
89 | Enter account NNudMSGzEoktFzdYGYoNb3bzHzbmM1genF password >
90 | Sent invocation transaction 0e6eb5e190f36332e5e5f4e866c7e100826e285fd949e11c085e15224f343ba6
91 | ```
92 |
93 | For instructions on how to set up DevEnv on macOS, please refer [the
94 | guide](docs/macOS.md) in `docs` directory.
95 |
96 | ## How it's organized
97 |
98 | ```
99 | .
100 | ├── Makefile # Commands to manage devenv
101 | ├── .services # List of services to work with
102 | ├── services # Services definitions and files
103 | │ ├── basenet
104 | │ ├── chain
105 | │ ├── ir
106 | │ ├── morph_chain
107 | │ └── storage
108 | ├── vendor # Temporary files and artifacts
109 | └── wallets # Wallet files to manage GAS assets
110 | ```
111 |
112 | Main commands and targets to manage devenv's services are in `Makefile`.
113 |
114 | Each service is defined in it's own directory under `services/` with all
115 | required files to run and scripts to get external artifacts or dependencies.
116 |
117 | The list of services and the starting order is defined in `.services` file. You
118 | can comment out services you don't want to start or add your own new services.
119 |
120 | You can find more information on each service in `docs` directory.
121 |
122 | Maybe you will find the answer for your question in [F.A.Q.](docs/faq.md)
123 |
124 | ## Using FrostFS Admin Tool in `dev-env`
125 |
126 | Devenv supports FrostFS network management via [frostfs-adm](https://github.com/TrueCloudLab/frostfs-node/tree/master/cmd/frostfs-adm).
127 | `services/ir` contains the Alphabet wallet in a proper format, specify it
128 | with `--alphabet-wallets` flag.
129 |
130 | ## Notable make targets
131 |
132 | `make help` will print the brief description of available targets. Here we
133 | describe some of them in a more detailed way.
134 |
135 | ### up
136 |
137 | Start all Devenv services.
138 |
139 | This target call `pull` to get container images, `get` to download required
140 | artifacts, `vendor/hosts` to generate hosts file and then starts all services in
141 | the order defined in `.services` file.
142 |
143 | ### down
144 |
145 | Shutdowns all services. This will destroy all containers and networks. All
146 | changes made inside containers will be lost.
147 |
148 | ### hosts
149 |
150 | Display addresses and host names for each running service, if available.
151 |
152 | ### clean
153 |
154 | Clean up `vendor` directory.
155 |
156 | ## Contributing
157 |
158 | Feel free to contribute to this project after reading the [contributing
159 | guidelines](CONTRIBUTING.md).
160 |
161 | Before starting to work on a certain topic, create an new issue first,
162 | describing the feature/topic you are going to implement.
163 |
164 | # License
165 |
166 | - [GNU General Public License v3.0](LICENSE)
167 |
--------------------------------------------------------------------------------
/bin/addCert.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Source env settings
4 | . .env
5 |
6 | ln -sf "$(pwd)/services/storage/s04tls.crt" "${CA_CERTS_TRUSTED_STORE}/s04.${LOCAL_DOMAIN}.tls.crt"
7 |
--------------------------------------------------------------------------------
/bin/config.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | echo "Running bin/config.sh"
4 |
5 | # Source env settings
6 | . .env
7 | . services/ir/.ir.env
8 | source bin/helper.sh
9 |
10 | # NeoGo binary path.
11 | NEOGO="${NEOGO:-docker exec morph_chain neo-go}"
12 |
13 | # Wallet files to change config value
14 | WALLET="${WALLET:-services/morph_chain/node-wallet.json}"
15 | CONFIG_IMG="${CONFIG_IMG:-/wallets/config.yml}"
16 |
17 | NETMAP_ADDR=$(bin/resolve.sh netmap.frostfs) || die "Failed to resolve 'netmap.frostfs' domain name"
18 |
19 | # FrostFS configuration record: variable type [string|int|etc],
20 | # key is a string and value is a constant of given type
21 | TYPE=${1}
22 | KEY=${2}
23 | VALUE="${3}"
24 |
25 | [ -z "$TYPE" ] && echo "Empty config value type" && exit 1
26 | [ -z "$KEY" ] && echo "Empty config key" && exit 1
27 | [ -z "$VALUE" ] && echo "Empty config value" && exit 1
28 |
29 | # Internal variables
30 | if [[ -z "${FROSTFS_NOTARY_DISABLED}" ]]; then
31 | ADDR=$(jq -r .accounts[2].address < "${WALLET}" || die "Cannot get address from ${WALLET}")
32 | else
33 | ADDR=$(jq -r .accounts[0].address < "${WALLET}" || die "Cannot get address from ${WALLET}")
34 | fi
35 |
36 | # Change config value in side chain
37 | echo "Changing ${KEY} configration value to ${VALUE}"
38 |
39 | # shellcheck disable=SC2086
40 | ${NEOGO} contract invokefunction \
41 | --wallet-config ${CONFIG_IMG} \
42 | -a ${ADDR} --force \
43 | -r http://morph-chain.${LOCAL_DOMAIN}:30333 \
44 | ${NETMAP_ADDR} \
45 | setConfig bytes:beefcafe \
46 | string:${KEY} \
47 | ${TYPE}:${VALUE} -- ${ADDR} || exit 1
48 |
49 | # Update epoch to apply new configuration value
50 | ./bin/tick.sh
51 |
--------------------------------------------------------------------------------
/bin/helper.sh:
--------------------------------------------------------------------------------
1 | set -eo pipefail
2 |
3 | die() {
4 | echo "$(caller 0):" "$*" >&2
5 | exit 1
6 | }
7 |
--------------------------------------------------------------------------------
/bin/passwd.exp:
--------------------------------------------------------------------------------
1 | #!/usr/bin/expect
2 |
3 | set passwd [lindex $argv 0]
4 | set args [lrange $argv 1 end]
5 |
6 | spawn -noecho {*}$args
7 | expect -re {^.*assword.*$}
8 |
9 | if { $passwd == "-"} {
10 | send -- "\r"
11 | } else {
12 | send -- "$passwd\r"
13 | }
14 |
15 | expect {
16 | "Relay transaction" {
17 | send "y\r"
18 | exp_continue
19 | }
20 | EOF
21 | }
22 | lassign [wait] pid spawnid os_error_flag value
23 | exit $value
24 |
--------------------------------------------------------------------------------
/bin/resolve.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Source env settings
4 | . .env
5 | source bin/helper.sh
6 |
7 | # NeoGo binary path.
8 | NEOGO="${NEOGO:-docker exec morph_chain neo-go}"
9 | # NNS contract script hash
10 | output=$(curl -s --data '{ "id": 1, "jsonrpc": "2.0", "method": "getcontractstate", "params": [1] }' \
11 | "http://morph-chain.${LOCAL_DOMAIN}:30333/") \
12 | || die "Cannot fetch NNS contract state"
13 |
14 | NNS_ADDR=$(jq -r '.result.hash' <<< "$output") \
15 | || die "Cannot parse NNS contract hash: $NNS_ADDR"
16 |
17 | ${NEOGO} contract testinvokefunction \
18 | -r "http://morph-chain.${LOCAL_DOMAIN}:30333" \
19 | "${NNS_ADDR}" resolve string:"${1}" int:16 \
20 | | jq -r '.stack[0].value | if type=="array" then .[0].value else . end' \
21 | | base64 -d \
22 | || die "Cannot invoke 'NNS.resolve' $output"
23 |
--------------------------------------------------------------------------------
/bin/tick.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | echo "Running bin/tick.sh"
4 |
5 | # Source env settings
6 | . .env
7 | . services/ir/.ir.env
8 | source bin/helper.sh
9 |
10 | # NeoGo binary path.
11 | NEOGO="${NEOGO:-docker exec morph_chain neo-go}"
12 |
13 | # Wallet files to change config value
14 | WALLET="${WALLET:-services/morph_chain/node-wallet.json}"
15 | CONFIG_IMG="${CONFIG_IMG:-/wallets/config.yml}"
16 |
17 | # Internal variables
18 | if [[ -z "${FROSTFS_NOTARY_DISABLED}" ]]; then
19 | ADDR=$(jq -r .accounts[2].address < "${WALLET}" || die "Cannot get address from ${WALLET}")
20 | else
21 | ADDR=$(jq -r .accounts[0].address < "${WALLET}" || die "Cannot get address from ${WALLET}")
22 | fi
23 |
24 | # Grep Morph block time
25 | SIDECHAIN_PROTO="${SIDECHAIN_PROTO:-services/morph_chain/protocol.privnet.yml}"
26 | BLOCK_DURATION=$(grep SecondsPerBlock < "$SIDECHAIN_PROTO" | awk '{print $2}') \
27 | || die "Cannot fetch block duration"
28 | NETMAP_ADDR=$(bin/resolve.sh netmap.frostfs) || die "Cannot resolve netmap.frostfs"
29 |
30 | # Fetch current epoch value
31 | EPOCH=$(${NEOGO} contract testinvokefunction \
32 | -r "http://morph-chain.${LOCAL_DOMAIN}:30333" "${NETMAP_ADDR}" epoch \
33 | | grep 'value' | awk -F'"' '{ print $4 }') \
34 | || die "Cannot fetch epoch from netmap contract"
35 |
36 | echo "Updating FrostFS epoch to $((EPOCH+1))"
37 |
38 | # shellcheck disable=SC2086
39 | ${NEOGO} contract invokefunction \
40 | --wallet-config ${CONFIG_IMG} \
41 | -a ${ADDR} --force \
42 | -r http://morph-chain.${LOCAL_DOMAIN}:30333 \
43 | ${NETMAP_ADDR} \
44 | newEpoch int:$((EPOCH+1)) -- ${ADDR}:Global \
45 | || die "Cannot increment an epoch"
46 |
47 | # Wait one Morph block to ensure the transaction broadcasted
48 | # shellcheck disable=SC2086
49 | sleep $BLOCK_DURATION
50 |
--------------------------------------------------------------------------------
/docs/basenet.md:
--------------------------------------------------------------------------------
1 | # basenet service
2 |
3 | The `basenet` service defines the common network to use as "Internet" to let
4 | services communicate to external world. It's a bridge network connected to the
5 | host machine, so all programs running on host can connect to services exposed to
6 | `basenet_internet` from devenv containers.
7 |
8 | ## .env settings
9 |
10 | ### LOCAL_DOMAIN=frostfs.devenv
11 |
12 | Domain to use for all containers exposed to `basenet_internet`.
13 |
14 | ### IPV4_PREFIX=192.168.130
15 |
16 | IPv4 /24 subnet to use for all containers exposed to `basenet_internet`. Last
17 | octet will be defined in `docker-compose.yml` file for each container inside
18 | service. For simplicity, each service reserves ten host addresses.
19 |
20 | ### CA_CERTS_TRUSTED_STORE=/usr/local/share/ca-certificates
21 | Trusted store location to add node self-signed tls certificates.
22 |
23 | ## bastion container
24 |
25 | There is a `bastion` container with debian 10 userspace to simplify access to
26 | devenv services.
27 |
28 | Run shell in bastion:
29 |
30 | ```
31 | frostfs-dev-env$ docker exec -ti bastion /bin/bash
32 | root@bastion:/# ip a sh
33 | 1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
34 | link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
35 | inet 127.0.0.1/8 scope host lo
36 | valid_lft forever preferred_lft forever
37 | 1569: eth0@if1570: mtu 1500 qdisc noqueue state UP group default
38 | link/ether 02:42:c0:a8:82:0a brd ff:ff:ff:ff:ff:ff link-netnsid 0
39 | inet 192.168.130.10/24 brd 192.168.130.255 scope global eth0
40 | valid_lft forever preferred_lft forever
41 | ```
42 |
--------------------------------------------------------------------------------
/docs/faq.md:
--------------------------------------------------------------------------------
1 | # F.A.Q, tips and tricks
2 |
3 |
4 | ### How to export private key from Neo wallet for FrostFS use?
5 |
6 | Private key for usage with FrostFS tools can be extracted from Neo wallet in three
7 | simple steps.
8 |
9 | 1. Get the key in WIF format
10 |
11 | ```
12 | $ docker exec -it main_chain neo-go wallet export -w wallets/wallet.json -d NbUgTSFvPmsRxmGeWpuuGeJUoRoi6PErcM
13 | Enter password >
14 | KxDgvEKzgSBPPfuVfw67oPQBSjidEiqTHURKSDL1R7yGaGYAeYnr
15 | ```
16 |
17 | 2. Convert form WIF to HEX
18 |
19 | ```
20 | $ frostfs-cli util keyer KxDgvEKzgSBPPfuVfw67oPQBSjidEiqTHURKSDL1R7yGaGYAeYnr
21 | PrivateKey 1dd37fba80fec4e6a6f13fd708d8dcb3b29def768017052f6c930fa1c5d90bbb
22 | PublicKey 031a6c6fbbdf02ca351745fa86b9ba5a9452d785ac4f7fc2b7548ca2a46c4fcf4a
23 | WIF KxDgvEKzgSBPPfuVfw67oPQBSjidEiqTHURKSDL1R7yGaGYAeYnr
24 | Wallet3.0 NbUgTSFvPmsRxmGeWpuuGeJUoRoi6PErcM
25 | ScriptHash3.0 5ea4d57ff4b09098a37db8138686ae2ef6a5b9aa
26 | ScriptHash3.0BE aab9a5f62eae868613b87da39890b0f47fd5a45e
27 | ```
28 |
29 | 3. Dump into file in binary format
30 |
31 | ```
32 | $ echo '1dd37fba80fec4e6a6f13fd708d8dcb3b29def768017052f6c930fa1c5d90bbb' | xxd -r -p > wallets/wallet.key
33 | $ xxd wallets/wallet.key
34 | 00000000: 1dd3 7fba 80fe c4e6 a6f1 3fd7 08d8 dcb3 ..........?.....
35 | 00000010: b29d ef76 8017 052f 6c93 0fa1 c5d9 0bbb ...v.../l.......
36 | ```
37 |
38 | Later you will be able to provide wallet file in frostfs-node config.
39 |
40 | ### How to create Neo wallet JSON file using a FrostFS key file?
41 |
42 | You will need `neo-go` and `frostfs-cli`.
43 |
44 | 1. Get the WIF format of the private key
45 |
46 | ```
47 | $ frostfs-cli util keyer -key ./services/ir/01.key | grep WIF | awk '{print $NF}' > temp_WIF
48 | ```
49 |
50 | 2. Init a new empty Neo wallet
51 |
52 | ```
53 | $ neo-go wallet init -w my_new_wallet.json
54 | ```
55 |
56 | 3. Import WIF to the new wallet
57 |
58 | ```
59 | $ neo-go wallet import -w my_new_wallet.json --wif $(cat temp_WIF) && rm temp_WIF
60 | Enter the name of the account >
61 | Enter passphrase >
62 | Confirm passphrase >
63 | ```
64 |
65 | ### How to see what's inside running container if there's no shell?
66 |
67 | You can run any program in container's namespace using `nsenter` utility.
68 |
69 | ```
70 | $ docker inspect -f '{{.State.Pid}}' fs.neo.org
71 | 27242
72 |
73 | $ sudo nsenter -t 27242 -n netstat -antp
74 | Active Internet connections (servers and established)
75 | Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
76 | tcp 0 0 127.0.0.11:43783 0.0.0.0:* LISTEN 1376/dockerd
77 | tcp6 0 0 :::443 :::* LISTEN 27242/nginx: master
78 | tcp6 0 0 :::80 :::* LISTEN 27242/nginx: master
79 | ```
80 |
--------------------------------------------------------------------------------
/docs/http_gate.md:
--------------------------------------------------------------------------------
1 | # HTTP Protocol gateway
2 |
3 | Protocol Gateway to access data in FrostFS using HTTP protocol.
4 |
5 | Source code and more information can be found in [project's GitHub repository](https://github.com/TrueCloudLab/frostfs-http-gate)
6 |
7 | ## .env settings
8 |
9 | ### HTTP_GW_VERSION=0.15.1
10 |
11 | Image version label to use for containers.
12 |
13 | If you want to use locally built image, just set its label here. Instead of
14 | pulling from DockerHub, the local image will be used.
15 |
16 | ### HTTP_GW_IMAGE=truecloudlab/frostfs-http-gw
17 |
18 | Image label prefix to use for containers.
19 |
20 | ## Usage example
21 |
22 | - Create a new container
23 | ```
24 | $ frostfs-cli --rpc-endpoint s01.frostfs.devenv:8080 \
25 | --key wallets/wallet.key \
26 | container create --basic-acl readonly --await \
27 | --policy "REP 1 SELECT 1 FROM *"
28 | container ID: 4LfREK1cetL4PUji5fqj9SgRTSmaC5jExEDK9HKCDjdP
29 | awaiting...
30 | container has been persisted on sidechain
31 |
32 | ```
33 | - Put an object into the newly created container
34 | ```
35 | $ frostfs-cli --rpc-endpoint s01.frostfs.devenv:8080 \
36 | --key wallets/wallet.key \
37 | object put --file /tmp/backup.jpeg \
38 | --cid 4LfREK1cetL4PUji5fqj9SgRTSmaC5jExEDK9HKCDjdP
39 | [/tmp/backup.jpeg] Object successfully stored
40 | ID: 6EPpYqSFMGWrNLvYE9mNnut1CPKuPBKyi1ixHakzqsSB
41 | CID: 4LfREK1cetL4PUji5fqj9SgRTSmaC5jExEDK9HKCDjdP
42 | ```
43 | - Call `curl -sSI -XGET http://http.frostfs.devenv/get//`
44 | ```
45 | $ curl -sSI -XGET http://http.frostfs.devenv/get/4LfREK1cetL4PUji5fqj9SgRTSmaC5jExEDK9HKCDjdP/6EPpYqSFMGWrNLvYE9mNnut1CPKuPBKyi1ixHakzqsSB
46 | HTTP/1.1 200 OK
47 | Date: Thu, 03 Dec 2020 10:34:26 GMT
48 | Content-Type: image/jpeg
49 | Content-Length: 144017
50 | x-object-id: 6EPpYqSFMGWrNLvYE9mNnut1CPKuPBKyi1ixHakzqsSB
51 | x-owner-id: NTrezR3C4X8aMLVg7vozt5wguyNfFhwuFx
52 | x-container-id: 4LfREK1cetL4PUji5fqj9SgRTSmaC5jExEDK9HKCDjdP
53 | x-FileName: backup.jpeg
54 | x-Timestamp: 1606983284
55 | Last-Modified: Thu, 03 Dec 2020 08:14:44 UTC
56 | Content-Disposition: inline; filename=backup.jpeg
57 | ```
58 |
--------------------------------------------------------------------------------
/docs/ir.md:
--------------------------------------------------------------------------------
1 | # FrostFS Inner Ring
2 |
3 | FrostFS Inner Ring (Alphabet) node. According to governance scheme, Inner Ring
4 | should contain Alphabet nodes that share key with one of side chain consensus
5 | nodes. In basic setup there is a single consensus node and single Inner Ring
6 | (Alphabet) node.
7 |
8 | ## .env settings
9 |
10 | ### IR_VERSION
11 |
12 | Image version label to use for Inner Ring docker containers.
13 |
14 | If you want to use locally built image, just set it's label here. Instead of
15 | pulling from DockerHub, the local image will be used.
16 |
17 | ### IR_IMAGE=truecloudlab/frostfs-ir
18 |
19 | Image label prefix to use for Inner Ring docker containers.
20 |
--------------------------------------------------------------------------------
/docs/macos.md:
--------------------------------------------------------------------------------
1 | # Setting up DevEnv on macOS
2 |
3 | ## The Problem
4 |
5 | Currently Docker for macOS has no support for network routing into the Host
6 | Virtual Machine that is created using hyperkit. The reason for this is due to
7 | the fact that the network interface options used to create the instance does not
8 | create a bridge interface between the Physical Machine and the Host Virtual
9 | Machine. To make matters worse, the arguments used to create the Host Virtual
10 | Machine is hardcoded into the Docker for macOS binary with no means to configure
11 | it.
12 |
13 | ## How to setup DevEnv on macOS
14 |
15 | - Clone https://github.com/AlmirKadric-Published/docker-tuntap-osx
16 | ```sh
17 | $ git clone git@github.com:AlmirKadric-Published/docker-tuntap-osx.git
18 | ```
19 |
20 | - Install tuntap for macOS
21 | ```
22 | $ brew tap caskroom/cask
23 | $ brew cask install tuntap
24 | ```
25 |
26 | - Restart macOS and allow tuntap kext in settings before
27 |
28 | - Docker for macOS should be run before
29 |
30 | - Install docker-tuntap. This will automatically check if the currently
31 | installed shim is the correct version and make a backup if necessary
32 |
33 | ```
34 | $ ./sbin/docker_tap_install.sh
35 | ```
36 |
37 | - After this you will need to bring up the network interfaces every time the
38 | docker Host Virtual Machine is restarted
39 |
40 | ```
41 | $ ./sbin/docker_tap_up.sh
42 | ```
43 |
44 | - Bootup devenv
45 |
46 | - See IPV4_PREFIX, for example, now it's
47 | ```
48 | IPV4_PREFIX=192.168.130
49 | ```
50 |
51 | - Add route to devenv (.0, for example IPV4_PREFIX=192.168.130)
52 | ```
53 | $ sudo route add -net 192.168.130.0 -netmask 255.255.255.0 10.0.75.2
54 | ```
55 |
56 | ## How to uninstall
57 |
58 | The uninstall script will simply revert the installer. Restoring the original
59 | and removing the shim:
60 |
61 | ```
62 | $ ./sbin/docker_tap_uninstall.sh
63 | ```
64 |
65 | Remove route to devenv (.0, for example IPV4_PREFIX=192.168.130)
66 | ```
67 | $ sudo route delete -net 192.168.130.0 -netmask 255.255.255.0 10.0.75.2
68 | ```
69 |
70 | ## Restart macOS or upgrade Docker for macoS
71 |
72 | When you restart macOS or install new version of Docker, you should do next
73 | steps:
74 | - reinstall docker-tuntap forced
75 | ```
76 | $ ./sbin/docker_tap_install.sh -f
77 | ```
78 |
79 | - wait until docker will be restarted
80 |
81 | - up tuntap interface
82 | ```
83 | $ ./sbin/docker_tap_up.sh
84 | ```
85 |
86 | - bootup devenv
87 |
88 | - Add route to devenv (.0, for example IPV4_PREFIX=192.168.130)
89 | ```
90 | $ sudo route add -net 192.168.130.0 -netmask 255.255.255.0 10.0.75.2
91 | ```
92 |
93 | ## How it works
94 |
95 | This installer (`docker_tap_install.sh`) will move the original hyperkit binary
96 | (`hyperkit.original`) inside the Docker for macOS application and places our shim
97 | (`./sbin/docker.hyperkit.tuntap.sh`) in it's stead. This shim will then inject
98 | the additional arguments required to attach a
99 | [TunTap](http://tuntaposx.sourceforge.net/) interface into the Host Virtual
100 | Machine, creating a bridge interface between the guest and the host (this is
101 | essentially what hvint0 is on Docker for Windows).
102 |
103 | From there the `up` script (`docker_tap_up.sh`) is used to bring the network
104 | interface up on both the Physical Machine and the Host Virtual Machine. Unlike
105 | the install script, which only needs to be run once, this `up` script must be
106 | run for every restart of the Host Virtual Machine.
107 |
108 | Once done, the IP address `10.0.75.2` can be used as a network routing gateway
109 | to reach any containers within the Host Virtual Machine:
110 |
111 | ```
112 | $ route add -net -netmask 10.0.75.2
113 | ```
114 |
115 | **Note:** Although as of docker-for-mac version `17.12.0` you do not need the
116 | following, for prior versions you will need to setup IP Forwarding in the
117 | iptables defintion on the Host Virtual Machine:
118 |
119 | (This is not done by the helpers as this is not a OSX or tuntap specific issue.
120 | You would need to do the same for Docker for Windows, as such it should be
121 | handled outside the scope of this project.)
122 |
123 | ```
124 | $ docker run --rm --privileged --pid=host debian nsenter -t 1 -m -u -n -i iptables -A FORWARD -i eth1 -j ACCEPT
125 | ```
126 |
127 | **Note:** Although not required for docker-for-mac versions greater than
128 | `17.12.0`, the above command can be replaced with the following if ever needed
129 | and is tested to be working on Docker for Windwos as an alternative. This is in
130 | case Docker for macOS changes something in future and this command ends up being a
131 | necessity once again.
132 |
133 | ```
134 | $ docker run --rm --privileged --pid=host docker4w/nsenter-dockerd /bin/sh -c 'iptables -A FORWARD -i eth1 -j ACCEPT'
135 | ```
136 |
137 | ## Dependencies
138 | - [Docker for Mac](https://www.docker.com/docker-mac)
139 | - [TunTap](http://tuntaposx.sourceforge.net/)
140 | - [Docker TunTap](https://github.com/AlmirKadric-Published/docker-tuntap-osx)
141 |
--------------------------------------------------------------------------------
/docs/morph.md:
--------------------------------------------------------------------------------
1 | # N3 FrostFS side chain privnet service
2 | A single-node N3 privnet deployment, running on
3 | [neo-go](https://github.com/nspcc-dev/neo-go). Represents N3 FrostFS SideChain.
4 |
5 | Contracts deployed:
6 | - Alphabet (AZ) [contract](https://github.com/TrueCloudLab/frostfs-contract/tree/master/alphabet)
7 | - Audit [contract](https://github.com/TrueCloudLab/frostfs-contract/tree/master/audit)
8 | - Balance [contract](https://github.com/TrueCloudLab/frostfs-contract/tree/master/balance)
9 | - Container [contract](https://github.com/TrueCloudLab/frostfs-contract/tree/master/container)
10 | - Netmap [contract](https://github.com/TrueCloudLab/frostfs-contract/tree/master/netmap)
11 | - NeoFSID [contract](https://github.com/TrueCloudLab/frostfs-contract/tree/master/neofsid)
12 | - Proxy [contract](https://github.com/TrueCloudLab/frostfs-contract/tree/master/proxy)
13 | - Reputation [contract](https://github.com/TrueCloudLab/frostfs-contract/tree/master/reputation)
14 |
15 | RPC available at `http://morph-chain.frostfs.devenv:30333`.
16 |
17 | ## .env settings
18 |
19 | ### MORPH_CHAIN_URL
20 |
21 | URL to get side chain dump. Used on artifact get stage.
22 |
23 | ### MORPH_CHAIN_PATH
24 |
25 | Path to get side chain dump. If set, overrides `CHAIN_URL`.
26 |
27 | ### NEOGO_VERSION
28 |
29 | Version of neo-go docker container for side chain deployment.
30 |
31 | ## Side chain wallets
32 |
33 | There is a wallet with GAS that used for contract deployment:
34 | `wallets/wallet.json`. This wallet has one account with **empty password**.
35 |
36 | ```
37 | $ neo-go wallet nep17 balance \
38 | -w wallets/wallet.json \
39 | -r http://morph-chain.frostfs.devenv:30333
40 |
41 | Account NbUgTSFvPmsRxmGeWpuuGeJUoRoi6PErcM
42 | GAS: GasToken (d2a4cff31913016155e38e474a2c06d08be276cf)
43 | Amount : 189826.0515316
44 | Updated: 3909
45 | FROSTFS: FrostFS Balance (69550190e740b93f92dbd5dea52246f550391057)
46 | Amount : 50
47 | Updated: 3909
48 | ```
49 |
50 | This way you can also monitor FrostFS internal balance of your account.
51 |
52 | ## FrostFS global config
53 |
54 | FrostFS uses global configuration to store epoch duration, maximum object size,
55 | container fee and other network parameters. Global configuration is stored in
56 | netmap contract and managed by Inner Ring (Alphabet) nodes.
57 |
58 | To change these parameters use `make update.*` commands. Command down below
59 | changes epoch duration from 300 blocks (about 300 seconds with 1bps) to 30.
60 | Script enters passwords automatically with `expect` utility.
61 |
62 | ```
63 | $ make update.epoch_duration val=30
64 | Changing EpochDuration configration value to 30
65 | Enter account NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP password >
66 | Sent invocation transaction bdc0fa88cd6719ef6df2b9c82de423ddec6141ca24255c2d0072688083b1de9d
67 | Updating FrostFS epoch to 20
68 | Enter account NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP password >
69 | Sent invocation transaction 12296e1ce24dd6c04edb9c56d0a1d0e26d3226adefb0333c74a28788f44a8d0f
70 | ```
71 |
72 | Read more about available configuration in Makefile help.
73 |
74 | ```
75 | $ make help
76 | ...
77 | Targets:
78 | ...
79 | update.audit_fee Update audit fee per result in fixed 12 (make update.audit_fee val=100)
80 | update.basic_income_rate Update basic income rate in fixed 12 (make update.basic_income_rate val=1000)
81 | update.container_fee Update container fee per alphabet node in fixed 12 (make update.container_fee val=500)
82 | update.eigen_trust_iterations Update amount of EigenTrust iterations (make update.eigen_trust_iterations val=2)
83 | update.epoch_duration Update epoch duration in side chain blocks (make update.epoch_duration val=30)
84 | update.max_object_size Update max object size in bytes (make update.max_object_size val=1000)
85 | ```
86 |
--------------------------------------------------------------------------------
/docs/notary.md:
--------------------------------------------------------------------------------
1 | # Notary service in chains
2 |
3 | [Notary service](https://github.com/neo-project/neo/issues/1573#issuecomment-704874472)
4 | is a service that provides on-chain network assistance to form multisignature
5 | transactions. Inner Ring (Alphabet) nodes use multisignature transactions to
6 | create containers, approve balance changes, update network map, tick epochs,
7 | etc. With notary service, it takes up to seven times fewer transactions
8 | to do these operations. Notary service calculates the exact amount of GAS
9 | to execute transaction, therefore operations are cheaper (withdraw fee **with**
10 | notary is less than 0.5 GAS; withdraw fee **without** notary is up to 7.0 GAS).
11 |
12 | By default, main chain service is running without notary service, and side chain
13 | running with notary service. However, you can change that in configuration.
14 |
15 | # Disable notary service in side chain
16 |
17 | To disable notary service in side chain do these steps.
18 |
19 | 1. Update `.env` and choose notary disabled chain dump for side chain.
20 |
21 | ```
22 | MORPH_CHAIN_URL="https://github.com/nspcc-dev/neofs-contract/releases/download/v0.9.0/devenv_sidechain_notary_disabled.gz"
23 | ```
24 |
25 | Make sure to update chain dump files with `make get` target.
26 |
27 | 2. Update `service/morph_chain/protocol.privnet.yml` and disable notary settings
28 | and state root in header.
29 |
30 | ```yaml
31 | ProtocolConfiguration:
32 | StateRootInHeader: false
33 | P2PSigExtensions: false
34 | ApplicationConfiguration:
35 | P2PNotary:
36 | Enabled: false
37 | ```
38 |
39 | Chain dump without notary service does not have predefined network map.
40 | Therefore, you need to wait about 5 minutes until new epoch tick with updated
41 | network map.
42 |
43 |
44 | 3. Enable helper commands
45 |
46 | To enable helper commands such as `make tick.epoch` or `make update.epoch_duration`
47 | make sure to export non-empty `FROSTFS_NOTARY_DISABLED` environment variable.
48 | ```
49 | $ export FROSTFS_NOTARY_DISABLED=1
50 | ```
51 |
52 | Use `unset` command to return it back.
53 | ```
54 | $ unset FROSTFS_NOTARY_DISABLED
55 | ```
56 |
57 | # Enable notary service in main chain
58 |
59 | To enable notary service in main chain do these steps.
60 |
61 | 1. Update `.env` and choose notary enabled chain dump for main chain.
62 |
63 | ```
64 | CHAIN_URL="https://github.com/nspcc-dev/neofs-contract/releases/download/v0.9.0/devenv_mainchain.gz"
65 | ```
66 |
67 | Make sure to update chain dump files with `make get` target.
68 |
69 | 2. Update `service/chain/protocol.privnet.yml` and enable notary settings.
70 |
71 | ```yaml
72 | ProtocolConfiguration:
73 | P2PSigExtensions: true
74 | ApplicationConfiguration:
75 | P2PNotary:
76 | Enabled: true
77 | ```
78 |
79 | Main chain generates a block once per 15 seconds, so Inner Ring takes about
80 | 15-30 seconds to make a notary deposit in main chain after startup. Then
81 | frostfs-dev-env is ready to work.
82 |
--------------------------------------------------------------------------------
/docs/rest_gate.md:
--------------------------------------------------------------------------------
1 | # REST Gateway
2 |
3 | REST Gateway to access data in FrostFS using REST.
4 |
5 | Source code and more information can be found in [project's GitHub repository](https://github.com/TrueCloudLab/frostfs-rest-gw)
6 |
7 | ## .env settings
8 |
9 | ### REST_GW_VERSION=0.4.0
10 |
11 | Image version label to use for containers.
12 |
13 | If you want to use locally built image, just set its label here.
14 | Instead of pulling from DockerHub, the local image will be used.
15 |
16 | ### REST_GW_IMAGE=truecloudlab/frostfs-rest-gw
17 |
18 | Image label prefix to use for containers.
19 |
20 | ## Usage example
21 |
22 | - List container for specific owner:
23 |
24 | ```shell
25 | $ curl http://rest.frostfs.devenv:8090/v1/containers?ownerId=NbUgTSFvPmsRxmGeWpuuGeJUoRoi6PErcM | jq
26 | {
27 | "containers": [
28 | {
29 | "attributes": [
30 | {
31 | "key": "Timestamp",
32 | "value": "1663755230"
33 | }
34 | ],
35 | "basicAcl": "fbfbfff",
36 | "cannedAcl": "eacl-public-read-write",
37 | "containerId": "BKcAvz8awKKy9NGsGKi1Hoxxu9AjTGvjKMNMQamvdLmX",
38 | "containerName": "",
39 | "ownerId": "NbUgTSFvPmsRxmGeWpuuGeJUoRoi6PErcM",
40 | "placementPolicy": "REP 1 IN X\nCBF 1\nSELECT 1 FROM * AS X",
41 | "version": "v2.13"
42 | }
43 | ],
44 | "size": 1
45 | }
46 | ```
47 |
48 |
49 | - Get container info:
50 |
51 | ```shell
52 | $ curl http://rest.frostfs.devenv:8090/v1/containers/BKcAvz8awKKy9NGsGKi1Hoxxu9AjTGvjKMNMQamvdLmX | jq
53 | {
54 | "attributes": [
55 | {
56 | "key": "Timestamp",
57 | "value": "1663755230"
58 | }
59 | ],
60 | "basicAcl": "fbfbfff",
61 | "cannedAcl": "eacl-public-read-write",
62 | "containerId": "BKcAvz8awKKy9NGsGKi1Hoxxu9AjTGvjKMNMQamvdLmX",
63 | "containerName": "",
64 | "ownerId": "NbUgTSFvPmsRxmGeWpuuGeJUoRoi6PErcM",
65 | "placementPolicy": "REP 1 IN X\nCBF 1\nSELECT 1 FROM * AS X",
66 | "version": "v2.13"
67 | }
68 | ```
69 |
70 | See all available routes http://rest.frostfs.devenv:8090/v1/docs
71 |
--------------------------------------------------------------------------------
/docs/s3_gate.md:
--------------------------------------------------------------------------------
1 | # S3 Protocol gateway
2 |
3 | Protocol Gateway to access data in FrostFS using AWS S3 protocol
4 |
5 | Source code and more information can be found in [project's GitHub repository](https://github.com/TrueCloudLab/frostfs-s3-gw)
6 |
7 | ## .env settings
8 |
9 | ### S3_GW_VERSION=0.12.0
10 |
11 | Image version label to use for containers.
12 |
13 | If you want to use locally built image, just set its label here. Instead of
14 | pulling from DockerHub, the local image will be used.
15 |
16 | ### S3_GW_IMAGE=truecloudlab/frostfs-s3-gw
17 |
18 | Image label prefix to use for containers.
19 |
--------------------------------------------------------------------------------
/docs/storage.md:
--------------------------------------------------------------------------------
1 | # Storage service
2 |
3 | ## .env settings
4 |
5 | ### NODE_VERSION
6 |
7 | Image version label to use for Storage docker containers.
8 |
9 | If you want to use locally built image, just set its label here. Instead of
10 | pulling from DockerHub, the local image will be used.
11 |
12 | ### NODE_IMAGE=truecloudlab/frostfs-ir
13 |
14 | Image label prefix to use for Storage docker containers.
15 |
--------------------------------------------------------------------------------
/frostfs-adm.yml:
--------------------------------------------------------------------------------
1 | rpc-endpoint: http://morph-chain.frostfs.devenv:30333
2 | network:
3 | max_object_size: 67108864
4 | epoch_duration: 240
5 | basic_income_rate: 100000000
6 | homomorphic_hash_disabled: false
7 | fee:
8 | audit: 10000
9 | candidate: 10000000000
10 | container: 0
11 | container_alias: 0
12 | withdraw: 100000000
13 | credentials:
14 | az: "one"
15 | contract: "one"
16 |
--------------------------------------------------------------------------------
/frostfs_config.mk:
--------------------------------------------------------------------------------
1 | # Update epoch duration in side chain blocks (make update.epoch_duration val=30)
2 | update.epoch_duration:
3 | @./bin/config.sh int EpochDuration $(val)
4 |
5 | # Update max object size in bytes (make update.max_object_size val=1000)
6 | update.max_object_size:
7 | @./bin/config.sh int MaxObjectSize $(val)
8 |
9 | # Update audit fee per result in fixed 12 (make update.audit_fee val=100)
10 | update.audit_fee:
11 | @./bin/config.sh int AuditFee $(val)
12 |
13 | # Update container fee per alphabet node in fixed 12 (make update.container_fee val=500)
14 | update.container_fee:
15 | @./bin/config.sh int ContainerFee $(val)
16 |
17 | # Update container alias fee per alphabet node in fixed 12 (make update.container_alias_fee val=100)
18 | update.container_alias_fee:
19 | @./bin/config.sh int ContainerAliasFee $(val)
20 |
21 | # Update amount of EigenTrust iterations (make update.eigen_trust_iterations val=2)
22 | update.eigen_trust_iterations:
23 | @./bin/config.sh int EigenTrustIterations $(val)
24 |
25 |
26 | # Update system dns to resolve container names (make update.system_dns val=container)
27 | update.system_dns:
28 | @./bin/config.sh string SystemDNS $(val)
29 |
30 | # Update alpha parameter of EigenTrust algorithm in 0 <= f <= 1.0 (make update.eigen_trust_alpha val=0.2)
31 | update.eigen_trust_alpha:
32 | @./bin/config.sh string EigenTrustAlpha $(val)
33 |
34 | # Update basic income rate in fixed 12 (make update.basic_income_rate val=1000)
35 | update.basic_income_rate:
36 | @./bin/config.sh int BasicIncomeRate $(val)
37 |
38 | # Update homomorphic hashing disabled flag (make update.homomorphic_hashing_disable val=true)
39 | update.homomorphic_hashing_disable:
40 | @./bin/config.sh bool HomomorphicHashingDisabled $(val)
41 |
42 | # Tick new epoch in side chain
43 | tick.epoch:
44 | @./bin/tick.sh
45 |
--------------------------------------------------------------------------------
/help.mk:
--------------------------------------------------------------------------------
1 | .PHONY: help
2 |
3 | HELP_MAKEFILE_LIST=$(filter-out %/artifacts.mk, $(MAKEFILE_LIST))
4 |
5 | # Show this help prompt
6 | help:
7 | @echo ' Usage:'
8 | @echo ''
9 | @echo ' make '
10 | @echo ''
11 | @echo ' Targets:'
12 | @echo ''
13 | @awk '/^#/{ comment = substr($$0,3) } comment && /^[a-zA-Z][a-zA-Z0-9._/-]+ ?:/{ print " ", $$1, comment }' $(HELP_MAKEFILE_LIST) | column -t -s ':' | grep -v 'IGNORE' | sort -u
14 |
--------------------------------------------------------------------------------
/services/basenet/.env:
--------------------------------------------------------------------------------
1 | ../../.env
--------------------------------------------------------------------------------
/services/basenet/.hosts:
--------------------------------------------------------------------------------
1 | IPV4_PREFIX.10 bastion.LOCAL_DOMAIN
2 |
--------------------------------------------------------------------------------
/services/basenet/.int_test.env:
--------------------------------------------------------------------------------
1 | ../../.int_test.env
--------------------------------------------------------------------------------
/services/basenet/docker-compose.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | version: "2.4"
4 | services:
5 |
6 | basenet:
7 | container_name: bastion
8 | image: ${BASTION_IMAGE}:${BASTION_VERSION}
9 | domainname: ${LOCAL_DOMAIN}
10 | hostname: bastion
11 | command: ["/bin/sleep", "infinity"]
12 | restart: always
13 | stop_signal: SIGKILL
14 | env_file: [ ".int_test.env" ]
15 | environment:
16 | - TZ=Etc/UTC
17 | networks:
18 | internet:
19 | ipv4_address: ${IPV4_PREFIX}.10
20 | volumes:
21 | - ./../../vendor/hosts:/etc/hosts
22 | networks:
23 | internet:
24 | driver: bridge
25 | ipam:
26 | driver: default
27 | config:
28 | - subnet: ${IPV4_PREFIX}.0/24
29 |
--------------------------------------------------------------------------------
/services/http_gate/.env:
--------------------------------------------------------------------------------
1 | ../../.env
--------------------------------------------------------------------------------
/services/http_gate/.hosts:
--------------------------------------------------------------------------------
1 | IPV4_PREFIX.81 http.LOCAL_DOMAIN
2 |
--------------------------------------------------------------------------------
/services/http_gate/.http.env:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrueCloudLab/frostfs-dev-env/37507199e2909ee0ca0cd10703f9f9622e1315b0/services/http_gate/.http.env
--------------------------------------------------------------------------------
/services/http_gate/.int_test.env:
--------------------------------------------------------------------------------
1 | ../../.int_test.env
--------------------------------------------------------------------------------
/services/http_gate/cfg/config.yml:
--------------------------------------------------------------------------------
1 | logger:
2 | level: debug
3 |
4 | rebalance_timer: 5m # Interval to check nodes health
5 |
6 | connect_timeout: 60s # Timeout to dial node
7 |
8 | request_timeout: 300s # Timeout to check node health during rebalance
9 |
10 | # The order in which resolvers are used to find an container id by name
11 | resolve_order:
12 | - nns
13 |
14 | server:
15 | - address: 0.0.0.0:80
16 |
17 | # Wallet settings
18 | wallet:
19 | path: /wallet.json # Path to wallet
20 | passphrase: one # Passphrase to decrypt wallet
21 |
--------------------------------------------------------------------------------
/services/http_gate/docker-compose.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | version: "2.4"
4 | services:
5 | http_gate:
6 | image: ${HTTP_GW_IMAGE}:${HTTP_GW_VERSION}
7 | domainname: ${LOCAL_DOMAIN}
8 | hostname: http_gate
9 | container_name: http_gate
10 | restart: on-failure
11 | networks:
12 | http_gate_int:
13 | internet:
14 | ipv4_address: ${IPV4_PREFIX}.81
15 | volumes:
16 | - ./wallet.json:/wallet.json
17 | - ./../../vendor/hosts:/etc/hosts
18 | - ./cfg:/etc/frostfs/http
19 | stop_signal: SIGKILL
20 | env_file: [ ".env", ".http.env", ".int_test.env" ]
21 | command: [ "frostfs-http-gw", "--config", "/etc/frostfs/http/config.yml" ]
22 | environment:
23 | - HTTP_GW_RPC_ENDPOINT=http://morph-chain.${LOCAL_DOMAIN}:30333
24 | - HTTP_GW_PEERS_0_ADDRESS=s01.${LOCAL_DOMAIN}:8080
25 | - HTTP_GW_PEERS_0_WEIGHT=0.2
26 | - HTTP_GW_PEERS_1_ADDRESS=s02.${LOCAL_DOMAIN}:8080
27 | - HTTP_GW_PEERS_1_WEIGHT=0.2
28 | - HTTP_GW_PEERS_2_ADDRESS=s03.${LOCAL_DOMAIN}:8080
29 | - HTTP_GW_PEERS_2_WEIGHT=0.2
30 | - HTTP_GW_PEERS_3_ADDRESS=s04.${LOCAL_DOMAIN}:8080
31 | - HTTP_GW_PEERS_3_WEIGHT=0.2
32 |
33 | networks:
34 | http_gate_int:
35 | internet:
36 | external: true
37 | name: basenet_internet
38 |
--------------------------------------------------------------------------------
/services/http_gate/node.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrueCloudLab/frostfs-dev-env/37507199e2909ee0ca0cd10703f9f9622e1315b0/services/http_gate/node.key
--------------------------------------------------------------------------------
/services/http_gate/wallet.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "3.0",
3 | "accounts": [
4 | {
5 | "address": "NXCvzXiodftxHHNQBzvQ6EwG8xfn5kmnbj",
6 | "key": "6PYXfN6BwDsQ8YnUBh32NX9J4241c1cits3wDWJoCMSqpJ7J9TxARcfQYv",
7 | "label": "http-gw",
8 | "contract": {
9 | "script": "DCEDGmD8vsOtF5JojjPiUv5LTDuo0nlvrCwR/iHdm9IpLhtBVuezJw==",
10 | "parameters": [
11 | {
12 | "name": "parameter0",
13 | "type": "Signature"
14 | }
15 | ],
16 | "deployed": false
17 | },
18 | "lock": false,
19 | "isDefault": false
20 | }
21 | ],
22 | "scrypt": {
23 | "n": 16384,
24 | "r": 8,
25 | "p": 8
26 | },
27 | "extra": {
28 | "Tokens": null
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/services/ir/.env:
--------------------------------------------------------------------------------
1 | ../../.env
--------------------------------------------------------------------------------
/services/ir/.hosts:
--------------------------------------------------------------------------------
1 | IPV4_PREFIX.61 ir01.LOCAL_DOMAIN
2 |
--------------------------------------------------------------------------------
/services/ir/.int_test.env:
--------------------------------------------------------------------------------
1 | ../../.int_test.env
--------------------------------------------------------------------------------
/services/ir/.ir.env:
--------------------------------------------------------------------------------
1 | FROSTFS_IR_CONTRACTS_FROSTFSID=1943e9bb78a0fe2fe0c95fd2677eec2da6aa4aa5
2 |
3 | FROSTFS_IR_CONTROL_GRPC_ENDPOINT=127.0.0.1:16512
4 |
--------------------------------------------------------------------------------
/services/ir/artifacts.mk:
--------------------------------------------------------------------------------
1 | # Get FrostFS IR artifacts (LOCODE database and FrostFS CLI)
2 |
3 | LOCODE_DB_ARCHIVE_PATH=./vendor
4 | LOCODE_DB_ARCHIVE_FILE=locode_db.gz
5 |
6 | get.ir: get.locode get.cli
7 |
8 | # Get FrostFS LOCODE database
9 | get.locode: LOCODE_DB_PATH?=
10 | get.locode:
11 | @mkdir -p ${LOCODE_DB_ARCHIVE_PATH}
12 |
13 | ifeq (${LOCODE_DB_PATH},)
14 | @echo "⇒ Download FrostFS LOCODE database from ${LOCODE_DB_URL}"
15 | @curl \
16 | -sSL "${LOCODE_DB_URL}" \
17 | -o ${LOCODE_DB_ARCHIVE_PATH}/${LOCODE_DB_ARCHIVE_FILE}
18 | else
19 | @echo "⇒ Copy local archive of FrostFS LOCODE database from ${LOCODE_DB_PATH}"
20 | @cp ${LOCODE_DB_PATH} ${LOCODE_DB_ARCHIVE_PATH}/${LOCODE_DB_ARCHIVE_FILE}
21 | endif
22 |
23 | gzip -dfk ${LOCODE_DB_ARCHIVE_PATH}/${LOCODE_DB_ARCHIVE_FILE}
24 |
25 | # Download FrostFS CLI
26 | .ONESHELL:
27 | get.cli: FROSTFS_CLI_FILE=./vendor/frostfs-cli
28 | get.cli: FROSTFS_CLI_ARCHIVE_FILE=${FROSTFS_CLI_FILE}.tar.gz
29 | get.cli: FROSTFS_CLI_PATH?=
30 | get.cli:
31 | @mkdir -p ./vendor
32 |
33 | ifeq (${FROSTFS_CLI_PATH},)
34 | @echo "⇒ Download FrostFS CLI binary from ${FROSTFS_CLI_URL}"
35 | @curl \
36 | -ksSL "${FROSTFS_CLI_URL}" \
37 | -o ${FROSTFS_CLI_ARCHIVE_FILE}
38 | @tar -xvf ${FROSTFS_CLI_ARCHIVE_FILE} -C ./vendor | xargs -I {} \
39 | mv ./vendor/{} ${FROSTFS_CLI_FILE}
40 | @rm ${FROSTFS_CLI_ARCHIVE_FILE}
41 | else
42 | @echo "⇒ Copy local binary from ${FROSTFS_CLI_PATH}"
43 | @cp ${FROSTFS_CLI_PATH} ${FROSTFS_CLI_FILE}
44 | endif
45 |
--------------------------------------------------------------------------------
/services/ir/az.json:
--------------------------------------------------------------------------------
1 | ../morph_chain/node-wallet.json
--------------------------------------------------------------------------------
/services/ir/az.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrueCloudLab/frostfs-dev-env/37507199e2909ee0ca0cd10703f9f9622e1315b0/services/ir/az.key
--------------------------------------------------------------------------------
/services/ir/cfg/config.yml:
--------------------------------------------------------------------------------
1 | # Logger section
2 | logger:
3 | level: debug # Minimum enabled logging level
4 |
5 | # Wallet settings
6 | wallet:
7 | path: /wallet.json # Path to NEP-6 NEO wallet file
8 | address: Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn # Account address in the wallet; ignore to use default address
9 | password: one # Account password in the wallet
10 |
11 | # Profiler section
12 | pprof:
13 | enabled: true
14 | address: :6060 # Endpoint for application pprof profiling; disabled by default
15 | shutdown_timeout: 30s # Timeout for profiling HTTP server graceful shutdown
16 |
17 | # Application metrics section
18 | prometheus:
19 | enabled: true
20 | address: :9090 # Endpoint for application prometheus metrics; disabled by default
21 | shutdown_timeout: 30s # Timeout for metrics HTTP server graceful shutdown
22 |
23 | # Toggling the sidechain-only mode
24 | without_mainnet: true
25 |
26 | # Neo main chain RPC settings
27 | mainnet:
28 | endpoint:
29 | client: # List of websocket RPC endpoints in mainchain; ignore if mainchain is disabled
30 | - address: ws://main-chain:30333/ws
31 |
32 | # Neo side chain RPC settings
33 | morph:
34 | endpoint:
35 | client: # List of websocket RPC endpoints in sidechain
36 | - address: ws://morph-chain:30333/ws
37 | validators: # List of hex-encoded 33-byte public keys of sidechain validators to vote for at application startup
38 | - 02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2
39 |
40 | # Network time settings
41 | timers:
42 | emit: 50 # Number of sidechain blocks between GAS emission cycles; disabled by default
43 | stop_estimation:
44 | mul: 1 # Multiplier in x/y relation of when to stop basic income estimation within the epoch
45 | div: 4 # Divider in x/y relation of when to stop basic income estimation within the epoch
46 | collect_basic_income:
47 | mul: 1 # Multiplier in x/y relation of when to start basic income asset collection within the epoch
48 | div: 2 # Divider in x/y relation of when to start basic income asset collecting within the epoch
49 | distribute_basic_income:
50 | mul: 3 # Multiplier in x/y relation of when to start basic income asset distribution within the epoch
51 | div: 4 # Divider in x/y relation of when to start basic income asset distribution within the epoch
52 |
53 | # Storage node GAS emission settings
54 | emit:
55 | storage:
56 | amount: 1000000000 # Fixed8 value of sidechain GAS emitted to all storage nodes once per GAS emission cycle; disabled by default
57 |
58 | # Storage node removal settings
59 | netmap_cleaner:
60 | enabled: true # Enable voting for removing stale storage nodes from network map
61 | threshold: 3 # Number of FrostFS epoch without bootstrap request from storage node before it considered stale
62 |
63 | # Audit settings
64 | audit:
65 | pdp:
66 | max_sleep_interval: 100ms # Maximum timeout between object.RangeHash requests to the storage node
67 |
68 | # Settlement settings
69 | settlement:
70 | basic_income_rate: 100000000 # Optional: override basic income rate value from network config; applied only in debug mode
71 | audit_fee: 100000 # Optional: override audit fee value from network config; applied only in debug mode
72 |
73 | # LOCODE database
74 | locode:
75 | db:
76 | path: /locode/db # Path to UN/LOCODE database file
77 |
--------------------------------------------------------------------------------
/services/ir/contract.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "3.0",
3 | "accounts": [
4 | {
5 | "address": "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn",
6 | "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY",
7 | "label": "",
8 | "contract": {
9 | "script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBVuezJw==",
10 | "parameters": [
11 | {
12 | "name": "parameter0",
13 | "type": "Signature"
14 | }
15 | ],
16 | "deployed": false
17 | },
18 | "lock": false,
19 | "isDefault": false
20 | }
21 | ],
22 | "scrypt": {
23 | "n": 16384,
24 | "r": 8,
25 | "p": 8
26 | },
27 | "extra": {
28 | "Tokens": null
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/services/ir/docker-compose.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | version: "2.4"
4 | services:
5 |
6 | ir01:
7 | image: ${IR_IMAGE}:${IR_VERSION}
8 | domainname: ${LOCAL_DOMAIN}
9 | hostname: ir01
10 | container_name: ir01
11 | restart: on-failure
12 | networks:
13 | ir_int:
14 | internet:
15 | ipv4_address: ${IPV4_PREFIX}.61
16 | stop_signal: SIGKILL
17 | volumes:
18 | - ./az.json:/wallet.json
19 | - ./az.key:/wallet01.key
20 | - ./../../vendor/hosts:/etc/hosts
21 | - ./../../vendor/locode_db:/locode/db
22 | - ./../../vendor/frostfs-cli:/frostfs-cli
23 | - ./healthcheck.sh:/healthcheck.sh
24 | - ./cfg:/etc/frostfs/ir
25 | env_file: [ ".env", ".ir.env", ".int_test.env" ]
26 | command: [ "frostfs-ir", "--config", "/etc/frostfs/ir/config.yml" ]
27 | healthcheck:
28 | test: ["CMD-SHELL", "/healthcheck.sh"]
29 | interval: 2s
30 | timeout: 1s
31 | retries: 5
32 | start_period: 20s
33 |
34 | ir-healthcheck:
35 | container_name: ir-healthcheck
36 | image: debian:10
37 | depends_on:
38 | ir01:
39 | condition: service_healthy
40 |
41 | networks:
42 | ir_int:
43 | internet:
44 | external: true
45 | name: basenet_internet
46 |
--------------------------------------------------------------------------------
/services/ir/healthcheck.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | /frostfs-cli control healthcheck \
4 | --endpoint "$FROSTFS_IR_CONTROL_GRPC_ENDPOINT" \
5 | --wallet /wallet01.key --ir |
6 | grep "Health status: READY"
7 |
--------------------------------------------------------------------------------
/services/ir/prepare.mk:
--------------------------------------------------------------------------------
1 | # Deposit GAS from default wallet to FrostFS privnet contract
2 | prepare.ir:
3 | @./bin/config.sh int ContainerFee 0
4 | @./bin/config.sh int ContainerAliasFee 0
5 |
--------------------------------------------------------------------------------
/services/morph_chain/.env:
--------------------------------------------------------------------------------
1 | ../../.env
--------------------------------------------------------------------------------
/services/morph_chain/.hosts:
--------------------------------------------------------------------------------
1 | IPV4_PREFIX.90 morph-chain.LOCAL_DOMAIN
2 |
--------------------------------------------------------------------------------
/services/morph_chain/.int_test.env:
--------------------------------------------------------------------------------
1 | ../../.int_test.env
--------------------------------------------------------------------------------
/services/morph_chain/artifacts.mk:
--------------------------------------------------------------------------------
1 | # Download FrostFS Contracts and Adm tool to deploy environment
2 |
3 | get.morph_chain: get.contracts get.adm
4 |
5 | # Download FrostFS Contracts
6 | get.contracts: FROSTFS_CONTRACTS_DEST=./vendor/contracts
7 | get.contracts: FROSTFS_CONTRACTS_ARCHIVE=frostfs-contracts.tar.gz
8 | get.contracts:
9 | @mkdir -p ${FROSTFS_CONTRACTS_DEST}
10 |
11 | ifeq (${FROSTFS_CONTRACTS_PATH},)
12 | @echo "⇒ Download compiled FrostFS contracts from ${FROSTFS_CONTRACTS_URL}"
13 | @curl -ksSL ${FROSTFS_CONTRACTS_URL} -o ${FROSTFS_CONTRACTS_ARCHIVE}
14 | @tar -xf ${FROSTFS_CONTRACTS_ARCHIVE} -C ${FROSTFS_CONTRACTS_DEST} --strip-components 1
15 | @rm ${FROSTFS_CONTRACTS_ARCHIVE}
16 | else
17 | @echo "⇒ Copy compiled contracts from ${FROSTFS_CONTRACTS_PATH}"
18 | @cp -r ${FROSTFS_CONTRACTS_PATH}/* ${FROSTFS_CONTRACTS_DEST}
19 | endif
20 |
21 | # Download FrostFS ADM tool
22 | get.adm: FROSTFS_ADM_DEST=./vendor/frostfs-adm
23 | get.adm: FROSTFS_ADM_ARCHIVE=frostfs-adm.tar.gz
24 | get.adm:
25 |
26 | ifeq (${FROSTFS_ADM_PATH},)
27 | @echo "⇒ Download FrostFS ADM binary from ${FROSTFS_ADM_URL}"
28 | @curl -skSL ${FROSTFS_ADM_URL} -o ${FROSTFS_ADM_ARCHIVE}
29 | @tar -xvf ${FROSTFS_ADM_ARCHIVE} -C ./vendor | xargs -I {} \
30 | mv ./vendor/{} ${FROSTFS_ADM_DEST}
31 | @rm ${FROSTFS_ADM_ARCHIVE}
32 | else
33 | @echo "⇒ Copy frostfs-adm binary from ${FROSTFS_ADM_PATH}"
34 | @cp ${FROSTFS_ADM_PATH} ${FROSTFS_ADM_DEST}
35 | endif
36 |
--------------------------------------------------------------------------------
/services/morph_chain/config.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | Path: "/wallets/node-wallet.json"
4 | Password: "one"
5 |
--------------------------------------------------------------------------------
/services/morph_chain/docker-compose.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | version: "2.4"
4 | services:
5 | frostfs_morph_chain:
6 | image: ${NEOGO_IMAGE}:${NEOGO_VERSION}
7 | container_name: morph_chain
8 | command: ["node", "--config-path", "/config", "--privnet", "--debug"]
9 | domainname: ${LOCAL_DOMAIN}
10 | hostname: morph-chain
11 | networks:
12 | chain_int:
13 | internet:
14 | ipv4_address: ${IPV4_PREFIX}.90
15 | stop_signal: SIGKILL
16 | env_file: [ ".int_test.env" ]
17 | volumes:
18 | - ./protocol.privnet.yml:/config/protocol.privnet.yml
19 | - ./node-wallet.json:/wallets/node-wallet.json
20 | - ./config.yml:/wallets/config.yml
21 | - ./../../vendor/hosts:/etc/hosts
22 | - ./../../wallets/wallet.json:/wallets/wallet.json
23 |
24 | networks:
25 | chain_int:
26 | internet:
27 | external: true
28 | name: basenet_internet
29 |
--------------------------------------------------------------------------------
/services/morph_chain/node-wallet.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "3.0",
3 | "name":null,
4 | "accounts": [
5 | {
6 | "address": "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn",
7 | "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY",
8 | "label": "single",
9 | "contract": {
10 | "script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBVuezJw==",
11 | "parameters": [
12 | {
13 | "name": "parameter0",
14 | "type": "Signature"
15 | }
16 | ],
17 | "deployed": false
18 | },
19 | "lock": false,
20 | "extra":null,
21 | "isDefault": false
22 | },
23 | {
24 | "address": "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP",
25 | "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY",
26 | "label": "consensus",
27 | "contract": {
28 | "script": "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEUGe0Nw6",
29 | "parameters": [
30 | {
31 | "name": "parameter0",
32 | "type": "Signature"
33 | }
34 | ],
35 | "deployed": false
36 | },
37 | "lock": false,
38 | "extra":null,
39 | "isDefault": false
40 | },
41 | {
42 | "address": "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP",
43 | "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY",
44 | "label": "committee",
45 | "contract": {
46 | "script": "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEUGe0Nw6",
47 | "parameters": [
48 | {
49 | "name": "parameter0",
50 | "type": "Signature"
51 | }
52 | ],
53 | "deployed": false
54 | },
55 | "lock": false,
56 | "extra":null,
57 | "isDefault": true
58 | }
59 | ],
60 | "scrypt": {
61 | "n": 16384,
62 | "r": 8,
63 | "p": 8
64 | },
65 | "extra": {
66 | "Tokens": null
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/services/morph_chain/protocol.privnet.yml:
--------------------------------------------------------------------------------
1 | ProtocolConfiguration:
2 | Magic: 15405
3 | MaxTraceableBlocks: 200000
4 | SecondsPerBlock: 1
5 | MemPoolSize: 50000
6 | StandbyCommittee:
7 | - 02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2
8 | ValidatorsCount: 1
9 | SeedList:
10 | - 172.200.0.1:20333
11 | VerifyBlocks: true
12 | VerifyTransactions: true
13 | StateRootInHeader: true
14 | P2PSigExtensions: true
15 |
16 | ApplicationConfiguration:
17 | DBConfiguration:
18 | Type: "boltdb"
19 | BoltDBOptions:
20 | FilePath: "./db/morph.bolt"
21 | NodePort: 20333
22 | Relay: true
23 | DialTimeout: 3
24 | ProtoTickInterval: 2
25 | PingInterval: 30
26 | PingTimeout: 90
27 | MaxPeers: 10
28 | AttemptConnPeers: 5
29 | MinPeers: 0
30 | RPC:
31 | Address: 192.168.130.90
32 | Enabled: true
33 | SessionEnabled: true
34 | EnableCORSWorkaround: false
35 | MaxGasInvoke: 100
36 | Port: 30333
37 | P2PNotary:
38 | Enabled: true
39 | UnlockWallet:
40 | Path: "./wallets/node-wallet.json"
41 | Password: "one"
42 | Prometheus:
43 | Enabled: true
44 | Port: 20001
45 | Pprof:
46 | Enabled: true
47 | Port: 20011
48 | UnlockWallet:
49 | Path: "./wallets/node-wallet.json"
50 | Password: "one"
51 |
--------------------------------------------------------------------------------
/services/nats/.env:
--------------------------------------------------------------------------------
1 | ../../.env
--------------------------------------------------------------------------------
/services/nats/.hosts:
--------------------------------------------------------------------------------
1 | IPV4_PREFIX.101 nats.LOCAL_DOMAIN
2 |
--------------------------------------------------------------------------------
/services/nats/.int_test.env:
--------------------------------------------------------------------------------
1 | ../../.int_test.env
--------------------------------------------------------------------------------
/services/nats/artifacts.mk:
--------------------------------------------------------------------------------
1 | # Create new TLS certs for NATS server and clients
2 |
3 | NATS_DIR=$(abspath services/nats)
4 |
5 | get.nats:
6 | @echo "⇒ Creating certs for NATS server and clients"
7 | ${NATS_DIR}/generate_cert.sh ${LOCAL_DOMAIN} > /dev/null
8 |
--------------------------------------------------------------------------------
/services/nats/docker-compose.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | version: "2.4"
4 | services:
5 | nats:
6 | image: ${NATS_IMAGE}:${NATS_VERSION}
7 | domainname: ${LOCAL_DOMAIN}
8 | hostname: nats
9 | container_name: nats
10 | restart: on-failure
11 | dns:
12 | - ${IPV4_PREFIX}.101
13 | networks:
14 | nats_int:
15 | internet:
16 | ipv4_address: ${IPV4_PREFIX}.101
17 | volumes:
18 | - ./../../vendor/hosts:/etc/hosts
19 | - ./nats.conf:/etc/nats/frostfs-nats-server.conf
20 | - ./server-cert.pem:/certs/server-cert.pem
21 | - ./server-key.pem:/certs/server-key.pem
22 | - ./ca-cert.pem:/certs/ca-cert.pem
23 | stop_signal: SIGKILL
24 | env_file: [ ".env", ".int_test.env" ]
25 | command: ["-c", "/etc/nats/frostfs-nats-server.conf"]
26 |
27 | networks:
28 | nats_int:
29 | internet:
30 | external: true
31 | name: basenet_internet
32 |
--------------------------------------------------------------------------------
/services/nats/generate_cert.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source bin/helper.sh
4 |
5 | WORKDIR=$(dirname "$0")
6 | LOCAL_DOMAIN=$1
7 |
8 | CA_KEY=$WORKDIR/ca-key.pem
9 | CA_CRT=$WORKDIR/ca-cert.pem
10 |
11 | SRV_KEY=$WORKDIR/server-key.pem
12 | SRV_REQ=$WORKDIR/server-req.csr
13 | SRV_CRT=$WORKDIR/server-cert.pem
14 |
15 | CLI_KEY=$WORKDIR/client-key.pem
16 | CLI_REQ=$WORKDIR/client-req.csr
17 | CLI_CRT=$WORKDIR/client-cert.pem
18 |
19 | SUBJ="/O=NSPCC"
20 |
21 | if [[ ! -f $CA_KEY || ! -f $CA_CRT ]]; then
22 | openssl req -newkey rsa:4096 -x509 -days 365 -nodes -keyout $CA_KEY -out $CA_CRT -subj $SUBJ 2>&1 ||
23 | die "CA certificate was not created"
24 | fi
25 |
26 | if [[ ! -f $SRV_KEY || ! -f $SRV_CRT ]]; then
27 | openssl req -newkey rsa:4096 -nodes -keyout $SRV_KEY -out $SRV_REQ -subj $SUBJ 2>&1 ||
28 | die "Server certificate was not created"
29 |
30 | openssl x509 -req -days 365 -set_serial 01 -in $SRV_REQ -out $SRV_CRT -CA $CA_CRT -CAkey $CA_KEY \
31 | -extensions san -extfile <(printf "[san]\nsubjectAltName=DNS:nats.$LOCAL_DOMAIN") 2>&1 || {
32 | rm $SRV_REQ
33 | die "Server certificate was not signed by CA"
34 | }
35 |
36 | rm $SRV_REQ
37 | fi
38 |
39 | if [[ ! -f $CLI_KEY || ! -f $CLI_CRT ]]; then
40 | openssl req -newkey rsa:4096 -nodes -keyout $CLI_KEY -out $CLI_REQ -subj $SUBJ 2>&1 ||
41 | die "Client certificate was not created"
42 |
43 | openssl x509 -req -days 365 -set_serial 01 -in $CLI_REQ -out $CLI_CRT -CA $CA_CRT -CAkey $CA_KEY 2>&1 || {
44 | rm $CLI_REQ
45 | die "Client certificate was not signed by CA"
46 | }
47 |
48 | rm $CLI_REQ
49 | fi
50 |
--------------------------------------------------------------------------------
/services/nats/nats.conf:
--------------------------------------------------------------------------------
1 | port: 4222
2 | monitor_port: 8222
3 |
4 | jetstream {
5 | store_dir=nats
6 | max_memory_store: 1GB
7 | max_file_store: 2GB
8 | }
9 |
10 | tls {
11 | cert_file: /certs/server-cert.pem
12 | key_file: /certs/server-key.pem
13 | ca_file: /certs/ca-cert.pem
14 | verify: true
15 | }
16 |
--------------------------------------------------------------------------------
/services/rest_gate/.env:
--------------------------------------------------------------------------------
1 | ../../.env
--------------------------------------------------------------------------------
/services/rest_gate/.hosts:
--------------------------------------------------------------------------------
1 | IPV4_PREFIX.83 rest.LOCAL_DOMAIN
2 |
--------------------------------------------------------------------------------
/services/rest_gate/.int_test.env:
--------------------------------------------------------------------------------
1 | ../../.int_test.env
--------------------------------------------------------------------------------
/services/rest_gate/cfg/config.yml:
--------------------------------------------------------------------------------
1 | server:
2 | # The IP and port to listen on.
3 | listen-address: 0.0.0.0:8090
4 |
5 | # Wallet settings
6 | wallet:
7 | path: /wallet.json # Path to wallet
8 | passphrase: one # Password to decrypt wallet
9 |
--------------------------------------------------------------------------------
/services/rest_gate/docker-compose.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | version: "2.4"
4 | services:
5 | rest_gate:
6 | image: ${REST_GW_IMAGE}:${REST_GW_VERSION}
7 | domainname: ${LOCAL_DOMAIN}
8 | hostname: rest
9 | container_name: rest_gate
10 | restart: on-failure
11 | networks:
12 | rest_gate_int:
13 | internet:
14 | ipv4_address: ${IPV4_PREFIX}.83
15 | volumes:
16 | - ./wallet.json:/wallet.json
17 | - ./../../vendor/hosts:/etc/hosts
18 | - ./cfg:/etc/frostfs/rest
19 | stop_signal: SIGKILL
20 | env_file: [ ".env", ".int_test.env" ]
21 | command: [ "frostfs-rest-gw", "--config", "/etc/frostfs/rest/config.yml" ]
22 | environment:
23 | - REST_GW_POOL_PEERS_0_ADDRESS=s01.${LOCAL_DOMAIN}:8080
24 | - REST_GW_POOL_PEERS_1_ADDRESS=s02.${LOCAL_DOMAIN}:8080
25 | - REST_GW_POOL_PEERS_2_ADDRESS=s03.${LOCAL_DOMAIN}:8080
26 | - REST_GW_POOL_PEERS_3_ADDRESS=s04.${LOCAL_DOMAIN}:8080
27 |
28 | networks:
29 | rest_gate_int:
30 | internet:
31 | external: true
32 | name: basenet_internet
33 |
--------------------------------------------------------------------------------
/services/rest_gate/wallet.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "3.0",
3 | "accounts": [
4 | {
5 | "address": "NPFCqWHfi9ixCJRu7DABRbVfXRbkSEr9Vo",
6 | "key": "6PYTAGjdaeicUDPqGv9mmgwb9kTwimWJJmmfNqJSDGH9qM79zSRcL9oHiB",
7 | "label": "REST Gateway",
8 | "contract": {
9 | "script": "DCECcuPzZCZ2VyDsm2jKEOMnU6xEWO2bF1dvOvBWTDFYB1ZBVuezJw==",
10 | "parameters": [
11 | {
12 | "name": "parameter0",
13 | "type": "Signature"
14 | }
15 | ],
16 | "deployed": false
17 | },
18 | "lock": false,
19 | "isDefault": false
20 | }
21 | ],
22 | "scrypt": {
23 | "n": 16384,
24 | "r": 8,
25 | "p": 8
26 | },
27 | "extra": {
28 | "Tokens": null
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/services/s3_gate/.env:
--------------------------------------------------------------------------------
1 | ../../.env
--------------------------------------------------------------------------------
/services/s3_gate/.hosts:
--------------------------------------------------------------------------------
1 | IPV4_PREFIX.82 s3.LOCAL_DOMAIN
2 | IPV4_PREFIX.82 *.s3.LOCAL_DOMAIN
3 |
--------------------------------------------------------------------------------
/services/s3_gate/.int_test.env:
--------------------------------------------------------------------------------
1 | ../../.int_test.env
--------------------------------------------------------------------------------
/services/s3_gate/.s3.env:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrueCloudLab/frostfs-dev-env/37507199e2909ee0ca0cd10703f9f9622e1315b0/services/s3_gate/.s3.env
--------------------------------------------------------------------------------
/services/s3_gate/cfg/config.yml:
--------------------------------------------------------------------------------
1 | logger:
2 | level: debug
3 |
4 | # Interval to check node health
5 | rebalance_interval: 30s
6 |
7 | # Timeout to check node health during rebalance
8 | healthcheck_timeout: 15s
9 |
10 | # Timeout to connect to a node
11 | connect_timeout: 10s
12 |
13 | # Limits for processing of clients' requests
14 | max_clients_count: 100
15 |
16 | # Deadline after which the gate sends error `RequestTimeout` to a client
17 | max_clients_deadline: 30s
18 |
19 | resolve_order:
20 | - nns
21 |
22 | server:
23 | - tls:
24 | enabled: true
25 | cert_file: /tls.crt
26 | key_file: /tls.key
27 |
28 | # Wallet configuration
29 | wallet:
30 | path: /wallet.json # Path to wallet
31 | passphrase: "s3" # Passphrase to decrypt wallet
32 |
--------------------------------------------------------------------------------
/services/s3_gate/docker-compose.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | version: "2.4"
4 | services:
5 | s3_gate:
6 | image: ${S3_GW_IMAGE}:${S3_GW_VERSION}
7 | domainname: ${LOCAL_DOMAIN}
8 | hostname: s3_gate
9 | container_name: s3_gate
10 | restart: on-failure
11 | networks:
12 | s3_gate_int:
13 | internet:
14 | ipv4_address: ${IPV4_PREFIX}.82
15 | volumes:
16 | - ./wallet.json:/wallet.json
17 | - ./tls.key:/tls.key
18 | - ./tls.crt:/tls.crt
19 | - ./../../vendor/hosts:/etc/hosts
20 | - ./cfg:/etc/frostfs/s3
21 | stop_signal: SIGKILL
22 | env_file: [ ".env", ".s3.env", ".int_test.env" ]
23 | command: [ "frostfs-s3-gw", "--config", "/etc/frostfs/s3/config.yml" ]
24 | environment:
25 | - S3_GW_RPC_ENDPOINT=http://morph-chain.${LOCAL_DOMAIN}:30333
26 | - S3_GW_SERVER_0_ADDRESS=s3.${LOCAL_DOMAIN}:8080
27 | - S3_GW_LISTEN_DOMAINS=s3.${LOCAL_DOMAIN}
28 | - S3_GW_TREE_SERVICE=s01.${LOCAL_DOMAIN}:8080
29 | - S3_GW_PEERS_0_ADDRESS=s01.${LOCAL_DOMAIN}:8080
30 | - S3_GW_PEERS_0_WEIGHT=0.2
31 | - S3_GW_PEERS_1_ADDRESS=s02.${LOCAL_DOMAIN}:8080
32 | - S3_GW_PEERS_1_WEIGHT=0.2
33 | - S3_GW_PEERS_2_ADDRESS=s03.${LOCAL_DOMAIN}:8080
34 | - S3_GW_PEERS_2_WEIGHT=0.2
35 | - S3_GW_PEERS_3_ADDRESS=s04.${LOCAL_DOMAIN}:8080
36 | - S3_GW_PEERS_3_WEIGHT=0.2
37 |
38 | networks:
39 | s3_gate_int:
40 | internet:
41 | external: true
42 | name: basenet_internet
43 |
--------------------------------------------------------------------------------
/services/s3_gate/tls.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIDpDCCAowCCQDXZEH0aQRqFzANBgkqhkiG9w0BAQsFADCBkzELMAkGA1UEBhMC
3 | UlUxFjAUBgNVBAgMDVN0LlBldGVyc2J1cmcxGTAXBgNVBAcMEFNhaW50IFBldGVy
4 | c2J1cmcxDjAMBgNVBAoMBU5TUENDMREwDwYDVQQLDAhOZW8gU1BDQzERMA8GA1UE
5 | AwwIbnNwY2MucnUxGzAZBgkqhkiG9w0BCQEWDG9wc0Buc3BjYy5ydTAeFw0yMDA3
6 | MTMxNTQyMzZaFw0zMDA3MTExNTQyMzZaMIGTMQswCQYDVQQGEwJSVTEWMBQGA1UE
7 | CAwNU3QuUGV0ZXJzYnVyZzEZMBcGA1UEBwwQU2FpbnQgUGV0ZXJzYnVyZzEOMAwG
8 | A1UECgwFTlNQQ0MxETAPBgNVBAsMCE5lbyBTUENDMREwDwYDVQQDDAhuc3BjYy5y
9 | dTEbMBkGCSqGSIb3DQEJARYMb3BzQG5zcGNjLnJ1MIIBIjANBgkqhkiG9w0BAQEF
10 | AAOCAQ8AMIIBCgKCAQEAwqo2l4fS0U6wZCLh7VjQn1LXN8pZlVaA62C+g1SwoWV2
11 | Q5qM8FDihWj3UBO3F+6vUVJl8N5S0JroxxU6L48Wmshei145SLSl/F28tsk7Bbuz
12 | NOchonlelW77Xr6l7cDJBWUWGkDoq6a/S6w6jjCGhZq+X0gyS5nZ4HTouVNv2oFK
13 | eeJGtueLsS4zoVovrHdLSYdZH9/yC+E1WVCzQB+vdUF/vJLTuULgqncLV0sELmRl
14 | +xsnnAV/REJswtCmKgrmAv9pMebBw5EEgROTGazdToWdD5X44xTlHjUb1bMuF9tL
15 | YtUMdLxXceXZFhYhiTBO7ev9awKaNYslbxh+goJo1wIDAQABMA0GCSqGSIb3DQEB
16 | CwUAA4IBAQBDEGhAyOtfsNwbZ0oZIw06e0JXCmri+8jsn5Ly/yHU0+ecHgMA5AAQ
17 | AG2QRpZZtZCtD/Cj4i6nSTWbRhS0FgqY998p5Lnh/AXTZHBx0t3LKJupN59CIjCK
18 | 1eMEfQChoAZg66oO/obAFkq72gj8gpagMY9vFNVcszmse3FWrvlKmO1TwTEh+CzM
19 | 7wbmiL/ujm0lIf44pp0U4qYFcSimSDqbwOfeDPif9lMinzylDxMfaAKBHBHPj5Vt
20 | fX8dgf6MIqyz51u/2G0gHfXMDxXec8huYKt2EtPyavh6kFxxGvcA15m6seJTcu+h
21 | 6WzeQFa2NBg7Z3ai4DiPXirNtcHWeqxK
22 | -----END CERTIFICATE-----
23 |
--------------------------------------------------------------------------------
/services/s3_gate/tls.key:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIIEowIBAAKCAQEAwqo2l4fS0U6wZCLh7VjQn1LXN8pZlVaA62C+g1SwoWV2Q5qM
3 | 8FDihWj3UBO3F+6vUVJl8N5S0JroxxU6L48Wmshei145SLSl/F28tsk7BbuzNOch
4 | onlelW77Xr6l7cDJBWUWGkDoq6a/S6w6jjCGhZq+X0gyS5nZ4HTouVNv2oFKeeJG
5 | tueLsS4zoVovrHdLSYdZH9/yC+E1WVCzQB+vdUF/vJLTuULgqncLV0sELmRl+xsn
6 | nAV/REJswtCmKgrmAv9pMebBw5EEgROTGazdToWdD5X44xTlHjUb1bMuF9tLYtUM
7 | dLxXceXZFhYhiTBO7ev9awKaNYslbxh+goJo1wIDAQABAoIBAEIp3mJEjPgNOdDf
8 | NlEYpdfxLStOQIKMo0bdXAOBToOc28SAjDTGGSflFGIIQWwF+Vq3meRzfExgyouY
9 | AG3XwYQcZF4USX4XwG71YUXzQXdiY7ewc3Mos2gxD4kVXYpgwzJtOET2GN72zwAm
10 | asSXY7GXdesmu8mMYkxzEAKlhFgMj+bGE/4QQUBKG9ylGIdo07zmU6rAsVhnwQTb
11 | LE3cf+AxCeTVA7OsJCUUR4S9qsgXUN1WeaV8LNg0lYx8UTu1xlbrpSjx7B4eYy6J
12 | FGJWuT9b3X+cBLcGk3BzheUAfqBG2UFDxUCt0grqmmTBkB850MtCDhffhPjxxrD7
13 | KrwAcpECgYEA6HApn2VtWI/tDYCbNix6yxeqq73fO3ng6yFry1u7EYvl8hJXBgR4
14 | b6kAVc3y/9pZO/5D23dHl1PQtnU5401/j6dQrb8A2TMqZ1vA8XIdIMjOiVjZtYMF
15 | nXzmf78PEbw9jWlDVARJdAwkJeuDI4/HVvgiDAh3zxx5F8uDVP16/r8CgYEA1mXS
16 | 9owfLIPtPSxyMJoGU0jP7OP+HVwlKkXpvg7uBtINKSDW4UU4rnpIGW5MohR3ACWO
17 | ReFliOnGA5FXBp9GzkbJ+wIYovPIsGuBdxSsBlPY1S0yPlo30hr7E6cK3B3EuxDg
18 | SkbJcWp2EwXYEIyEcopbVUTTlBO3wmBFgm/Ps+kCgYA/+Kar9OlMR4hRgAS3uzQs
19 | cx4I2F/46YlKjU8yj9ODd8JYhk2nHVHcQWITO3RWkEyg41DftQtiDbJSlR7SfUDP
20 | U5gzyW69WISiH7GRgfucS0f0qxx4BVBlULvLitTl5631HnRmSivBIZpNSW01O1v8
21 | hpwwPaBjww1czCkgGgdg1wKBgQCkaSdTW/bX+z9lpvzWWnc5TN/uSJRpTW1Osphh
22 | 4C8WWeQvwvglfiDOZAWAQv5PWKQ9H4+v9P4Y9TSdLcpv0JrKuqxPabcc1xfyei6o
23 | 89hLbecc6vDZsfOWkowx8Oo6DDX+Qh3Nt+TorXxocBXV8vvqnkEV7ZbWuhwz2gHT
24 | 2gyMaQKBgEE7rNzm8Q03IqQ08eYaRw8gWz8EpLeVebrGqtoH9AR5cd4OeTeZAEqc
25 | iPehXctke2pUgS47XgG98G7Yg3E9UuOYM+H2nzQCoT7jrM0dZrVGZ0ty7z1a8QGe
26 | UrjaAC/cyIGdszhf0Rf3qA7450nit9Txh+ilLiumgnUezl+eJXyI
27 | -----END RSA PRIVATE KEY-----
28 |
--------------------------------------------------------------------------------
/services/s3_gate/wallet.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "3.0",
3 | "name":null,
4 | "accounts": [
5 | {
6 | "address": "NUUb82KR2JrVByHs2YSKgtK29gKnF5q6Vt",
7 | "key": "6PYSPET41jKtqie2cfkqgy7q9ueeucH8bX9Gotm2HwdNEDptj6aBe8dDg8",
8 | "label": "FrostFS S3 Gate",
9 | "contract": {
10 | "script": "DCEDE7GsOoB24VWn55eyTwtlDMytWUHqWdfP1RoCSosqBr9BVuezJw==",
11 | "parameters": [
12 | {
13 | "name": "parameter0",
14 | "type": "Signature"
15 | }
16 | ],
17 | "deployed": false
18 | },
19 | "lock": false,
20 | "extra":null,
21 | "isDefault": false
22 | }
23 | ],
24 | "scrypt": {
25 | "n": 16384,
26 | "r": 8,
27 | "p": 8
28 | },
29 | "extra": {
30 | "Tokens": null
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/services/storage/.env:
--------------------------------------------------------------------------------
1 | ../../.env
--------------------------------------------------------------------------------
/services/storage/.hosts:
--------------------------------------------------------------------------------
1 | IPV4_PREFIX.71 s01.LOCAL_DOMAIN
2 | IPV4_PREFIX.72 s02.LOCAL_DOMAIN
3 | IPV4_PREFIX.73 s03.LOCAL_DOMAIN
4 | IPV4_PREFIX.74 s04.LOCAL_DOMAIN
5 |
--------------------------------------------------------------------------------
/services/storage/.int_test.env:
--------------------------------------------------------------------------------
1 | ../../.int_test.env
--------------------------------------------------------------------------------
/services/storage/.storage.env:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrueCloudLab/frostfs-dev-env/37507199e2909ee0ca0cd10703f9f9622e1315b0/services/storage/.storage.env
--------------------------------------------------------------------------------
/services/storage/artifacts.mk:
--------------------------------------------------------------------------------
1 | # Create new TLS certs to FrostFS node
2 |
3 | STORAGE_DIR=$(abspath services/storage)
4 |
5 | get.storage:
6 | @echo "⇒ Creating TLS certs to FrostFS node"
7 | ${STORAGE_DIR}/generate_cert.sh ${LOCAL_DOMAIN} > /dev/null
8 |
--------------------------------------------------------------------------------
/services/storage/cfg/config.yml:
--------------------------------------------------------------------------------
1 | # Logger section
2 | logger:
3 | level: debug # Minimum enabled logging level
4 |
5 | # Profiler section
6 | pprof:
7 | enabled: true
8 | address: :6060 # Server address
9 | shutdown_timeout: 15s # Timeout for profiling HTTP server graceful shutdown
10 |
11 | # Application metrics section
12 | prometheus:
13 | enabled: true
14 | address: :9090 # Server address
15 | shutdown_timeout: 15s # Timeout for metrics HTTP server graceful shutdown
16 |
17 | # Morph section
18 | morph:
19 | dial_timeout: 30s # Timeout for side chain NEO RPC client connection
20 | rpc_endpoint: # Side chain NEO RPC endpoints
21 | - address: ws://morph-chain:30333/ws
22 | priority: 1
23 |
24 | # Common storage node settings
25 | node:
26 | attribute_0: "User-Agent:FrostFS/0.34"
27 | notification:
28 | enabled: true # Turn on object notification service
29 | endpoint: "tls://nats.frostfs.devenv:4222" # Notification server endpoint
30 | timeout: "6s" # Timeout for object notification client connection
31 | default_topic: "test" # Default topic for object notifications if not found in object's meta
32 | certificate: "/etc/frostfs-node/nats.tls.cert" # Path to TLS certificate
33 | key: "/etc/frostfs-node/nats.tls.key" # Path to TLS key
34 | ca: "/etc/frostfs-node/nats.ca.crt" # Path to optional CA certificate
35 |
36 | # Tree section
37 | tree:
38 | enabled: true
39 |
40 | # Storage engine configuration
41 | storage:
42 | shard:
43 | 0:
44 | writecache:
45 | enabled: false
46 | path: /storage/wc0 # Write-cache root directory
47 |
48 | metabase:
49 | path: /storage/meta0 # Path to the metabase
50 |
51 | blobstor:
52 | - type: blobovnicza
53 | path: /storage/blobovnicza0 # Blobovnicza root directory
54 | depth: 2
55 | width: 4
56 | - type: fstree
57 | path: /storage/fstree0 # FSTree root directory
58 | depth: 2
59 |
60 | pilorama:
61 | path: /storage/pilorama0 # Path to the pilorama database
62 |
63 | 1:
64 | writecache:
65 | enabled: false
66 | path: /storage/wc1 # Write-cache root directory
67 |
68 | metabase:
69 | path: /storage/meta1 # Path to the metabase
70 |
71 | blobstor:
72 | - type: blobovnicza
73 | path: /storage/blobovnicza1 # Blobovnicza root directory
74 | depth: 2
75 | width: 4
76 | - type: fstree
77 | path: /storage/fstree1 # FSTree root directory
78 | depth: 2
79 |
80 | pilorama:
81 | path: /storage/pilorama1 # Path to the pilorama database
82 |
--------------------------------------------------------------------------------
/services/storage/cli-cfg.yml:
--------------------------------------------------------------------------------
1 | wallet: /wallet.json
2 | password: ""
3 |
--------------------------------------------------------------------------------
/services/storage/docker-compose.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | version: "2.4"
4 | services:
5 | storage01:
6 | image: ${NODE_IMAGE}:${NODE_VERSION}
7 | domainname: ${LOCAL_DOMAIN}
8 | hostname: s01
9 | container_name: s01
10 | restart: on-failure
11 | networks:
12 | storage_int:
13 | internet:
14 | ipv4_address: ${IPV4_PREFIX}.71
15 | volumes:
16 | - ./wallet01.json:/wallet.json
17 | - ./../../vendor/hosts:/etc/hosts
18 | - storage_s01:/storage
19 | - ./../../vendor/frostfs-cli:/frostfs-cli
20 | - ./cli-cfg.yml:/cli-cfg.yml
21 | - ./healthcheck.sh:/healthcheck.sh
22 | - ./s04tls.crt:/etc/ssl/certs/s04tls.crt
23 | - ../nats/client-cert.pem:/etc/frostfs-node/nats.tls.cert
24 | - ../nats/client-key.pem:/etc/frostfs-node/nats.tls.key
25 | - ../nats/ca-cert.pem:/etc/frostfs-node/nats.ca.crt
26 | - ./cfg:/etc/frostfs/storage
27 | stop_signal: SIGKILL
28 | env_file: [ ".env", ".storage.env", ".int_test.env" ]
29 | command: [ "frostfs-node", "--config", "/etc/frostfs/storage/config.yml" ]
30 | environment:
31 | - FROSTFS_NODE_WALLET_PATH=./wallet.json
32 | - FROSTFS_NODE_WALLET_PASSWORD=
33 | - FROSTFS_NODE_ADDRESSES=s01.${LOCAL_DOMAIN}:8080
34 | - FROSTFS_GRPC_0_ENDPOINT=s01.${LOCAL_DOMAIN}:8080
35 | - FROSTFS_CONTROL_GRPC_ENDPOINT=s01.${LOCAL_DOMAIN}:8081
36 | - FROSTFS_NODE_ATTRIBUTE_1=UN-LOCODE:RU MOW
37 | - FROSTFS_NODE_ATTRIBUTE_2=Price:22
38 | healthcheck:
39 | test: ["CMD-SHELL", "/healthcheck.sh"]
40 | interval: 2s
41 | timeout: 1s
42 | retries: 5
43 | start_period: 10s
44 |
45 | storage02:
46 | image: ${NODE_IMAGE}:${NODE_VERSION}
47 | domainname: ${LOCAL_DOMAIN}
48 | hostname: s02
49 | container_name: s02
50 | restart: on-failure
51 | networks:
52 | storage_int:
53 | internet:
54 | ipv4_address: ${IPV4_PREFIX}.72
55 | volumes:
56 | - ./wallet02.json:/wallet.json
57 | - ./../../vendor/hosts:/etc/hosts
58 | - storage_s02:/storage
59 | - ./../../vendor/frostfs-cli:/frostfs-cli
60 | - ./cli-cfg.yml:/cli-cfg.yml
61 | - ./healthcheck.sh:/healthcheck.sh
62 | - ./s04tls.crt:/etc/ssl/certs/s04tls.crt
63 | - ../nats/client-cert.pem:/etc/frostfs-node/nats.tls.cert
64 | - ../nats/client-key.pem:/etc/frostfs-node/nats.tls.key
65 | - ../nats/ca-cert.pem:/etc/frostfs-node/nats.ca.crt
66 | - ./cfg:/etc/frostfs/storage
67 | stop_signal: SIGKILL
68 | env_file: [ ".env", ".storage.env", ".int_test.env" ]
69 | command: [ "frostfs-node", "--config", "/etc/frostfs/storage/config.yml" ]
70 | environment:
71 | - FROSTFS_NODE_WALLET_PATH=./wallet.json
72 | - FROSTFS_NODE_WALLET_PASSWORD=
73 | - FROSTFS_NODE_ADDRESSES=s02.${LOCAL_DOMAIN}:8080
74 | - FROSTFS_GRPC_0_ENDPOINT=s02.${LOCAL_DOMAIN}:8080
75 | - FROSTFS_CONTROL_GRPC_ENDPOINT=s02.${LOCAL_DOMAIN}:8081
76 | - FROSTFS_NODE_ATTRIBUTE_1=UN-LOCODE:RU LED
77 | - FROSTFS_NODE_ATTRIBUTE_2=Price:33
78 | healthcheck:
79 | test: ["CMD-SHELL", "/healthcheck.sh"]
80 | interval: 2s
81 | timeout: 1s
82 | retries: 5
83 | start_period: 10s
84 |
85 | storage03:
86 | image: ${NODE_IMAGE}:${NODE_VERSION}
87 | domainname: ${LOCAL_DOMAIN}
88 | hostname: s03
89 | container_name: s03
90 | restart: on-failure
91 | networks:
92 | storage_int:
93 | internet:
94 | ipv4_address: ${IPV4_PREFIX}.73
95 | volumes:
96 | - ./wallet03.json:/wallet.json
97 | - ./../../vendor/hosts:/etc/hosts
98 | - storage_s03:/storage
99 | - ./../../vendor/frostfs-cli:/frostfs-cli
100 | - ./cli-cfg.yml:/cli-cfg.yml
101 | - ./healthcheck.sh:/healthcheck.sh
102 | - ./s04tls.crt:/etc/ssl/certs/s04tls.crt
103 | - ../nats/client-cert.pem:/etc/frostfs-node/nats.tls.cert
104 | - ../nats/client-key.pem:/etc/frostfs-node/nats.tls.key
105 | - ../nats/ca-cert.pem:/etc/frostfs-node/nats.ca.crt
106 | - ./cfg:/etc/frostfs/storage
107 | stop_signal: SIGKILL
108 | env_file: [ ".env", ".storage.env", ".int_test.env" ]
109 | command: [ "frostfs-node", "--config", "/etc/frostfs/storage/config.yml" ]
110 | environment:
111 | - FROSTFS_NODE_WALLET_PATH=./wallet.json
112 | - FROSTFS_NODE_WALLET_PASSWORD=
113 | - FROSTFS_NODE_ADDRESSES=s03.${LOCAL_DOMAIN}:8080
114 | - FROSTFS_GRPC_0_ENDPOINT=s03.${LOCAL_DOMAIN}:8080
115 | - FROSTFS_CONTROL_GRPC_ENDPOINT=s03.${LOCAL_DOMAIN}:8081
116 | - FROSTFS_NODE_ATTRIBUTE_1=UN-LOCODE:SE STO
117 | - FROSTFS_NODE_ATTRIBUTE_2=Price:11
118 | healthcheck:
119 | test: ["CMD-SHELL", "/healthcheck.sh"]
120 | interval: 2s
121 | timeout: 1s
122 | retries: 5
123 | start_period: 10s
124 |
125 | storage04:
126 | image: ${NODE_IMAGE}:${NODE_VERSION}
127 | domainname: ${LOCAL_DOMAIN}
128 | hostname: s04
129 | container_name: s04
130 | restart: on-failure
131 | networks:
132 | storage_int:
133 | internet:
134 | ipv4_address: ${IPV4_PREFIX}.74
135 | volumes:
136 | - ./wallet04.json:/wallet.json
137 | - ./../../vendor/hosts:/etc/hosts
138 | - storage_s04:/storage
139 | - ./../../vendor/frostfs-cli:/frostfs-cli
140 | - ./cli-cfg.yml:/cli-cfg.yml
141 | - ./healthcheck.sh:/healthcheck.sh
142 | - ./s04tls.crt:/tls.crt
143 | - ./s04tls.key:/tls.key
144 | - ../nats/client-cert.pem:/etc/frostfs-node/nats.tls.cert
145 | - ../nats/client-key.pem:/etc/frostfs-node/nats.tls.key
146 | - ../nats/ca-cert.pem:/etc/frostfs-node/nats.ca.crt
147 | - ./cfg:/etc/frostfs/storage
148 | stop_signal: SIGKILL
149 | env_file: [ ".env", ".storage.env", ".int_test.env" ]
150 | command: [ "frostfs-node", "--config", "/etc/frostfs/storage/config.yml" ]
151 | environment:
152 | - FROSTFS_NODE_WALLET_PATH=./wallet.json
153 | - FROSTFS_NODE_WALLET_PASSWORD=
154 | - FROSTFS_NODE_ADDRESSES=s04.${LOCAL_DOMAIN}:8080 grpcs://s04.${LOCAL_DOMAIN}:8082
155 | - FROSTFS_CONTROL_GRPC_ENDPOINT=s04.${LOCAL_DOMAIN}:8081
156 | - FROSTFS_GRPC_NUM=2
157 | - FROSTFS_GRPC_0_ENDPOINT=s04.${LOCAL_DOMAIN}:8080
158 | - FROSTFS_GRPC_1_ENDPOINT=s04.${LOCAL_DOMAIN}:8082
159 | - FROSTFS_GRPC_1_TLS_ENABLED=true
160 | - FROSTFS_GRPC_1_TLS_CERTIFICATE=/tls.crt
161 | - FROSTFS_GRPC_1_TLS_KEY=/tls.key
162 | - FROSTFS_NODE_ATTRIBUTE_1=UN-LOCODE:FI HEL
163 | - FROSTFS_NODE_ATTRIBUTE_2=Price:44
164 | healthcheck:
165 | test: ["CMD-SHELL", "/healthcheck.sh"]
166 | interval: 2s
167 | timeout: 1s
168 | retries: 5
169 | start_period: 10s
170 |
171 | sn-healthcheck:
172 | container_name: sn-healthcheck
173 | image: debian:10
174 | depends_on:
175 | storage01:
176 | condition: service_healthy
177 | storage02:
178 | condition: service_healthy
179 | storage03:
180 | condition: service_healthy
181 | storage04:
182 | condition: service_healthy
183 |
184 | volumes:
185 | storage_s01:
186 | storage_s02:
187 | storage_s03:
188 | storage_s04:
189 |
190 | networks:
191 | storage_int:
192 | internet:
193 | external: true
194 | name: basenet_internet
195 |
--------------------------------------------------------------------------------
/services/storage/generate_cert.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source bin/helper.sh
4 |
5 | WORKDIR=$(dirname "$0")
6 | LOCAL_DOMAIN=$1
7 | SSL_CONFIG=$(mktemp)
8 | CERT="${WORKDIR}/s04tls.crt"
9 | KEY="${WORKDIR}/s04tls.key"
10 |
11 |
12 | if [[ ! -f ${CERT} ]]; then
13 | (
14 | echo "[req]"; \
15 | echo "distinguished_name=req"; \
16 | echo "req_extensions=san"; \
17 | echo "[san]"; \
18 | echo "subjectAltName=DNS:s04.${LOCAL_DOMAIN}"
19 | ) > ${SSL_CONFIG}
20 |
21 | openssl req -new -newkey rsa:4096 -x509 -sha256 -days 365 -nodes \
22 | -subj "/C=RU/ST=SPB/L=St.Petersburg/O=NSPCC/OU=NSPCC/CN=s04.${LOCAL_DOMAIN}" \
23 | -keyout "${KEY}" -out "${CERT}" -extensions san -config "${SSL_CONFIG}" &> /dev/null || {
24 | die "Failed to generate SSL certificate for s04"
25 | }
26 | fi
27 |
--------------------------------------------------------------------------------
/services/storage/healthcheck.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | /frostfs-cli control healthcheck -c /cli-cfg.yml \
4 | --endpoint "$FROSTFS_CONTROL_GRPC_ENDPOINT" |
5 | grep "Health status: READY"
6 |
--------------------------------------------------------------------------------
/services/storage/prepare.mk:
--------------------------------------------------------------------------------
1 | # Add self-signed node TLS certificate to trusted store
2 |
3 | prepare.storage:
4 | @echo "Adding self-signed TLS certs to trusted store"
5 | @./bin/addCert.sh
6 |
--------------------------------------------------------------------------------
/services/storage/wallet01.json:
--------------------------------------------------------------------------------
1 | {
2 | "version":"3.0",
3 | "accounts":[
4 | {
5 | "address":"NejLbQpojKJWec4NQRMBhzsrmCyhXfGJJe",
6 | "key":"6PYSS8ccmBcttfcw2YJh8VcNSoeQbQLuJLQ7HoKeYF5roRmGs9LUvmKcWz",
7 | "label":"",
8 | "contract":{
9 | "script":"DCECK7QEHFDWB/+HHex+TNd3g4jg6mhJ2EzL2aqPMuFqgTFBVuezJw==",
10 | "parameters":[
11 | {
12 | "name":"parameter0",
13 | "type":"Signature"
14 | }
15 | ],
16 | "deployed":false
17 | },
18 | "lock":false,
19 | "extra":null,
20 | "isDefault":true
21 | }
22 | ],
23 | "name":null,
24 | "scrypt":{
25 | "n":16384,
26 | "r":8,
27 | "p":8
28 | },
29 | "extra":{
30 | "Tokens":null
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/services/storage/wallet02.json:
--------------------------------------------------------------------------------
1 | {
2 | "version":"3.0",
3 | "accounts":[
4 | {
5 | "address":"NVXXy3hNTvwVEZa2dAibALyJB3Q86aiHvL",
6 | "key":"6PYXd9hxMYfaCkgeZp3q1RoMB921RQFkRxYftcacTJ2S7MUwnivrxi6Yk5",
7 | "label":"",
8 | "contract":{
9 | "script":"DCED/2W2rnkTSk3OnQ0504Uem6tO6Xq/hugeHFu8UM0oJq5BVuezJw==",
10 | "parameters":[
11 | {
12 | "name":"parameter0",
13 | "type":"Signature"
14 | }
15 | ],
16 | "deployed":false
17 | },
18 | "lock":false,
19 | "isDefault":false
20 | }
21 | ],
22 | "scrypt":{
23 | "n":16384,
24 | "r":8,
25 | "p":8
26 | },
27 | "extra":{
28 | "Tokens":null
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/services/storage/wallet03.json:
--------------------------------------------------------------------------------
1 | {
2 | "version":"3.0",
3 | "accounts":[
4 | {
5 | "address":"NPTmih9X14Y7xLvmD6RVtDHdH1Y9qJwoTe",
6 | "key":"6PYXNeQzge9fWztVnWYRbr5Mh9q1y4npKVARHYGb484Hct1iNd3vXGR1kk",
7 | "label":"",
8 | "contract":{
9 | "script":"DCECrJIM198LYbKJBy5rlG4tpOGjG5qxxiG7R14w+kqxAsNBVuezJw==",
10 | "parameters":[
11 | {
12 | "name":"parameter0",
13 | "type":"Signature"
14 | }
15 | ],
16 | "deployed":false
17 | },
18 | "lock":false,
19 | "isDefault":false
20 | }
21 | ],
22 | "scrypt":{
23 | "n":16384,
24 | "r":8,
25 | "p":8
26 | },
27 | "extra":{
28 | "Tokens":null
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/services/storage/wallet04.json:
--------------------------------------------------------------------------------
1 | {
2 | "version":"3.0",
3 | "accounts":[
4 | {
5 | "address":"Ne2DAQbWvP1s7TbtFc7BStKMnjKJdBaVRm",
6 | "key":"6PYWCsGWx8uSVYK94tvK7Ccit8x8Z3f3dHADTFTgLhT9NBXTBqBECL8AyC",
7 | "label":"",
8 | "contract":{
9 | "script":"DCEDjIYpWeVrQ+IPeRh8T+ngvHyMZsFgPmzw7H+Hq2sI3DVBVuezJw==",
10 | "parameters":[
11 | {
12 | "name":"parameter0",
13 | "type":"Signature"
14 | }
15 | ],
16 | "deployed":false
17 | },
18 | "lock":false,
19 | "isDefault":false
20 | }
21 | ],
22 | "scrypt":{
23 | "n":16384,
24 | "r":8,
25 | "p":8
26 | },
27 | "extra":{
28 | "Tokens":null
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/wallets/wallet.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "3.0",
3 | "accounts": [
4 | {
5 | "address": "NbUgTSFvPmsRxmGeWpuuGeJUoRoi6PErcM",
6 | "key": "6PYP7YrwGnLuu4WYQbEe3WJiC44aKmqwqawLsp7H3oh5vocS9xTv2ZfTp3",
7 | "label": "",
8 | "contract": {
9 | "script": "DCEDGmxvu98CyjUXRfqGubpalFLXhaxPf8K3VIyipGxPz0pBVuezJw==",
10 | "parameters": [
11 | {
12 | "name": "parameter0",
13 | "type": "Signature"
14 | }
15 | ],
16 | "deployed": false
17 | },
18 | "lock": false,
19 | "isdefault": false
20 | }
21 | ],
22 | "scrypt": {
23 | "n": 16384,
24 | "r": 8,
25 | "p": 8
26 | },
27 | "extra": {
28 | "Tokens": null
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/wallets/wallet.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrueCloudLab/frostfs-dev-env/37507199e2909ee0ca0cd10703f9f9622e1315b0/wallets/wallet.key
--------------------------------------------------------------------------------