diff --git a/.github/workflows/ansible.yml b/.github/workflows/ansible.yml index f89fb06..4a4e016 100644 --- a/.github/workflows/ansible.yml +++ b/.github/workflows/ansible.yml @@ -34,40 +34,15 @@ jobs: # reporter: github-pr-check # fail_on_error: true - collection: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Setup python - uses: actions/setup-python@v5 - with: - python-version: "3.x" - cache: pip - - - name: Install python dependencies - run: python -m pip install -r requirements.txt - - - name: Build collection - run: ansible-galaxy collection build . - - - name: Upload collection - uses: actions/upload-artifact@v4 - with: - path: fluencelabs-provider-*.tar.gz - name: collection - if-no-files-found: error - molecule: runs-on: ubuntu-latest - needs: collection - strategy: fail-fast: false matrix: scenario: - ubuntu2204 + - debian12 steps: - uses: actions/checkout@v4 @@ -89,14 +64,5 @@ jobs: - name: Install python dependencies run: python -m pip install -r requirements.txt - - name: Download collection - uses: actions/download-artifact@v4 - with: - name: collection - - - name: Install collection - run: ansible-galaxy collection install fluencelabs-provider-*.tar.gz - - name: Run ${{ matrix.scenario }} scenario - working-directory: extensions run: molecule test --scenario-name "${{ matrix.scenario }}" diff --git a/README.md b/README.md index a761e80..0061e09 100644 --- a/README.md +++ b/README.md @@ -10,4 +10,6 @@ Fluence provider toolkit. ## Roles - [nox](https://github.com/fluencelabs/ansible/tree/main/roles/nox) +- [ccp](https://github.com/fluencelabs/ansible/tree/main/roles/ccp) +- [prerequisites](https://github.com/fluencelabs/ansible/tree/main/roles/prerequisites) - [ipfs_cli](https://github.com/fluencelabs/ansible/tree/main/roles/ipfs_cli) diff --git a/example/README.md b/example/README.md index 2a4c2b7..3bc1c55 100644 --- a/example/README.md +++ b/example/README.md @@ -2,9 +2,6 @@ This directory contains all necessary predefined files to setup Nox locally. -You can follow this guide by [using predefined files](#Using-predefined-files) -or by [starting from scratch](#Starting-from-scratch). - ## Prerequisites ### Podman @@ -29,10 +26,11 @@ Install using commands from the After installation, set a specific version of FCLI compatible with this guide: ```bash -fluence update --version 0.14.0 +fluence update --version 0.15.17 ``` ### MacOS + #### gnu-tar Users of MacOS need to install `gnu-tar` for this collection of roles to work. @@ -42,6 +40,7 @@ brew install gnu-tar ``` #### sshpass + Users of MacOS need to install (only for running examples) `sshpass`: ```bash @@ -60,151 +59,13 @@ podman machine start ## Setup Nox -### Using Predefined Files - - Clone this repo and change to `example` directory -``` bash -git clone https://github.com/fluencelabs/ansible -cd example -``` - -- Create and activate python virtual environment - -```bash -python3 -m venv ~/.virtualenvs/fluence/nox-ansible-demo -source ~/.virtualenvs/fluence/nox-ansible-demo/bin/activate -``` - -- Install python dependencies - -```bash -pip3 install -r requirements.txt -``` - -- Install Ansible Provider collection - -```bash -ansible-galaxy collection install fluencelabs.provider -``` - -- Start services and servers - -```bash -podman-compose up -d --build -``` - -- Wait for all services to start and setup Noxes - -```bash -ansible-playbook nox.yml -i inventory.yml -``` - -- When finished run cleanup ```bash -podman-compose down -``` - -### Starting from Scratch - -- Clone this repo and change to `example` directory -``` bash git clone https://github.com/fluencelabs/ansible cd example ``` -- Create project directories - -```bash -# create project directory -mkdir ansible-demo && cd ansible-demo -# create necessary directories for ansible -mkdir -p files/demo -cd files/demo -``` - -- Initialize project - -```bash -fluence provider init --no-input --env=local --noxes=3 -``` - -- Update `provider.yaml` with nox config required for Ansible - -```bash -cat <<EOF | patch provider.yaml -@@ -4,13 +4,14 @@ - - # Documentation: https://github.com/fluencelabs/cli/tree/main/docs/configs/provider.md - --version: 0 -- - env: local - - computePeers: - nox-0: - computeUnits: 32 -+ nox: -+ rawConfig: | -+ local = true - nox-1: - computeUnits: 32 - nox-2: -@@ -24,3 +25,39 @@ - - nox-0 - - nox-1 - - nox-2 -+ -+nox: -+ # you can write config overrides with yaml syntax using camelCase -+ systemServices: -+ enable: -+ - aqua-apfs -+ - decider -+ -+ # or you can write config in toml -+ # some options can be set only with rawConfig -+ # this has highest priority when merging -+ rawConfig: | -+ allowed_binaries = [ -+ "/usr/bin/curl", -+ # we need to set path to ipfs binary that was downloaded by role -+ "{{ nox_dir }}/ipfs", -+ ] -+ -+ local = false -+ bootstrap_nodes = [ -+ "/ip4/172.30.10.10/tcp/7771" -+ ] -+ -+ [system_services.aqua_ipfs] -+ ipfs_binary_path = "{{ nox_dir }}/ipfs" -+ external_api_multiaddr = "/ip4/127.0.0.1/tcp/5001" -+ local_api_multiaddr = "/ip4/172.30.10.95/tcp/5001" -+ -+ [system_services.decider] -+ decider_period_sec = 10 -+ worker_ipfs_multiaddr = "/ip4/172.30.10.95/tcp/5001" -+ network_api_endpoint = "http://172.30.10.85:8545" -+ network_id = 31337 -+ start_block = "earliest" -+ matcher_address = "0x0e1F3B362E22B2Dc82C9E35d6e62998C7E8e2349" -+ wallet_key = "0x3cc23e0227bd17ea5d6ea9d42b5eaa53ad41b1974de4755c79fe236d361a6fd5" -EOF -``` - -- Regenerate nox configs - -```bash -fluence provider gen -``` - -- Change directory back - -```bash -cd ../../ -``` - - Create and activate python virtual environment ```bash @@ -215,10 +76,6 @@ source ~/.virtualenvs/fluence/nox-ansible-demo/bin/activate - Install python dependencies ```bash -cat << EOF > requirements.txt -ansible==9.2.0 -podman-compose -EOF pip3 install -r requirements.txt ``` @@ -228,49 +85,6 @@ pip3 install -r requirements.txt ansible-galaxy collection install fluencelabs.provider ``` -- Create ansible inventory file - -```bash -cat << EOF > inventory.yml -all: - children: - servers: - hosts: - server-0: - ansible_port: 2200 - nox_instances: [0] - server-1: - ansible_port: 2201 - nox_instances: [1,2] - vars: - ansible_user: "ubuntu" - ansible_password: "ubuntu" - ansible_host: "127.0.0.1" - # fluencelabs.provider.nox variables - nox_version: "0.18.0" # hardcoded compatible with fcli 0.18.1 - nox_project_dir: "demo" - # fluencelabs.provider.ipfs_cli variables - ipfs_cli_version: "0.26.0" -EOF -``` - -- Create playbook - -```bash -cat <<EOF > nox.yml -- hosts: "all" - become: true - roles: - - "fluencelabs.provider.nox" -EOF -``` - -- Copy `podmad-compose.yml` - -```bash -cp ../podman-compose.yml . -``` - - Start services and servers ```bash @@ -283,7 +97,7 @@ podman-compose up -d --build ansible-playbook nox.yml -i inventory.yml ``` -- When finished, run cleanup +- When finished run cleanup ```bash podman-compose down @@ -291,4 +105,7 @@ podman-compose down ## Do some things with Nox network -TODO +TODO: + +- integrate IPC +- add provider registration diff --git a/example/files/demo/.fluence/configs/nox-0_Config.toml b/example/files/demo/.fluence/configs/nox-0_Config.toml index 82b1ea1..771d62d 100644 --- a/example/files/demo/.fluence/configs/nox-0_Config.toml +++ b/example/files/demo/.fluence/configs/nox-0_Config.toml @@ -1,21 +1,30 @@ aquavm_pool_size = 2 +local = true +bootstrap_nodes = [ "/ip4/172.30.10.10/tcp/7771" ] tcp_port = 7_771 websocket_port = 9_991 http_port = 18_080 -allowed_binaries = [ "/usr/bin/curl", "{{ nox_dir }}/ipfs" ] -local = true -bootstrap_nodes = [ "/ip4/172.30.10.10/tcp/7771" ] -[system_services.aqua_ipfs] -ipfs_binary_path = "{{ nox_dir }}/ipfs" -external_api_multiaddr = "/ip4/127.0.0.1/tcp/5001" -local_api_multiaddr = "/ip4/172.30.10.95/tcp/5001" +[system_services] +enable = [ "aqua-apfs", "decider" ] + + [system_services.aqua_ipfs] + external_api_multiaddr = "/ip4/127.0.0.1/tcp/5001" + local_api_multiaddr = "/ip4/172.30.10.95/tcp/5001" + + [system_services.decider] + decider_period_sec = 10 + worker_ipfs_multiaddr = "/ip4/172.30.10.95/tcp/5001" + network_api_endpoint = "http://172.30.10.85:8545" + network_id = 31_337 + start_block = "earliest" + matcher_address = "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c" + wallet_key = "0x3cc23e0227bd17ea5d6ea9d42b5eaa53ad41b1974de4755c79fe236d361a6fd5" -[system_services.decider] -decider_period_sec = 10 -worker_ipfs_multiaddr = "/ip4/172.30.10.95/tcp/5001" -network_api_endpoint = "http://172.30.10.85:8545" +[chain_config] +http_endpoint = "http://172.30.10.85:8545" +core_contract_address = "0x0B306BF915C4d645ff596e518fAf3F9669b97016" +cc_contract_address = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" +market_contract_address = "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c" network_id = 31_337 -start_block = "earliest" -matcher_address = "0x0e1F3B362E22B2Dc82C9E35d6e62998C7E8e2349" wallet_key = "0x3cc23e0227bd17ea5d6ea9d42b5eaa53ad41b1974de4755c79fe236d361a6fd5" diff --git a/example/files/demo/.fluence/configs/nox-1_Config.toml b/example/files/demo/.fluence/configs/nox-1_Config.toml index 2956ba7..c213681 100644 --- a/example/files/demo/.fluence/configs/nox-1_Config.toml +++ b/example/files/demo/.fluence/configs/nox-1_Config.toml @@ -1,21 +1,30 @@ aquavm_pool_size = 2 +local = false +bootstrap_nodes = [ "/ip4/172.30.10.10/tcp/7771" ] tcp_port = 7_772 websocket_port = 9_992 http_port = 18_081 -allowed_binaries = [ "/usr/bin/curl", "{{ nox_dir }}/ipfs" ] -local = false -bootstrap_nodes = [ "/ip4/172.30.10.10/tcp/7771" ] -[system_services.aqua_ipfs] -ipfs_binary_path = "{{ nox_dir }}/ipfs" -external_api_multiaddr = "/ip4/127.0.0.1/tcp/5001" -local_api_multiaddr = "/ip4/172.30.10.95/tcp/5001" +[system_services] +enable = [ "aqua-apfs", "decider" ] + + [system_services.aqua_ipfs] + external_api_multiaddr = "/ip4/127.0.0.1/tcp/5001" + local_api_multiaddr = "/ip4/172.30.10.95/tcp/5001" + + [system_services.decider] + decider_period_sec = 10 + worker_ipfs_multiaddr = "/ip4/172.30.10.95/tcp/5001" + network_api_endpoint = "http://172.30.10.85:8545" + network_id = 31_337 + start_block = "earliest" + matcher_address = "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c" + wallet_key = "0x089162470bcfc93192b95bff0a1860d063266875c782af9d882fcca125323b41" -[system_services.decider] -decider_period_sec = 10 -worker_ipfs_multiaddr = "/ip4/172.30.10.95/tcp/5001" -network_api_endpoint = "http://172.30.10.85:8545" +[chain_config] +http_endpoint = "http://172.30.10.85:8545" +core_contract_address = "0x0B306BF915C4d645ff596e518fAf3F9669b97016" +cc_contract_address = "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d" +market_contract_address = "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c" network_id = 31_337 -start_block = "earliest" -matcher_address = "0x0e1F3B362E22B2Dc82C9E35d6e62998C7E8e2349" -wallet_key = "0x3cc23e0227bd17ea5d6ea9d42b5eaa53ad41b1974de4755c79fe236d361a6fd5" +wallet_key = "0x089162470bcfc93192b95bff0a1860d063266875c782af9d882fcca125323b41" diff --git a/example/files/demo/.fluence/configs/nox-2_Config.toml b/example/files/demo/.fluence/configs/nox-2_Config.toml deleted file mode 100644 index 0d0ad43..0000000 --- a/example/files/demo/.fluence/configs/nox-2_Config.toml +++ /dev/null @@ -1,21 +0,0 @@ -aquavm_pool_size = 2 -tcp_port = 7_773 -websocket_port = 9_993 -http_port = 18_082 -allowed_binaries = [ "/usr/bin/curl", "{{ nox_dir }}/ipfs" ] -local = false -bootstrap_nodes = [ "/ip4/172.30.10.10/tcp/7771" ] - -[system_services.aqua_ipfs] -ipfs_binary_path = "{{ nox_dir }}/ipfs" -external_api_multiaddr = "/ip4/127.0.0.1/tcp/5001" -local_api_multiaddr = "/ip4/172.30.10.95/tcp/5001" - -[system_services.decider] -decider_period_sec = 10 -worker_ipfs_multiaddr = "/ip4/172.30.10.95/tcp/5001" -network_api_endpoint = "http://172.30.10.85:8545" -network_id = 31_337 -start_block = "earliest" -matcher_address = "0x0e1F3B362E22B2Dc82C9E35d6e62998C7E8e2349" -wallet_key = "0x3cc23e0227bd17ea5d6ea9d42b5eaa53ad41b1974de4755c79fe236d361a6fd5" diff --git a/example/files/demo/.fluence/provider-secrets.yaml b/example/files/demo/.fluence/provider-secrets.yaml index a979500..a50a456 100644 --- a/example/files/demo/.fluence/provider-secrets.yaml +++ b/example/files/demo/.fluence/provider-secrets.yaml @@ -13,6 +13,3 @@ noxes: nox-1: networkKey: kgWAtvlfhYZnJflH6c+Ibqaxi0/LjEosBscn8nWqQ/k= signingWallet: "0x089162470bcfc93192b95bff0a1860d063266875c782af9d882fcca125323b41" - nox-2: - networkKey: RSJ7ZXY9WEzFNW1E2PYE4Jb9G/9FBAMDoaZG3mGcyrg= - signingWallet: "0xdacd4b197ee7e9efdd5db1921c6c558d88e2c8b69902b8bafc812fb226a6b5e0" diff --git a/example/files/demo/.fluence/schemas/env.json b/example/files/demo/.fluence/schemas/env.json index 15ba59d..9c03303 100644 --- a/example/files/demo/.fluence/schemas/env.json +++ b/example/files/demo/.fluence/schemas/env.json @@ -9,8 +9,7 @@ "description": "Fluence environment to connect to", "type": "string", "enum": [ - "kras", - "testnet", + "dar", "stage", "local", "custom" @@ -18,7 +17,7 @@ "nullable": true }, "version": { - "type": "number", + "type": "integer", "const": 0 } }, diff --git a/example/files/demo/.fluence/schemas/provider-secrets.json b/example/files/demo/.fluence/schemas/provider-secrets.json index a66b141..0edd832 100644 --- a/example/files/demo/.fluence/schemas/provider-secrets.json +++ b/example/files/demo/.fluence/schemas/provider-secrets.json @@ -6,7 +6,7 @@ "additionalProperties": false, "properties": { "version": { - "type": "number", + "type": "integer", "const": 0, "description": "Config version" }, diff --git a/example/files/demo/.fluence/schemas/provider.json b/example/files/demo/.fluence/schemas/provider.json index 4654543..1aa599a 100644 --- a/example/files/demo/.fluence/schemas/provider.json +++ b/example/files/demo/.fluence/schemas/provider.json @@ -5,15 +5,10 @@ "type": "object", "additionalProperties": false, "properties": { - "env": { - "description": "Defines the the environment for which you intend to generate nox configuration", + "providerName": { + "description": "Provider name. Must not be empty", "type": "string", - "enum": [ - "kras", - "testnet", - "stage", - "local" - ] + "minLength": 1 }, "offers": { "description": "A map with offer names as keys and offers as values", @@ -24,12 +19,8 @@ "additionalProperties": false, "properties": { "minPricePerWorkerEpoch": { - "type": "number", - "description": "Minimum price per worker epoch. This number is multiplied by 10^18" - }, - "maxCollateralPerWorker": { - "type": "number", - "description": "Max collateral per worker. This number is multiplied by 10^18" + "type": "string", + "description": "Minimum price per worker epoch in USDC" }, "computePeers": { "description": "Number of Compute Units for this Compute Peer", @@ -45,11 +36,24 @@ "type": "string" }, "nullable": true + }, + "minProtocolVersion": { + "type": "integer", + "description": "Min protocol version. Must be less then or equal to maxProtocolVersion. Default: 1", + "nullable": true, + "default": 1, + "minimum": 1 + }, + "maxProtocolVersion": { + "type": "integer", + "description": "Max protocol version. Must be more then or equal to minProtocolVersion. Default: 1", + "nullable": true, + "default": 1, + "minimum": 1 } }, "required": [ "minPricePerWorkerEpoch", - "maxCollateralPerWorker", "computePeers" ] }, @@ -60,12 +64,8 @@ "additionalProperties": false, "properties": { "minPricePerWorkerEpoch": { - "type": "number", - "description": "Minimum price per worker epoch. This number is multiplied by 10^18" - }, - "maxCollateralPerWorker": { - "type": "number", - "description": "Max collateral per worker. This number is multiplied by 10^18" + "type": "string", + "description": "Minimum price per worker epoch in USDC" }, "computePeers": { "description": "Number of Compute Units for this Compute Peer", @@ -81,11 +81,24 @@ "type": "string" }, "nullable": true + }, + "minProtocolVersion": { + "type": "integer", + "description": "Min protocol version. Must be less then or equal to maxProtocolVersion. Default: 1", + "nullable": true, + "default": 1, + "minimum": 1 + }, + "maxProtocolVersion": { + "type": "integer", + "description": "Max protocol version. Must be more then or equal to minProtocolVersion. Default: 1", + "nullable": true, + "default": 1, + "minimum": 1 } }, "required": [ "minPricePerWorkerEpoch", - "maxCollateralPerWorker", "computePeers" ] } @@ -101,8 +114,7 @@ "additionalProperties": false, "properties": { "computeUnits": { - "type": "number", - "nullable": true, + "type": "integer", "description": "How many compute units should nox have. Default: 32 (each compute unit requires 2GB of RAM)" }, "nox": { @@ -111,22 +123,22 @@ "properties": { "tcpPort": { "nullable": true, - "type": "number", + "type": "integer", "description": "Both host and container TCP port to use. Default: for each nox a unique port is assigned starting from 7771" }, "websocketPort": { "nullable": true, - "type": "number", + "type": "integer", "description": "Both host and container WebSocket port to use. Default: for each nox a unique port is assigned starting from 9991" }, "httpPort": { "nullable": true, - "type": "number", + "type": "integer", "description": "Both host and container HTTP port to use. Default: for each nox a unique port is assigned starting from 18080" }, "aquavmPoolSize": { "nullable": true, - "type": "number", + "type": "integer", "description": "Number of aquavm instances to run. Default: 2" }, "systemServices": { @@ -170,7 +182,7 @@ "properties": { "deciderPeriodSec": { "nullable": true, - "type": "number", + "type": "integer", "description": "Decider period in seconds" }, "workerIpfsMultiaddr": { @@ -185,7 +197,7 @@ }, "networkId": { "nullable": true, - "type": "number", + "type": "integer", "description": "Network ID" }, "startBlock": { @@ -209,6 +221,109 @@ }, "required": [] }, + "effectors": { + "nullable": true, + "type": "object", + "description": "Effectors to allow on the nox", + "additionalProperties": { + "type": "object", + "description": "Effector configuration", + "additionalProperties": false, + "properties": { + "wasmCID": { + "type": "string", + "description": "Wasm CID of the effector" + }, + "allowedBinaries": { + "type": "object", + "description": "Allowed binaries", + "additionalProperties": { + "type": "string" + }, + "properties": { + "curl": { + "type": "string" + } + }, + "required": [] + } + }, + "required": [ + "wasmCID", + "allowedBinaries" + ] + }, + "properties": { + "effectorName": { + "type": "object", + "description": "Effector configuration", + "additionalProperties": false, + "properties": { + "wasmCID": { + "type": "string", + "description": "Wasm CID of the effector" + }, + "allowedBinaries": { + "type": "object", + "description": "Allowed binaries", + "additionalProperties": { + "type": "string" + }, + "properties": { + "curl": { + "type": "string" + } + }, + "required": [] + } + }, + "required": [ + "wasmCID", + "allowedBinaries" + ] + } + }, + "required": [] + }, + "chainConfig": { + "nullable": true, + "type": "object", + "description": "Chain config", + "additionalProperties": false, + "properties": { + "httpEndpoint": { + "nullable": true, + "type": "string", + "description": "HTTP endpoint of the chain. Same as decider" + }, + "coreContractAddress": { + "nullable": true, + "type": "string", + "description": "Core contract address" + }, + "ccContractAddress": { + "nullable": true, + "type": "string", + "description": "Capacity commitment contract address" + }, + "marketContractAddress": { + "nullable": true, + "type": "string", + "description": "Market contract address" + }, + "networkId": { + "nullable": true, + "type": "integer", + "description": "Network ID" + }, + "walletKey": { + "nullable": true, + "type": "string", + "description": "Wallet key" + } + }, + "required": [] + }, "rawConfig": { "nullable": true, "type": "string", @@ -220,7 +335,9 @@ "additionalProperties": false } }, - "required": [] + "required": [ + "computeUnits" + ] }, "properties": { "ComputePeer": { @@ -229,8 +346,7 @@ "additionalProperties": false, "properties": { "computeUnits": { - "type": "number", - "nullable": true, + "type": "integer", "description": "How many compute units should nox have. Default: 32 (each compute unit requires 2GB of RAM)" }, "nox": { @@ -239,22 +355,22 @@ "properties": { "tcpPort": { "nullable": true, - "type": "number", + "type": "integer", "description": "Both host and container TCP port to use. Default: for each nox a unique port is assigned starting from 7771" }, "websocketPort": { "nullable": true, - "type": "number", + "type": "integer", "description": "Both host and container WebSocket port to use. Default: for each nox a unique port is assigned starting from 9991" }, "httpPort": { "nullable": true, - "type": "number", + "type": "integer", "description": "Both host and container HTTP port to use. Default: for each nox a unique port is assigned starting from 18080" }, "aquavmPoolSize": { "nullable": true, - "type": "number", + "type": "integer", "description": "Number of aquavm instances to run. Default: 2" }, "systemServices": { @@ -298,7 +414,7 @@ "properties": { "deciderPeriodSec": { "nullable": true, - "type": "number", + "type": "integer", "description": "Decider period in seconds" }, "workerIpfsMultiaddr": { @@ -313,7 +429,7 @@ }, "networkId": { "nullable": true, - "type": "number", + "type": "integer", "description": "Network ID" }, "startBlock": { @@ -337,6 +453,109 @@ }, "required": [] }, + "effectors": { + "nullable": true, + "type": "object", + "description": "Effectors to allow on the nox", + "additionalProperties": { + "type": "object", + "description": "Effector configuration", + "additionalProperties": false, + "properties": { + "wasmCID": { + "type": "string", + "description": "Wasm CID of the effector" + }, + "allowedBinaries": { + "type": "object", + "description": "Allowed binaries", + "additionalProperties": { + "type": "string" + }, + "properties": { + "curl": { + "type": "string" + } + }, + "required": [] + } + }, + "required": [ + "wasmCID", + "allowedBinaries" + ] + }, + "properties": { + "effectorName": { + "type": "object", + "description": "Effector configuration", + "additionalProperties": false, + "properties": { + "wasmCID": { + "type": "string", + "description": "Wasm CID of the effector" + }, + "allowedBinaries": { + "type": "object", + "description": "Allowed binaries", + "additionalProperties": { + "type": "string" + }, + "properties": { + "curl": { + "type": "string" + } + }, + "required": [] + } + }, + "required": [ + "wasmCID", + "allowedBinaries" + ] + } + }, + "required": [] + }, + "chainConfig": { + "nullable": true, + "type": "object", + "description": "Chain config", + "additionalProperties": false, + "properties": { + "httpEndpoint": { + "nullable": true, + "type": "string", + "description": "HTTP endpoint of the chain. Same as decider" + }, + "coreContractAddress": { + "nullable": true, + "type": "string", + "description": "Core contract address" + }, + "ccContractAddress": { + "nullable": true, + "type": "string", + "description": "Capacity commitment contract address" + }, + "marketContractAddress": { + "nullable": true, + "type": "string", + "description": "Market contract address" + }, + "networkId": { + "nullable": true, + "type": "integer", + "description": "Network ID" + }, + "walletKey": { + "nullable": true, + "type": "string", + "description": "Wallet key" + } + }, + "required": [] + }, "rawConfig": { "nullable": true, "type": "string", @@ -348,7 +567,9 @@ "additionalProperties": false } }, - "required": [] + "required": [ + "computeUnits" + ] } }, "required": [] @@ -359,22 +580,22 @@ "properties": { "tcpPort": { "nullable": true, - "type": "number", + "type": "integer", "description": "Both host and container TCP port to use. Default: for each nox a unique port is assigned starting from 7771" }, "websocketPort": { "nullable": true, - "type": "number", + "type": "integer", "description": "Both host and container WebSocket port to use. Default: for each nox a unique port is assigned starting from 9991" }, "httpPort": { "nullable": true, - "type": "number", + "type": "integer", "description": "Both host and container HTTP port to use. Default: for each nox a unique port is assigned starting from 18080" }, "aquavmPoolSize": { "nullable": true, - "type": "number", + "type": "integer", "description": "Number of aquavm instances to run. Default: 2" }, "systemServices": { @@ -418,7 +639,7 @@ "properties": { "deciderPeriodSec": { "nullable": true, - "type": "number", + "type": "integer", "description": "Decider period in seconds" }, "workerIpfsMultiaddr": { @@ -433,7 +654,7 @@ }, "networkId": { "nullable": true, - "type": "number", + "type": "integer", "description": "Network ID" }, "startBlock": { @@ -457,6 +678,109 @@ }, "required": [] }, + "effectors": { + "nullable": true, + "type": "object", + "description": "Effectors to allow on the nox", + "additionalProperties": { + "type": "object", + "description": "Effector configuration", + "additionalProperties": false, + "properties": { + "wasmCID": { + "type": "string", + "description": "Wasm CID of the effector" + }, + "allowedBinaries": { + "type": "object", + "description": "Allowed binaries", + "additionalProperties": { + "type": "string" + }, + "properties": { + "curl": { + "type": "string" + } + }, + "required": [] + } + }, + "required": [ + "wasmCID", + "allowedBinaries" + ] + }, + "properties": { + "effectorName": { + "type": "object", + "description": "Effector configuration", + "additionalProperties": false, + "properties": { + "wasmCID": { + "type": "string", + "description": "Wasm CID of the effector" + }, + "allowedBinaries": { + "type": "object", + "description": "Allowed binaries", + "additionalProperties": { + "type": "string" + }, + "properties": { + "curl": { + "type": "string" + } + }, + "required": [] + } + }, + "required": [ + "wasmCID", + "allowedBinaries" + ] + } + }, + "required": [] + }, + "chainConfig": { + "nullable": true, + "type": "object", + "description": "Chain config", + "additionalProperties": false, + "properties": { + "httpEndpoint": { + "nullable": true, + "type": "string", + "description": "HTTP endpoint of the chain. Same as decider" + }, + "coreContractAddress": { + "nullable": true, + "type": "string", + "description": "Core contract address" + }, + "ccContractAddress": { + "nullable": true, + "type": "string", + "description": "Capacity commitment contract address" + }, + "marketContractAddress": { + "nullable": true, + "type": "string", + "description": "Market contract address" + }, + "networkId": { + "nullable": true, + "type": "integer", + "description": "Network ID" + }, + "walletKey": { + "nullable": true, + "type": "string", + "description": "Wallet key" + } + }, + "required": [] + }, "rawConfig": { "nullable": true, "type": "string", @@ -467,8 +791,71 @@ "nullable": true, "additionalProperties": false }, + "capacityCommitments": { + "description": "A map with nox names as keys and capacity commitments as values", + "type": "object", + "additionalProperties": { + "type": "object", + "description": "Defines a capacity commitment", + "required": [ + "duration", + "rewardDelegationRate" + ], + "additionalProperties": false, + "properties": { + "duration": { + "type": "string", + "default": "100 days", + "description": "Duration of the commitment in human-readable format. Example: 1 months 1 days" + }, + "delegator": { + "type": "string", + "description": "Delegator address", + "nullable": true + }, + "rewardDelegationRate": { + "type": "number", + "minimum": 0, + "maximum": 100, + "description": "Reward delegation rate in percent", + "default": 7 + } + } + }, + "properties": { + "noxName": { + "type": "object", + "description": "Defines a capacity commitment", + "required": [ + "duration", + "rewardDelegationRate" + ], + "additionalProperties": false, + "properties": { + "duration": { + "type": "string", + "default": "100 days", + "description": "Duration of the commitment in human-readable format. Example: 1 months 1 days" + }, + "delegator": { + "type": "string", + "description": "Delegator address", + "nullable": true + }, + "rewardDelegationRate": { + "type": "number", + "minimum": 0, + "maximum": 100, + "description": "Reward delegation rate in percent", + "default": 7 + } + } + } + }, + "required": [] + }, "version": { - "type": "number", + "type": "integer", "const": 0, "description": "Config version" } @@ -477,6 +864,7 @@ "version", "computePeers", "offers", - "env" + "providerName", + "capacityCommitments" ] } diff --git a/example/files/demo/.fluence/secrets/nox-2.txt b/example/files/demo/.fluence/secrets/nox-2.txt deleted file mode 100644 index 848f8fe..0000000 --- a/example/files/demo/.fluence/secrets/nox-2.txt +++ /dev/null @@ -1 +0,0 @@ -RSJ7ZXY9WEzFNW1E2PYE4Jb9G/9FBAMDoaZG3mGcyrg= \ No newline at end of file diff --git a/example/files/demo/provider.yaml b/example/files/demo/provider.yaml index 684f3a4..bf4f999 100644 --- a/example/files/demo/provider.yaml +++ b/example/files/demo/provider.yaml @@ -3,28 +3,34 @@ # Defines config used for provider set up # Documentation: https://github.com/fluencelabs/cli/tree/main/docs/configs/provider.md +# +version: 0 -env: local +providerName: demo computePeers: nox-0: - computeUnits: 32 + computeUnits: 1 nox: rawConfig: | local = true nox-1: - computeUnits: 32 - nox-2: - computeUnits: 32 + computeUnits: 1 offers: offer: - maxCollateralPerWorker: 1 - minPricePerWorkerEpoch: 0.00001 + minPricePerWorkerEpoch: "0.00001" computePeers: - nox-0 - nox-1 - - nox-2 + +capacityCommitments: + nox-0: + duration: 100 minutes + rewardDelegationRate: 7 + nox-1: + duration: 100 minutes + rewardDelegationRate: 7 nox: # you can write config overrides with yaml syntax using camelCase @@ -32,32 +38,21 @@ nox: enable: - aqua-apfs - decider + decider: + workerIpfsMultiaddr: "/ip4/172.30.10.95/tcp/5001" + networkApiEndpoint: "http://172.30.10.85:8545" + aquaIpfs: + externalApiMultiaddr: "/ip4/127.0.0.1/tcp/5001" + localApiMultiaddr: "/ip4/172.30.10.95/tcp/5001" + + chainConfig: + httpEndpoint: "http://172.30.10.85:8545" # or you can write config in toml # some options can be set only with rawConfig # this has highest priority when merging rawConfig: | - allowed_binaries = [ - "/usr/bin/curl", - # we need to set path to ipfs binary that was downloaded by role - "{{ nox_dir }}/ipfs", - ] - local = false bootstrap_nodes = [ "/ip4/172.30.10.10/tcp/7771" ] - - [system_services.aqua_ipfs] - ipfs_binary_path = "{{ nox_dir }}/ipfs" - external_api_multiaddr = "/ip4/127.0.0.1/tcp/5001" - local_api_multiaddr = "/ip4/172.30.10.95/tcp/5001" - - [system_services.decider] - decider_period_sec = 10 - worker_ipfs_multiaddr = "/ip4/172.30.10.95/tcp/5001" - network_api_endpoint = "http://172.30.10.85:8545" - network_id = 31337 - start_block = "earliest" - matcher_address = "0x0e1F3B362E22B2Dc82C9E35d6e62998C7E8e2349" - wallet_key = "0x3cc23e0227bd17ea5d6ea9d42b5eaa53ad41b1974de4755c79fe236d361a6fd5" diff --git a/example/inventory.yml b/example/inventory.yml index 00b0a63..fc3591d 100644 --- a/example/inventory.yml +++ b/example/inventory.yml @@ -4,17 +4,20 @@ all: hosts: server-0: ansible_port: 2200 - nox_instances: [0] + fluence_instance_id: "nox-0" server-1: ansible_port: 2201 - nox_instances: [1,2] + fluence_instance_id: "nox-1" vars: ansible_user: "ubuntu" ansible_password: "ubuntu" ansible_host: "127.0.0.1" ansible_ssh_common_args: "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" + # fluencelabs.provider variables + fluence_project_dir: "demo" # fluencelabs.provider.nox variables - nox_version: "0.18.0" # hardcoded compatible with fcli 0.18.1 - nox_project_dir: "demo" + nox_version: "0.22.0" # hardcoded compatible with fcli 0.15.17 + # fluencelabs.provider.ccp variables + ccp_version: "0.2.0" # fluencelabs.provider.ipfs_cli variables ipfs_cli_version: "0.26.0" diff --git a/example/podman-compose.yml b/example/podman-compose.yml index 70ef13e..f6427be 100644 --- a/example/podman-compose.yml +++ b/example/podman-compose.yml @@ -39,14 +39,39 @@ services: ipv4_address: 172.30.10.11 # services required for Nox to work - chain: - image: docker.io/fluencelabs/chain-rpc:0.2.20 + chain-rpc: + image: fluencelabs/chain-rpc:0.8.0 ports: - 8545:8545 + volumes: + - chain-rpc:/data + environment: + LOCAL_CHAIN_BLOCK_MINING_INTERVAL: 1 + healthcheck: + test: "curl -s -X POST 'http://localhost:8545' -H 'Content-Type: + application/json' --data '{\"jsonrpc\":\"2.0\", + \"method\":\"eth_chainId\", \"params\":[], \"id\":1}' | jq -e '.result + != null'" + interval: 8s + timeout: 10s + retries: 20 networks: demo: ipv4_address: 172.30.10.85 + chain-deploy-script: + image: fluencelabs/chain-deploy-script:0.8.0 + environment: + CHAIN_RPC_URL: http://chain-rpc:8545 + MAX_FAILED_RATIO: "9999" + IS_MOCKED_RANDOMX: "true" + MIN_DURATION: 0 + depends_on: + chain-rpc: + condition: service_healthy + networks: + demo: + ipfs: image: docker.io/ipfs/kubo:v0.26.0 ports: diff --git a/extensions/molecule/files/molecule/.fluence/configs/nox-1_Config.toml b/extensions/molecule/files/molecule/.fluence/configs/nox-1_Config.toml deleted file mode 100644 index 0165879..0000000 --- a/extensions/molecule/files/molecule/.fluence/configs/nox-1_Config.toml +++ /dev/null @@ -1,25 +0,0 @@ -aquavm_pool_size = 2 -tcp_port = 7_772 -websocket_port = 9_992 -http_port = 18_081 - -allowed_binaries = [ - "/usr/bin/curl", - "/usr/local/bin/ipfs", -] - -[system_services] -enable = [ "aqua-ipfs", "decider" ] - - [system_services.aqua_ipfs] - external_api_multiaddr = "/ip4/127.0.0.1/tcp/5001" - local_api_multiaddr = "/dns4/ipfs/tcp/5001" - - [system_services.decider] - decider_period_sec = 10 - worker_ipfs_multiaddr = "/dns4/ipfs/tcp/5001" - network_api_endpoint = "http://chain:8545" - network_id = 31_337 - start_block = "earliest" - matcher_address = "0x0e1F3B362E22B2Dc82C9E35d6e62998C7E8e2349" - wallet_key = "0x089162470bcfc93192b95bff0a1860d063266875c782af9d882fcca125323b41" diff --git a/extensions/molecule/files/molecule/.fluence/configs/nox-2_Config.toml b/extensions/molecule/files/molecule/.fluence/configs/nox-2_Config.toml deleted file mode 100644 index e84553e..0000000 --- a/extensions/molecule/files/molecule/.fluence/configs/nox-2_Config.toml +++ /dev/null @@ -1,25 +0,0 @@ -aquavm_pool_size = 2 -tcp_port = 7_773 -websocket_port = 9_993 -http_port = 18_082 - -allowed_binaries = [ - "/usr/bin/curl", - "/usr/local/bin/ipfs", -] - -[system_services] -enable = [ "aqua-ipfs", "decider" ] - - [system_services.aqua_ipfs] - external_api_multiaddr = "/ip4/127.0.0.1/tcp/5001" - local_api_multiaddr = "/dns4/ipfs/tcp/5001" - - [system_services.decider] - decider_period_sec = 10 - worker_ipfs_multiaddr = "/dns4/ipfs/tcp/5001" - network_api_endpoint = "http://chain:8545" - network_id = 31_337 - start_block = "earliest" - matcher_address = "0x0e1F3B362E22B2Dc82C9E35d6e62998C7E8e2349" - wallet_key = "0xdacd4b197ee7e9efdd5db1921c6c558d88e2c8b69902b8bafc812fb226a6b5e0" diff --git a/extensions/molecule/files/molecule/.fluence/secrets/nox-1.txt b/extensions/molecule/files/molecule/.fluence/secrets/nox-1.txt deleted file mode 100644 index feceb23..0000000 --- a/extensions/molecule/files/molecule/.fluence/secrets/nox-1.txt +++ /dev/null @@ -1 +0,0 @@ -hda9vRX8eR3VFlTVNqZ8jhvw1TnNrKVPB+lCxHefOGQ= \ No newline at end of file diff --git a/extensions/molecule/files/molecule/.fluence/secrets/nox-2.txt b/extensions/molecule/files/molecule/.fluence/secrets/nox-2.txt deleted file mode 100644 index 75d4133..0000000 --- a/extensions/molecule/files/molecule/.fluence/secrets/nox-2.txt +++ /dev/null @@ -1 +0,0 @@ -vO8ost9xZRCsQWiMc/ttsVjcUteV8BqJnojnkBVsJ+Y= \ No newline at end of file diff --git a/extensions/molecule/prepare.yml b/extensions/molecule/prepare.yml deleted file mode 100644 index f9d14f5..0000000 --- a/extensions/molecule/prepare.yml +++ /dev/null @@ -1,16 +0,0 @@ -- name: prepare - hosts: all - become: true - vars: - nox_version: "0.16.13" - nox_project_dir: "molecule" - nox_instances: [0] - ipfs_cli_version: "0.25.0" - - collections: - - fluencelabs.provider - - tasks: - - name: Run nox role - include_role: - name: nox diff --git a/extensions/molecule/tests/test_default.py b/extensions/molecule/tests/test_default.py deleted file mode 100644 index fb180ee..0000000 --- a/extensions/molecule/tests/test_default.py +++ /dev/null @@ -1,50 +0,0 @@ -import testinfra.utils.ansible_runner -import pytest -import os - -testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( - os.environ["MOLECULE_INVENTORY_FILE"]).get_hosts("all") - - -@pytest.mark.parametrize("directory", [ - "/opt/nox/nox-1", - "/opt/nox/nox-2", -]) -def test_nox_directories(host, directory): - d = host.file(directory) - - assert d.is_directory - assert d.exists - assert d.user == "nox" - assert d.mode == 493 - -def test_nox_cleanup(host): - directory = host.file("/opt/nox/nox-0") - service = host.service("nox-@0") - - assert not service.is_running - assert not service.is_enabled - assert not directory.exists - - -def test_ipfs_download(host): - f = host.file("/opt/nox/ipfs") - - assert f.is_file - assert f.exists - - -@pytest.mark.parametrize("service", [ - "nox-@1", - "nox-@2", -]) -def test_nox_is_running(host, service): - service = host.service(service) - - assert service.is_running - assert service.is_enabled - - -def test_user_created(host): - assert host.user("nox").exists - assert "nox" in host.user("nox").groups diff --git a/extensions/molecule/converge.yml b/molecule/converge.yml similarity index 57% rename from extensions/molecule/converge.yml rename to molecule/converge.yml index c757ccc..d510c42 100644 --- a/extensions/molecule/converge.yml +++ b/molecule/converge.yml @@ -1,10 +1,13 @@ -- name: nox role +- name: role hosts: all become: true vars: - nox_version: "0.16.13" - nox_project_dir: "molecule" + nox_version: "0.22.0" ipfs_cli_version: "0.25.0" + ccp_version: "0.2.0" + + fluence_instance_id: "peer-0" + fluence_project_dir: "molecule" collections: - fluencelabs.provider diff --git a/molecule/debian12/molecule.yml b/molecule/debian12/molecule.yml new file mode 100644 index 0000000..818d40d --- /dev/null +++ b/molecule/debian12/molecule.yml @@ -0,0 +1,25 @@ +driver: + name: molecule-qemu + +platforms: + - name: debian12 + image_url: https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2 + image_checksum: sha512:https://cloud.debian.org/images/cloud/bookworm/latest/SHA512SUMS + network_ssh_port: 2229 + +provisioner: + name: ansible + playbooks: + prepare: ../prepare.yml + converge: ../converge.yml + +verifier: + name: testinfra + directory: ../tests + env: + # get rid of the DeprecationWarning messages of third-party libs, + # see https://docs.pytest.org/en/latest/warnings.html#deprecationwarning-and-pendingdeprecationwarning + PYTHONWARNINGS: "ignore:.*U.*mode is deprecated:DeprecationWarning" + options: + # show which tests where executed in test output + v: 1 diff --git a/molecule/files/molecule/.fluence/ccp-configs/peer-0_Config.toml b/molecule/files/molecule/.fluence/ccp-configs/peer-0_Config.toml new file mode 100644 index 0000000..8c79f14 --- /dev/null +++ b/molecule/files/molecule/.fluence/ccp-configs/peer-0_Config.toml @@ -0,0 +1,26 @@ +[rpc-endpoint] +host = "0.0.0.0" +port = "9383" +utility-thread-ids = [1] + +[prometheus-endpoint] +host = "0.0.0.0" +port = "9384" + +[optimizations] +# large-pages = true +# hard-aes = true +# jit = true +# secure = false +# argon2-sse3 = true +# argon2-avx2 = true +# argon2 = true +# msr = false +# threads-per-physical-core = 2 + +[logs] +report-hashrate = false +log-level = "info" + +[state] +path = "/opt/fluence/ccp/state" diff --git a/extensions/molecule/files/molecule/.fluence/configs/nox-0_Config.toml b/molecule/files/molecule/.fluence/configs/peer-0_Config.toml similarity index 100% rename from extensions/molecule/files/molecule/.fluence/configs/nox-0_Config.toml rename to molecule/files/molecule/.fluence/configs/peer-0_Config.toml diff --git a/extensions/molecule/files/molecule/.fluence/secrets/nox-0.txt b/molecule/files/molecule/.fluence/secrets/peer-0.txt similarity index 100% rename from extensions/molecule/files/molecule/.fluence/secrets/nox-0.txt rename to molecule/files/molecule/.fluence/secrets/peer-0.txt diff --git a/extensions/molecule/files/molecule/provider.yaml b/molecule/files/molecule/provider.yaml similarity index 83% rename from extensions/molecule/files/molecule/provider.yaml rename to molecule/files/molecule/provider.yaml index 5399aae..aaad7f5 100644 --- a/extensions/molecule/files/molecule/provider.yaml +++ b/molecule/files/molecule/provider.yaml @@ -4,16 +4,12 @@ # Documentation: https://github.com/fluencelabs/cli/tree/main/docs/configs/provider.md -version: 0 +version: 8 env: local computePeers: - nox-0: - computeUnits: 1 - nox-1: - computeUnits: 1 - nox-2: + peer-0: computeUnits: 1 offers: diff --git a/molecule/tests/test_default.py b/molecule/tests/test_default.py new file mode 100644 index 0000000..6a7f450 --- /dev/null +++ b/molecule/tests/test_default.py @@ -0,0 +1,65 @@ +import testinfra.utils.ansible_runner +import pytest +import os + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ["MOLECULE_INVENTORY_FILE"]).get_hosts("all") + + +@pytest.mark.parametrize("directory", [ + "/opt/fluence/nox", + "/opt/fluence/ccp", +]) +def test_directories(host, directory): + d = host.file(directory) + + assert d.is_directory + assert d.exists + assert d.mode == 493 + + +@pytest.mark.parametrize("config", [ + "/opt/fluence/nox/Config.toml", + "/opt/fluence/ccp/Config.toml", +]) +def test_config(host, config): + d = host.file(config) + + assert d.is_file + assert d.exists + assert d.mode == 416 + + +def test_ipfs_download(host): + f = host.file("/usr/local/bin/ipfs") + + assert f.is_file + assert f.exists + + +@pytest.mark.parametrize("service", [ + "nox", + "ccp", +]) +def test_service_is_running(host, service): + service = host.service(service) + + assert service.is_running + assert service.is_enabled + + +@pytest.mark.parametrize("user", [ + "nox", + "ccp", +]) +def test_user_created(host, user): + assert host.user(user).exists + assert user in host.user(user).groups + + +@pytest.mark.parametrize("package", [ + "libhwloc-dev", + "curl", +]) +def test_packages_installed(host, package): + assert host.package(package).is_installed diff --git a/extensions/molecule/ubuntu2204/molecule.yml b/molecule/ubuntu2204/molecule.yml similarity index 86% rename from extensions/molecule/ubuntu2204/molecule.yml rename to molecule/ubuntu2204/molecule.yml index 5efbfb7..e8cfba7 100644 --- a/extensions/molecule/ubuntu2204/molecule.yml +++ b/molecule/ubuntu2204/molecule.yml @@ -9,15 +9,12 @@ platforms: provisioner: name: ansible - env: - ANSIBLE_ROLES_PATH: "../../../roles" + config_options: + defaults: + collections_path: ../.. playbooks: prepare: ../prepare.yml converge: ../converge.yml - inventory: - group_vars: - all: - nox_instances: [1, 2] verifier: name: testinfra diff --git a/requirements.txt b/requirements.txt index 877738f..d5a618b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ -ansible==8.6.1 +ansible==9.3.0 # molecule pytest==7.2.1 pytest-testinfra==7.0.0 -molecule==6.0.2 +molecule==24.2.0 molecule-qemu==0.5.7 diff --git a/roles/ccp/README.md b/roles/ccp/README.md new file mode 100644 index 0000000..dc31fd3 --- /dev/null +++ b/roles/ccp/README.md @@ -0,0 +1,105 @@ +# fluencelabs.provider.ccp + +Install and configure [ccp](https://github.com/fluencelabs/capacity-commitment-peer/) - Fluence capacity-commitment-prover + +## Usage + +See this [example](https://github.com/fluencelabs/ansible/blob/main/example/) + +### Cleanup ccp state + +Rerun playbook with `ccp_cleanup_state` set to `true`: +```bash +ansible-playbook ccp.yml -e "ccp_cleanup_state=true" +``` + +### Install ccp snapshot from PR + +Only for Fluence Labs members. + +- Go to GitHub to e2e run from your PR, for example + https://github.com/fluencelabs/capacity-commitment-peer/actions/runs/7409293504 - `7409293504` is + run id +- Rerun role providing your `GITHUB_TOKEN` as env variable: + ```bash + GITHUB_TOKEN=<your_token> ansible-playbook ccp.yml -e "ccp_run_id=7409293504" + ``` + +## Role Variables + +See [defaults/](https://github.com/fluencelabs/ansible/blob/main/roles/ccp/defaults) for details and examples. + +#### `fluence_project_dir` + +- directory that contains provider settings, configs and secrets generated by + [Fluence CLI](https://github.com/fluencelabs/cli) from `provider.yaml` config. + Shared in collection. +- type: string + +Should be put to `files/` directory where you run this role. + +#### `fluence_instance_id` + +- instance id to assing to target. Shared in collection. +- type: stiring + +#### `ccp_version` + +- version of ccp +- type: string + +#### `ccp_dir` + +- root ccp directory +- type: string +- default: + ```yml + ccp_dir: "/opt/fluence/ccp" + ``` + +It will contain everything this role creates: ccp binaries, configs and state. + +#### `ccp_unit_file` + +- systemd unit file +- type: string +- default: see [defaults/main.yml](https://github.com/fluencelabs/blob/main/roles/ccp/defaults/main.yml) + +#### `ccp_user` + +- owner of ccp process and files +- type: string +- default: + ```yml + ccp_user: "ccp" + ``` + +#### `ccp_group` + +- group of `ccp_user` +- type: string +- default: + ```yml + ccp_group: "ccp" + ``` + +#### `ccp_cleanup_state` + +- whether to cleanup ccp state +- type: bool +- default: + ```yml + ccp_cleanup_state: false + ``` + +#### `ccp_run_id` + +- GitHub actions run id of workflow in + [ccp e2e run](https://github.com/fluencelabs/capacity-commitment-prover/actions/workflows/e2e.yml). + Used by Fluence Labs internally to install a snapshot version of ccp for + testing. `GITHUB_TOKEN` is required. +- type: string + +## Author + +- **Anatolios Laskaris** - [nahsi](https://github.com/nahsi) diff --git a/roles/ccp/defaults/example.yml b/roles/ccp/defaults/example.yml new file mode 100644 index 0000000..8f97b86 --- /dev/null +++ b/roles/ccp/defaults/example.yml @@ -0,0 +1,4 @@ +ccp_version: "0.2.0" + +fluence_project_dir: "playground" +fluence_instance_id: "peer-0" diff --git a/roles/ccp/defaults/main.yml b/roles/ccp/defaults/main.yml new file mode 100644 index 0000000..48d722f --- /dev/null +++ b/roles/ccp/defaults/main.yml @@ -0,0 +1,21 @@ +ccp_version: "" +ccp_dir: "/opt/fluence/ccp" +ccp_project_dir: "" +ccp_group: "ccp" +ccp_user: "ccp" +ccp_run_id: "" +ccp_cleanup_state: false +ccp_unit_file: | + [Unit] + Description=CCP - Fluence capacity commitment prover + After=network.target + + [Service] + Type=simple + ExecStart={{ ccp_dir }}/ccp {{ ccp_dir }}/Config.toml + Restart=on-failure + User={{ ccp_user }} + Group={{ ccp_group }} + + [Install] + WantedBy=multi-user.target diff --git a/roles/ccp/handlers/main.yml b/roles/ccp/handlers/main.yml new file mode 100644 index 0000000..21f7efe --- /dev/null +++ b/roles/ccp/handlers/main.yml @@ -0,0 +1,5 @@ +- name: restart ccp + ansible.builtin.systemd: + daemon_reload: true + name: ccp + state: restarted diff --git a/roles/ccp/meta/main.yml b/roles/ccp/meta/main.yml new file mode 100644 index 0000000..cea6797 --- /dev/null +++ b/roles/ccp/meta/main.yml @@ -0,0 +1,21 @@ +galaxy_info: + namespace: fluencelabs + role_name: ccp + license: Apache-2.0 + author: Anatolios Laskaris + description: Install and setup CCP - Fluence capacity commitment prover + issue_tracker_url: https://github.com/fluencelabs/ansible/issues + min_ansible_version: "2.12" + + platforms: + - name: Ubuntu + versions: + - jammy + - name: Debian + versions: + - bookworm + + galaxy_tags: + - p2p + - fluence + - web3 diff --git a/roles/ccp/tasks/00-preflight.yml b/roles/ccp/tasks/00-preflight.yml new file mode 100644 index 0000000..3a33d04 --- /dev/null +++ b/roles/ccp/tasks/00-preflight.yml @@ -0,0 +1,93 @@ +- name: check that GITHUB_TOKEN is defined + tags: always + vars: + github_token: "{{ lookup('env', 'GITHUB_TOKEN') }}" + ansible.builtin.assert: + that: + - github_token is string + - github_token | length + quiet: true + when: ccp_run_id | string | length + +- name: check that tar is GNU type # noqa + tags: always + fluencelabs.provider.check_tar_type: + +- name: check "fluence_instance_id" variable + tags: always + ansible.builtin.assert: + that: + - fluence_instance_id is string + - fluence_instance_id | length + quiet: true + +- name: check "ccp_version" variable + tags: always + ansible.builtin.assert: + that: + - ccp_version is defined + - ccp_version is string + - ccp_version | length + - ccp_version is regex(_semver_regex) + quiet: true + +- name: check "ccp_user" variable + tags: always + ansible.builtin.assert: + that: + - ccp_user is defined + - ccp_user is string + - ccp_user | length + quiet: true + +- name: check "ccp_group" variable + tags: always + ansible.builtin.assert: + that: + - ccp_group is defined + - ccp_group is string + - ccp_group | length + quiet: true + +- name: check "ccp_dir" variable + tags: always + ansible.builtin.assert: + that: + - ccp_dir is defined + - ccp_dir is string + - ccp_dir | length + quiet: true + +- name: check "ccp_unit_file" variable + tags: always + ansible.builtin.assert: + that: + - ccp_unit_file is defined + - ccp_unit_file is string + - ccp_unit_file | length + quiet: true + +- name: check "fluence_project_dir" variable + tags: always + ansible.builtin.assert: + that: + - fluence_project_dir is defined + - fluence_project_dir is string + - fluence_project_dir | length + quiet: true + +- name: gather stats about ccp configs + tags: always + become: false + delegate_to: localhost + stat: + path: "files/{{ fluence_project_dir }}/.fluence/ccp-configs/{{ fluence_instance_id }}_Config.toml" + register: _config_stat + +- name: check if config file exists + tags: always + vars: + _config_path: "files/{{ fluence_project_dir }}/.fluence/ccp-configs/{{ fluence_instance_id }}_Config.toml" + debug: + msg: "Checking existence of {{ fluence_instance_id }} config at {{ _config_path }}" + failed_when: not _config_stat.stat.exists diff --git a/roles/ccp/tasks/01-install.yml b/roles/ccp/tasks/01-install.yml new file mode 100644 index 0000000..c3baf89 --- /dev/null +++ b/roles/ccp/tasks/01-install.yml @@ -0,0 +1,157 @@ +- name: create ccp system group + ansible.builtin.group: + name: "{{ ccp_group }}" + system: true + state: present + +- name: create ccp system user + ansible.builtin.user: + name: "{{ ccp_user }}" + system: true + shell: "/sbin/nologin" + group: "{{ ccp_group }}" + create_home: false + state: present + +- name: cleanup ccp state + ansible.builtin.file: + path: "{{ ccp_dir }}" + state: absent + when: ccp_cleanup_state + +- name: create ccp directories + ansible.builtin.file: + path: "{{ ccp_dir }}/state" + state: directory + owner: "{{ ccp_user }}" + group: "{{ ccp_group }}" + mode: 0o755 + +- name: download ccp release to localhost + become: false + run_once: true + delegate_to: localhost + when: ccp_run_id | string | length == 0 + block: + - name: create files directory + become: false + run_once: true + delegate_to: localhost + ansible.builtin.file: + path: "{{ role_path }}/files/ccp/{{ _ccp_version }}" + state: directory + mode: 0o755 + + - name: download ccp release binary + ansible.builtin.get_url: + url: "{{ _ccp_download_url }}/{{ _ccp_bin }}" + dest: "{{ role_path }}/files/ccp/{{ _ccp_version }}/{{ _ccp_bin }}" + checksum: "{{ _ccp_checksums }}" + register: _download_bin + until: _download_bin is succeeded + retries: 5 + delay: 2 + + - name: propagate ccp release binary + become: true + become_user: root + run_once: false + delegate_to: "{{ inventory_hostname }}" + ansible.builtin.copy: + src: "{{ role_path }}/files/ccp/{{ _ccp_version }}/{{ _ccp_bin }}" + dest: "{{ ccp_dir }}/ccp" + owner: "{{ ccp_user }}" + group: "{{ ccp_group }}" + mode: 0o555 + notify: restart ccp + +- name: download ccp snapshot to localhost + become: false + run_once: true + delegate_to: localhost + vars: + github_token: "{{ lookup('env', 'GITHUB_TOKEN') }}" + when: ccp_run_id | string | length + block: + - name: get list of artifacts from GitHub API + ansible.builtin.uri: + url: "https://api.github.com/repos/fluencelabs/capacity-commitment-prover/actions/runs/{{ ccp_run_id }}/artifacts" + method: GET + headers: + Accept: "application/vnd.github.v3+json" + return_content: true + register: _artifacts_response + + - name: parse the artifact download URL + ansible.builtin.set_fact: + _artifact_download_url: "{{ item.archive_download_url }}" + loop: "{{ _artifacts_response.json.artifacts }}" + when: "item.name == _bin" + loop_control: + label: "{{ item.url }}" + + - name: create a temporary directory + ansible.builtin.tempfile: + state: directory + register: _artifact_temp_dir + + - name: download the artifact + ansible.builtin.get_url: + url: "{{ _artifact_download_url }}" + dest: "{{ _artifact_temp_dir.path }}/{{ _ccp_bin }}.zip" + headers: + Authorization: "token {{ github_token }}" + register: _download_artifact + until: _download_artifact is succeeded + retries: 5 + delay: 2 + + - name: unarchive the downloaded artifact + ansible.builtin.unarchive: + src: "{{ _artifact_temp_dir.path }}/{{ _ccp_bin }}.zip" + dest: "{{ _artifact_temp_dir.path }}/" + + - name: propagate ccp artifact binary + become: true + become_user: root + run_once: false + delegate_to: "{{ inventory_hostname }}" + ansible.builtin.copy: + src: "{{ _artifact_temp_dir.path }}/ccp" + dest: "{{ ccp_dir }}/ccp" + owner: "{{ ccp_user }}" + group: "{{ ccp_group }}" + mode: 0o555 + notify: restart ccp + register: _binary_snapshot + + always: + - name: remove temporary directory + ansible.builtin.file: + path: "{{ _artifact_temp_dir.path }}" + state: absent + when: _artifact_temp_dir.path is defined + +- name: copy ccp config + ansible.builtin.template: + src: "files/{{ fluence_project_dir }}/.fluence/ccp-configs/{{ fluence_instance_id }}_Config.toml" + dest: "{{ ccp_dir }}/Config.toml" + owner: "{{ ccp_user }}" + group: "{{ ccp_group }}" + mode: 0o640 + notify: restart ccp + +- name: create ccp unit file + ansible.builtin.copy: + content: "{{ ccp_unit_file }}" + dest: "/etc/systemd/system/ccp.service" + owner: root + group: root + mode: 0o755 + notify: restart ccp + +- name: enable ccp + ansible.builtin.systemd: + name: ccp + enabled: true + daemon_reload: true diff --git a/roles/ccp/tasks/main.yml b/roles/ccp/tasks/main.yml new file mode 100644 index 0000000..08e8c0f --- /dev/null +++ b/roles/ccp/tasks/main.yml @@ -0,0 +1,6 @@ +- name: Preflight + tags: always + ansible.builtin.include_tasks: 00-preflight.yml + +- name: Install CCP + ansible.builtin.include_tasks: 01-install.yml diff --git a/roles/ccp/vars/main.yml b/roles/ccp/vars/main.yml new file mode 100644 index 0000000..252f92f --- /dev/null +++ b/roles/ccp/vars/main.yml @@ -0,0 +1,12 @@ +_arch_map: + amd64: amd64 + x86_64: amd64 + aarch64: arm64 + 64-bit: amd64 +_arch: "{{ _arch_map[ansible_architecture] }}" +_semver_regex: "^v?\\d+\\.\\d+\\.\\d+$" + +_ccp_version: "{{ ccp_version | regex_replace('^(?!v)', 'v') }}" +_ccp_download_url: "https://github.com/fluencelabs/capacity-commitment-prover/releases/download/ccp-{{ _ccp_version }}" +_ccp_checksums: "sha256:{{ _ccp_download_url + '/ccp_SHA256_SUMS' }}" +_ccp_bin: "ccp-{{ _arch }}" diff --git a/roles/ipfs_cli/README.md b/roles/ipfs_cli/README.md index 94d16a4..1bd1a16 100644 --- a/roles/ipfs_cli/README.md +++ b/roles/ipfs_cli/README.md @@ -1,5 +1,7 @@ # fluencelabs.provider.ipfs_cli +Fluence IPFS effector binary. Installs IPFS cli to "/usr/local/bin". + ## Role Variables See [defaults/](https://github.com/fluencelabs/ansible/blob/main/roles/ipfs_cli/defaults) for details and examples. diff --git a/roles/ipfs_cli/meta/main.yml b/roles/ipfs_cli/meta/main.yml index c0f5e42..d8effc9 100644 --- a/roles/ipfs_cli/meta/main.yml +++ b/roles/ipfs_cli/meta/main.yml @@ -11,9 +11,13 @@ galaxy_info: - name: Ubuntu versions: - jammy + - name: Debian + versions: + - bookworm galaxy_tags: - p2p - fluence + - web3 dependencies: [] diff --git a/roles/ipfs_cli/tasks/01-ipfs.yml b/roles/ipfs_cli/tasks/01-ipfs.yml index 23ab464..453f0a0 100644 --- a/roles/ipfs_cli/tasks/01-ipfs.yml +++ b/roles/ipfs_cli/tasks/01-ipfs.yml @@ -37,7 +37,7 @@ - name: propagate IPFS binary ansible.builtin.copy: src: "{{ role_path }}/files/ipfs/{{ _ipfs_version }}/{{ _arch }}/ipfs" - dest: "{{ nox_dir }}/ipfs" + dest: "/usr/local/bin/ipfs" owner: root group: root mode: 0o755 diff --git a/roles/nox/README.md b/roles/nox/README.md index 8adf3ac..164a6b2 100644 --- a/roles/nox/README.md +++ b/roles/nox/README.md @@ -1,4 +1,4 @@ -# Nox +# fluencelabs.provider.nox Install and configure [Nox](https://github.com/fluencelabs/nox/) - Rust implementation of the Fluence network peer. @@ -14,41 +14,6 @@ Rerun playbook with `nox_cleanup_state` set to `true`: ansible-playbook nox.yml -e "nox_cleanup_state=true" ``` -### Reassign instances to different host - -`nox-0` runs on `server-0`, `nox-1` nox-2` on `server-1`. - -```yml -all: - children: - servers: - hosts: - server-0: - nox_instances: [0] - server-1: - nox_instances: [1,2] -``` - -Reassign `nox-1` to `server-0` - -```yml -all: - children: - servers: - hosts: - server-0: - nox_instances: [0,1] - server-1: - nox_instances: [2] -``` - -and run playbook: -```bash -ansible-playbook nox.yml -``` - -This will stop `nox-1` at `server-1` and will run it on `server-0`. - ### Install nox snapshot from PR Only for Fluence Labs members. @@ -65,15 +30,24 @@ Only for Fluence Labs members. See [defaults/](https://github.com/fluencelabs/ansible/blob/main/roles/nox/defaults) for details and examples. -#### `nox_version` +#### `nox_project_dir` -- version of nox +- directory that contains provider settings, configs and secrets generated by + [Fluence CLI](https://github.com/fluencelabs/cli) from `provider.yaml` config. + Shared in collection. - type: string -#### `nox_instances` +Should be put to `files/` directory where you run this role. -- list of nox instances to install on target -- type: list +#### `fluence_instance_id` + +- instance id to assing to target. Shared in collection. +- type: string + +#### `nox_version` + +- version of nox +- type: string #### `nox_dir` @@ -81,19 +55,10 @@ See [defaults/](https://github.com/fluencelabs/ansible/blob/main/roles/nox/defau - type: string - default: ```yml - nox_dir: "/opt/nox" + nox_dir: "/opt/fluence/nox" ``` -It will contain everything this role creates: IPFS binary, nox instances -subdirectories (`nox-1`, `nox-foo` etc) with nox binaries, configs and state. - -#### `nox_project_dir` - -- directory that contains configs and secrets generated by - [Fluence CLI](https://github.com/fluencelabs/cli) from `provider.yaml` config. -- type: string - -Should be put to `files/` directory where you run this role. +It will contain everything this role creates: nox binaries, configs, secrets. #### `nox_unit_file` diff --git a/roles/nox/defaults/example.yml b/roles/nox/defaults/example.yml index 281524c..251e9bc 100644 --- a/roles/nox/defaults/example.yml +++ b/roles/nox/defaults/example.yml @@ -1,3 +1,4 @@ -nox_version: "0.16.13" -nox_project_dir: "playground" -nox_instances: [0, 1, 2] +nox_version: "0.22.0" + +fluence_project_dir: "playground" +fluence_instance_id: "peer-0" diff --git a/roles/nox/defaults/main.yml b/roles/nox/defaults/main.yml index 72809b4..0a6ed17 100644 --- a/roles/nox/defaults/main.yml +++ b/roles/nox/defaults/main.yml @@ -1,6 +1,5 @@ nox_version: "" -nox_instances: [] -nox_dir: "/opt/nox" +nox_dir: "/opt/fluence/nox" nox_project_dir: "" nox_group: "nox" nox_user: "nox" @@ -13,10 +12,10 @@ nox_unit_file: | [Service] Type=simple - Environment="FLUENCE_CONFIG={{ nox_dir }}/nox-%i/Config.toml" - Environment="FLUENCE_BASE_DIR={{ nox_dir }}/nox-%i/state" - Environment="FLUENCE_ROOT_KEY_PAIR__PATH={{ nox_dir }}/nox-%i/state/root_secret_key.ed25519" - ExecStart={{ nox_dir }}/nox-%i/nox + Environment="FLUENCE_CONFIG={{ nox_dir }}/Config.toml" + Environment="FLUENCE_BASE_DIR={{ nox_dir }}/state" + Environment="FLUENCE_ROOT_KEY_PAIR__PATH={{ nox_dir }}/state/root_secret_key.ed25519" + ExecStart={{ nox_dir }}/nox Restart=on-failure User={{ nox_user }} Group={{ nox_group }} diff --git a/roles/nox/handlers/main.yml b/roles/nox/handlers/main.yml index ad36b38..6fe2863 100644 --- a/roles/nox/handlers/main.yml +++ b/roles/nox/handlers/main.yml @@ -1,9 +1,5 @@ - name: restart nox - systemd: + ansible.builtin.systemd: daemon_reload: true - name: nox-@{{ instance }} + name: nox state: restarted - loop: "{{ _instances_to_restart }}" - loop_control: - loop_var: instance - label: "nox-{{ instance }}" diff --git a/roles/nox/meta/main.yml b/roles/nox/meta/main.yml index a80fb91..f78a2f4 100644 --- a/roles/nox/meta/main.yml +++ b/roles/nox/meta/main.yml @@ -11,10 +11,16 @@ galaxy_info: - name: Ubuntu versions: - jammy + - name: Debian + versions: + - bookworm galaxy_tags: - p2p - fluence + - web3 dependencies: + - name: prerequisites - name: ipfs_cli + - name: ccp diff --git a/roles/nox/tasks/00-preflight.yml b/roles/nox/tasks/00-preflight.yml index cb07ca3..5ba484a 100644 --- a/roles/nox/tasks/00-preflight.yml +++ b/roles/nox/tasks/00-preflight.yml @@ -13,18 +13,15 @@ tags: always fluencelabs.provider.check_tar_type: -- name: check "nox_instances" variable +- name: check "fluence_instance_id" variable tags: always ansible.builtin.assert: that: - - nox_instances is iterable - - nox_instances is not string + - fluence_instance_id is defined + - fluence_instance_id is string + - fluence_instance_id | length quiet: true -- name: convert all elements in nox_instances to strings - set_fact: - nox_instances: "{{ nox_instances | map('string') | list }}" - - name: check "nox_version" variable tags: always ansible.builtin.assert: @@ -71,13 +68,13 @@ - nox_unit_file | length quiet: true -- name: check "nox_project_dir" variable +- name: check "fluence_project_dir" variable tags: always ansible.builtin.assert: that: - - nox_project_dir is defined - - nox_project_dir is string - - nox_project_dir | length + - fluence_project_dir is defined + - fluence_project_dir is string + - fluence_project_dir | length quiet: true - name: gather stats about nox configs @@ -85,20 +82,13 @@ become: false delegate_to: localhost stat: - path: "files/{{ nox_project_dir }}/.fluence/configs/nox-{{ instance }}_Config.toml" + path: "files/{{ fluence_project_dir }}/.fluence/configs/{{ fluence_instance_id }}_Config.toml" register: _config_stat - loop: "{{ nox_instances }}" - loop_control: - loop_var: instance - label: "nox-{{ instance }}" - name: check if config file exists tags: always vars: - _config_path: "files/{{ nox_project_dir }}/.fluence/configs/nox-{{ item.instance }}_Config.toml" + _config_path: "files/{{ fluence_project_dir }}/.fluence/configs/{{ fluence_instance_id }}_Config.toml" debug: - msg: "Checking existence of nox-{{ item.instance }} config at {{ _config_path }}" - loop: "{{ _config_stat.results }}" - loop_control: - label: "nox-{{ item.instance }}" - failed_when: not item.stat.exists + msg: "Checking existence of {{ fluence_instance_id }} config at {{ _config_path }}" + failed_when: not _config_stat.stat.exists diff --git a/roles/nox/tasks/01-cleanup.yml b/roles/nox/tasks/01-cleanup.yml deleted file mode 100644 index c3ad495..0000000 --- a/roles/nox/tasks/01-cleanup.yml +++ /dev/null @@ -1,39 +0,0 @@ -- name: get list of all running nox instances - ansible.builtin.command: systemctl list-units --type=service --no-legend --no-pager nox-@* - register: _running_instances - changed_when: false - -- name: extract running nox instance names - vars: - _present_instances: "{{ _running_instances.stdout_lines - | map('regex_replace', '.*?nox-@([^\\s]+)\\.service.*', '\\1') - | list }}" - ansible.builtin.set_fact: - _cleanup_instances: "{{ _present_instances | difference(nox_instances) | default([]) }}" - changed_when: false - -- name: instances to cleanup - ansible.builtin.debug: - msg: "{{ _cleanup_instances }}" - -- name: cleanup nox instances - when: _cleanup_instances | length - block: - - name: stop and disable noxes - ansible.builtin.systemd: - name: nox-@{{ instance }} - enabled: false - state: stopped - loop: "{{ _cleanup_instances }}" - loop_control: - loop_var: instance - label: "nox-{{ instance }}" - - - name: cleanup nox directories - ansible.builtin.file: - path: "{{ nox_dir }}/nox-{{ instance }}" - state: absent - loop: "{{ _cleanup_instances }}" - loop_control: - loop_var: instance - label: "nox-{{ instance }}" diff --git a/roles/nox/tasks/02-install.yml b/roles/nox/tasks/01-install.yml similarity index 64% rename from roles/nox/tasks/02-install.yml rename to roles/nox/tasks/01-install.yml index e7fdcfc..7a58d88 100644 --- a/roles/nox/tasks/02-install.yml +++ b/roles/nox/tasks/01-install.yml @@ -15,25 +15,17 @@ - name: cleanup nox state ansible.builtin.file: - path: "{{ nox_dir }}/nox-{{ instance }}" + path: "{{ nox_dir }}" state: absent when: nox_cleanup_state - loop: "{{ nox_instances }}" - loop_control: - loop_var: instance - label: "nox-{{ instance }}" - name: create nox directories ansible.builtin.file: - path: "{{ nox_dir }}/nox-{{ instance }}/state" + path: "{{ nox_dir }}/state" state: directory owner: "{{ nox_user }}" group: "{{ nox_group }}" mode: 0o755 - loop: "{{ nox_instances }}" - loop_control: - loop_var: instance - label: "nox-{{ instance }}" - name: download nox release to localhost become: false @@ -67,16 +59,11 @@ delegate_to: "{{ inventory_hostname }}" ansible.builtin.copy: src: "{{ role_path }}/files/nox/{{ _nox_version }}/{{ _nox_bin }}" - dest: "{{ nox_dir }}/nox-{{ instance }}/nox" + dest: "{{ nox_dir }}/nox" owner: "{{ nox_user }}" group: "{{ nox_group }}" mode: 0o555 - loop: "{{ nox_instances }}" - loop_control: - loop_var: instance - label: "nox-{{ instance }}" notify: restart nox - register: _binary_release - name: download nox snapshot to localhost become: false @@ -131,16 +118,11 @@ delegate_to: "{{ inventory_hostname }}" ansible.builtin.copy: src: "{{ _artifact_temp_dir.path }}/nox" - dest: "{{ nox_dir }}/nox-{{ instance }}/nox" + dest: "{{ nox_dir }}/nox" owner: "{{ nox_user }}" group: "{{ nox_group }}" mode: 0o555 - loop: "{{ nox_instances }}" - loop_control: - loop_var: instance - label: "nox-{{ instance }}" notify: restart nox - register: _binary_snapshot always: - name: remove temporary directory @@ -151,57 +133,32 @@ - name: copy nox config ansible.builtin.template: - src: "files/{{ nox_project_dir }}/.fluence/configs/nox-{{ instance }}_Config.toml" - dest: "{{ nox_dir }}/nox-{{ instance }}/Config.toml" + src: "files/{{ fluence_project_dir }}/.fluence/configs/{{ fluence_instance_id }}_Config.toml" + dest: "{{ nox_dir }}/Config.toml" owner: "{{ nox_user }}" group: "{{ nox_group }}" mode: 0o640 - loop: "{{ nox_instances }}" - loop_control: - loop_var: instance - label: "nox-{{ instance }}" notify: restart nox - register: _config - name: copy nox secret ansible.builtin.template: - src: "files/{{ nox_project_dir }}/.fluence/secrets/nox-{{ instance }}.txt" - dest: "{{ nox_dir }}/nox-{{ instance }}/state/root_secret_key.ed25519" + src: "files/{{ fluence_project_dir }}/.fluence/secrets/{{ fluence_instance_id }}.txt" + dest: "{{ nox_dir }}/state/root_secret_key.ed25519" owner: "{{ nox_user }}" group: "{{ nox_group }}" mode: 0o600 - loop: "{{ nox_instances }}" - loop_control: - loop_var: instance - label: "nox-{{ instance }}" notify: restart nox - register: _secret - name: create nox unit file ansible.builtin.copy: content: "{{ nox_unit_file }}" - dest: "/etc/systemd/system/nox-@.service" + dest: "/etc/systemd/system/nox.service" owner: root group: root mode: 0o755 - register: _systemd - name: enable noxes ansible.builtin.systemd: - name: nox-@{{ instance }} + name: nox enabled: true daemon_reload: true - loop: "{{ nox_instances }}" - loop_control: - loop_var: instance - label: "nox-{{ instance }}" - -- name: determine which instances to restart - vars: - _binary_release_changed: "{{ _binary_release.results | selectattr('changed', 'equalto', true) | map(attribute='instance') | list }}" - _binary_snapshot_changed: "{{ _binary_snapshot.results | selectattr('changed', 'equalto', true) | map(attribute='instance') | list }}" - _config_changed: "{{ _config.results | selectattr('changed', 'equalto', true) | map(attribute='instance') | list }}" - _secret_changed: "{{ _secret.results | selectattr('changed', 'equalto', true) | map(attribute='instance') | list }}" - _instances_changed: "{{ (_systemd is changed) | ternary(nox_instances, _binary_release_changed + _binary_snapshot_changed + _config_changed + _secret_changed) }}" - ansible.builtin.set_fact: - _instances_to_restart: "{{ (nox_instances | select('in', _instances_changed) | list) | unique }}" diff --git a/roles/nox/tasks/main.yml b/roles/nox/tasks/main.yml index 73f8743..d3db1b8 100644 --- a/roles/nox/tasks/main.yml +++ b/roles/nox/tasks/main.yml @@ -2,8 +2,5 @@ tags: always ansible.builtin.include_tasks: 00-preflight.yml -- name: Cleanup Nox - ansible.builtin.include_tasks: 01-cleanup.yml - - name: Install Nox - ansible.builtin.include_tasks: 02-install.yml + ansible.builtin.include_tasks: 01-install.yml diff --git a/roles/prerequisites/README.md b/roles/prerequisites/README.md new file mode 100644 index 0000000..f2f6d02 --- /dev/null +++ b/roles/prerequisites/README.md @@ -0,0 +1,12 @@ +# fluencelabs.provider.prerequisites + +Configure system before running Fluence provider toolkit. + +⚠ Attention: this role will modify system by: +- installing packages + - libhwloc-dev - required to get CPU topology + - curl - default effector used by Nox + +## Author + +- **Anatolios Laskaris** - [nahsi](https://github.com/nahsi) diff --git a/roles/prerequisites/meta/main.yml b/roles/prerequisites/meta/main.yml new file mode 100644 index 0000000..ee50cfc --- /dev/null +++ b/roles/prerequisites/meta/main.yml @@ -0,0 +1,21 @@ +galaxy_info: + namespace: fluencelabs + role_name: preprequisites + license: Apache-2.0 + author: Anatolios Laskaris + description: Prepare OS to run Fluence provider toolkit + issue_tracker_url: https://github.com/fluencelabs/ansible/issues + min_ansible_version: "2.12" + + platforms: + - name: Ubuntu + versions: + - jammy + - name: Debian + versions: + - bookworm + + galaxy_tags: + - p2p + - fluence + - web3 diff --git a/roles/prerequisites/tasks/main.yml b/roles/prerequisites/tasks/main.yml new file mode 100644 index 0000000..8c41bf6 --- /dev/null +++ b/roles/prerequisites/tasks/main.yml @@ -0,0 +1,14 @@ +- name: install required packages and libraries + apt: + name: "{{ package }}" + install_recommends: false + update_cache: true + autoclean: true + autoremove: true + state: present + loop: + - libhwloc-dev + - curl + loop_control: + loop_var: package + label: "{{ package }}"