Feat: Node orchestration UX improvements (#6848)
* improve nginx playbook * improve configure-vm script * improve initialise-vm script * expand config naming options * provide args docs * syntax fix * address rabbitai comments * cleanup ansible * document ansible changes * fix review comments * update scraed data * fix max comment review
This commit is contained in:
@@ -1,21 +1,4 @@
|
||||
---
|
||||
ansible_ssh_private_key_file: ~/.ssh/<SSH_KEY>
|
||||
|
||||
cli_url: "https://github.com/nymtech/nym/releases/download/nym-binaries-{{ nym_version }}/nym-cli"
|
||||
tunnel_manager_url: "https://github.com/nymtech/nym/raw/refs/heads/develop/scripts/nym-node-setup/network-tunnel-manager.sh"
|
||||
quic_bridge_deployment_url: "https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/nym-node-setup/quic_bridge_deployment.sh"
|
||||
|
||||
###############################################################################
|
||||
## GLOBAL VARS
|
||||
## These values will be used globally unless overwritten per node in inventory/all
|
||||
###############################################################################
|
||||
|
||||
ansible_user: root # used for ssh, like `ssh root@nym-exit.ch-1.mynodes.net`
|
||||
email: "<EMAIL>" # used in certbot, description.toml and landing page
|
||||
website: "<WEBSITE>" # it is used in the description.toml
|
||||
description: "<NODE_PUBLIC_DESCRIPTION>" # or define per node in inventory/all
|
||||
# operator_name: "<OPERATOR_NAME>" # used in landing page if provided
|
||||
|
||||
###############################################################################
|
||||
## GLOBAL VARS
|
||||
## These values will be used globally unless overwritten per node in inventory/all
|
||||
@@ -23,16 +6,41 @@ description: "<NODE_PUBLIC_DESCRIPTION>" # or define per node in inventory/all
|
||||
## Per node changes in inventory/all will overwrite these global vars
|
||||
###############################################################################
|
||||
|
||||
# moniker: "<MONIKER>" # if not setup here not in inventory/all it get's derived from the hostname
|
||||
# mode: <MODE> # entry-gateway/exit-gateway/mixnode
|
||||
# wireguard_enabled: <WIREGUARD_ENABLED> # true/false
|
||||
hostname: "" # this is a fallback, keep it and setup hostname per node in inventory/all
|
||||
## MANDATORY - uncomment & define
|
||||
|
||||
## --SSH--
|
||||
#ansible_user: root # used for ssh, like `ssh root@nym-exit.ch-1.mynodes.net`
|
||||
# ansible_ssh_private_key_file: ~/.ssh/<SSH_KEY>
|
||||
|
||||
## --Operator info--
|
||||
# email: "<EMAIL>" # used in certbot, description.toml and landing page
|
||||
# website: "<WEBSITE>" # it is used in the description.toml
|
||||
# description: "<NODE_PUBLIC_DESCRIPTION>" # or define per node in inventory/all
|
||||
# moniker: "<MONIKER>"
|
||||
|
||||
## --Node defaults (can override per node in inventory/all)--
|
||||
# accept_operator_terms: true # controls --accept-operator-terms-and-conditions, read: https://nym.com/docs/operators/nodes/nym-node/setup#terms--conditions
|
||||
# mode: exit-gateway # entry-gateway/exit-gateway/mixnode
|
||||
# wireguard_enabled: true # true/false
|
||||
hostname: "" # keep this fallback, keep it and setup hostname per node in inventory/all
|
||||
|
||||
## OPTIONAL - uncomment & define
|
||||
|
||||
# operator_name: "<OPERATOR_NAME>" # used in landing page if provided
|
||||
# nym_version: "nym-binaries-v2026.7-tola" # to use particular version instead of Latest, provide in such form:
|
||||
|
||||
## alternative SSH key var setting, instead of a hardcoded path
|
||||
## useful if the playbook is shared in a repo by more admins with each having own local key
|
||||
# ansible_ssh_private_key_file: "{{ lookup('env', '<YOUR_ANSIBLE SSH_KEY_ENV_VAR>') }}"
|
||||
|
||||
###############################################################################
|
||||
## GLOBAL PACKAGES
|
||||
## GLOBAL PACKAGES & URLs
|
||||
## These will be installed during deployment
|
||||
###############################################################################
|
||||
|
||||
nym_cli_url: "https://github.com/nymtech/nym/releases/download/{{ nym_version }}/nym-cli"
|
||||
tunnel_manager_url: "https://github.com/nymtech/nym/raw/refs/heads/develop/scripts/nym-node-setup/network-tunnel-manager.sh"
|
||||
quic_bridge_deployment_url: "https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/nym-node-setup/quic_bridge_deployment.sh"
|
||||
|
||||
packages:
|
||||
- tmux
|
||||
@@ -50,24 +58,6 @@ packages:
|
||||
- ufw
|
||||
|
||||
|
||||
###############################################################################
|
||||
## OPTIONAL OVERRIDES
|
||||
## All values below already have defaults in the playbook/roles
|
||||
## Uncomment only if you want to override them
|
||||
###############################################################################
|
||||
|
||||
###############################################################################
|
||||
## SYSTEM MAINTENANCE PLAYBOOK KNOBS
|
||||
###############################################################################
|
||||
|
||||
# To use particular version instead of Latest, provide in such form:
|
||||
# nym_version: "nym-binaries-v2026.7-tola"
|
||||
|
||||
## NOTE:
|
||||
## if you want to pin Nym to a specific version instead of using the
|
||||
## latest release from GitHub in /tasks/main.yml then
|
||||
## uncomment the line above and set the tag
|
||||
|
||||
###############################################################################
|
||||
## SYSTEM MAINTENANCE PLAYBOOK KNOBS
|
||||
###############################################################################
|
||||
|
||||
@@ -1,34 +1,39 @@
|
||||
[nym_nodes]
|
||||
# READ CONFIGURATION GUIDE:
|
||||
# https://nym.com//docs/operators/orchestration/ansible#configuration
|
||||
## READ CONFIGURATION GUIDE:
|
||||
## https://nym.com/docs/operators/orchestration/ansible#configuration
|
||||
|
||||
# VARIABLES INFO
|
||||
# required vars to set values per node:
|
||||
# `ansible_host`, `hostname`, `location`
|
||||
##############
|
||||
## TEMPLATE ##
|
||||
##############
|
||||
## uncomment and exchange the <VARIABLES> with your real values for each node without the <> brackets
|
||||
|
||||
# global vars can be set in the group_vars/all.yml, for example:
|
||||
# `email`, `ansible_user`, `moniker`, `description`, `mode`, `wireguard_enabled`
|
||||
# othersise they must be set per node!
|
||||
|
||||
############
|
||||
# TEMPLATE #
|
||||
############
|
||||
# node1 ansible_host=<YOUR_SERVER_IP> ansible_user=<USER> hostname=<HOSTNAME> location=<LOCATION> email=<EMAIL> mode=<MODE> wireguard_enabled=<true/false> moniker=<MONIKER> description=<DESCRIPTION>
|
||||
|
||||
# remove all comments and exchange the <VARIABLES> with your real values for each node
|
||||
# without <> brackets
|
||||
####################
|
||||
## VARIABLES INFO ##
|
||||
####################
|
||||
|
||||
# PRIORITY ORDER
|
||||
# anything setup globaly can be overwritten in this file per node
|
||||
# if provided here, it takes priority over the global setting
|
||||
## --REQUIRED VARS--
|
||||
## required per node:
|
||||
## ansible_host, hostname, location
|
||||
|
||||
# EXAMPLES
|
||||
# exit + wireguard gateway:
|
||||
## --OPTIONAL VARS--
|
||||
## can be set in the group_vars/all.yml or per node here:
|
||||
## email, ansible_user, moniker, description, mode, wireguard_enabled
|
||||
|
||||
## --PRIORITY ORDER--
|
||||
## anything setup globaly can be overwritten in this file per node
|
||||
## if provided here, it takes priority over the global setting
|
||||
|
||||
## --EXAMPLES--
|
||||
## exit + wireguard gateway:
|
||||
# node2 ansible_host=11.12.13.14 hostname=nym-exit.ch-1.mydomain.net mode=exit-gateway location=CH wireguard_enabled=true
|
||||
|
||||
# entry gateway, no wireguard:
|
||||
## entry gateway, no wireguard:
|
||||
# node3 ansible_host=12.13.14.15 hostname=nym-entry.ch-2.mydomain.net mode=entry-gateway location=CH wireguard_enabled=false
|
||||
|
||||
# NOTE:
|
||||
# all examples above don't have defined user, email nor description as we use the definition from group_vars/main.yml without an attempt of overwriting it
|
||||
# all examples above don't have moniker defined as there is a function in /templates/description.toml.j2 deriving it from the hostname
|
||||
## mixnode (comment out tunnel+quic roles in deploy.yml for these)
|
||||
# mix-de-1 ansible_host=13.14.15.16 hostname=nym-mix.de-1.example.net location=DE mode=mixnode wireguard_enabled=false
|
||||
|
||||
## NOTE:
|
||||
## all examples above don't have defined user, email nor description as we use global vars from playbooks/group_vars/all.yml
|
||||
|
||||
@@ -89,7 +89,6 @@
|
||||
loop:
|
||||
- "/etc/nginx/sites-enabled/{{ hostname }}-ssl"
|
||||
- "/etc/nginx/sites-enabled/nym-wss-config"
|
||||
when: not le_cert.stat.exists
|
||||
notify: Restart nginx
|
||||
|
||||
- name: Ensure nginx is enabled and running (needed for ACME http-01)
|
||||
@@ -111,18 +110,13 @@
|
||||
- name: Obtain/renew certificate
|
||||
command:
|
||||
cmd: >-
|
||||
{% if le_cert.stat.exists %}
|
||||
certbot certonly --webroot
|
||||
-w /var/www/{{ hostname }}
|
||||
certbot certonly --nginx
|
||||
--non-interactive --agree-tos --keep-until-expiring
|
||||
-m {{ email }} -d {{ hostname }}
|
||||
{% else %}
|
||||
certbot --nginx
|
||||
--non-interactive --agree-tos --redirect
|
||||
-m {{ email }} -d {{ hostname }}
|
||||
{% endif %}
|
||||
register: certbot_result
|
||||
failed_when: false
|
||||
failed_when: false
|
||||
|
||||
|
||||
|
||||
# re-check cert after certbot attempt
|
||||
- name: Re-check whether certificate exists after certbot
|
||||
@@ -170,4 +164,4 @@
|
||||
changed_when: false
|
||||
|
||||
- name: Flush handlers (apply restart after successful tests)
|
||||
meta: flush_handlers
|
||||
meta: flush_handlers
|
||||
@@ -10,7 +10,7 @@ mixnet_bind_address: "0.0.0.0:1789" # maps to --mixnet-bind-address
|
||||
landing_page_assets_base_dir: "/var/www"
|
||||
|
||||
# Flag toggles
|
||||
# accept_operator_terms: true # controls --accept-operator-terms-and-conditions
|
||||
accept_operator_terms: false # override in group_vars or inventory
|
||||
nym_write_flag: true # controls -w
|
||||
nym_init_only_flag: true # controls --init-only
|
||||
wss_port: 9001 # controlls --announce-wss-port
|
||||
@@ -18,7 +18,7 @@ wss_port: 9001 # controlls --announce-wss-port
|
||||
# Optional: extra flags if you want to append more later
|
||||
nym_extra_flags: ""
|
||||
|
||||
# CLI URL (nym_version can be set elsewhere / via GitHub API)
|
||||
# CLI URL
|
||||
nym_cli_url: "https://github.com/nymtech/nym/releases/download/{{ nym_version }}/nym-cli"
|
||||
|
||||
# UFW
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
},
|
||||
"mixmining_reserve": {
|
||||
"denom": "unym",
|
||||
"amount": "166613455567357"
|
||||
"amount": "164623226345363"
|
||||
},
|
||||
"vesting_tokens": {
|
||||
"denom": "unym",
|
||||
@@ -13,6 +13,6 @@
|
||||
},
|
||||
"circulating_supply": {
|
||||
"denom": "unym",
|
||||
"amount": "833386544432643"
|
||||
"amount": "835376773654637"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"nodes": 682,
|
||||
"locations": 78,
|
||||
"mixnodes": 242,
|
||||
"exit_gateways": 432
|
||||
"locations": 76,
|
||||
"mixnodes": 239,
|
||||
"exit_gateways": 435
|
||||
}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
833_386_544
|
||||
835_376_773
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
4_628
|
||||
4_572
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
254_977
|
||||
255_586
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
61_194_673
|
||||
61_340_814
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
61_194_672
|
||||
61_340_813
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
| **Item** | **Description** | **Amount in NYM** |
|
||||
|:-------------------|:------------------------------------------------------|--------------------:|
|
||||
| Total Supply | Maximum amount of NYM token in existence | 1_000_000_000 |
|
||||
| Mixmining Reserve | Tokens releasing for operators rewards | 166_613_455 |
|
||||
| Mixmining Reserve | Tokens releasing for operators rewards | 164_623_226 |
|
||||
| Vesting Tokens | Tokens locked outside of circulation for future claim | 0 |
|
||||
| Circulating Supply | Amount of unlocked tokens | 833_386_544 |
|
||||
| Stake Saturation | Optimal size of node self-bond + delegation | 254_977 |
|
||||
| Circulating Supply | Amount of unlocked tokens | 835_376_773 |
|
||||
| Stake Saturation | Optimal size of node self-bond + delegation | 255_586 |
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"interval": {
|
||||
"reward_pool": "166613455567357.391753168447944888",
|
||||
"staking_supply": "61194672938727.325886595653401629",
|
||||
"reward_pool": "164623226345363.285226429762152046",
|
||||
"staking_supply": "61340813321050.793375219026221616",
|
||||
"staking_supply_scale_factor": "0.07342892",
|
||||
"epoch_reward_budget": "4628151543.537705326476901331",
|
||||
"stake_saturation_point": "254977803911.363857860815222506",
|
||||
"epoch_reward_budget": "4572867398.482313478511937837",
|
||||
"stake_saturation_point": "255586722171.04497239674594259",
|
||||
"sybil_resistance": "0.3",
|
||||
"active_set_work_factor": "10",
|
||||
"interval_pool_emission": "0.02"
|
||||
|
||||
@@ -1 +1 @@
|
||||
Wednesday, May 27th 2026, 11:42:58 UTC
|
||||
Thursday, June 4th 2026, 09:20:29 UTC
|
||||
|
||||
@@ -291,17 +291,26 @@ KVM network is gone.
|
||||
|
||||
##### 3. Setup KVM public bridge for new VMs
|
||||
|
||||
To create a KVM network bridge on Ubuntu, edit a config file located in `/etc/netplan/` either called `00-installer.yaml` or `00-installer-config.yaml` and add the bridge details.
|
||||
To create a KVM network bridge on Ubuntu, edit a config file located in `/etc/netplan/` often called `50-cloud-init.yaml` or `00-installer.yaml` or `00-installer-config.yaml` and add the bridge details.
|
||||
|
||||
- Before you edit the file, make a backup to stay on the save side:
|
||||
- Before you edit the file, make a backup to stay on the save side, the file should be named something like this:
|
||||
```bash
|
||||
cp /etc/netplan/00-installer-config.yaml /etc/netplan/00-installer-config.yaml.bak
|
||||
cp /etc/netplan/50-cloud-init.yaml /etc/netplan/50-cloud-init.yaml.bak
|
||||
# or
|
||||
cp /etc/netplan/00-installer.yaml /etc/netplan/00-installer.yaml.bak
|
||||
# or
|
||||
cp /etc/netplan/00-installer-config.yaml /etc/netplan/00-installer-config.yaml.bak
|
||||
```
|
||||
|
||||
- Open `00-installer-config.yaml` or `00-installer.yaml.`config in a text editor:
|
||||
- If none of these files existed, simply check the name of your config by this command and apply the same backup logic:
|
||||
```sh
|
||||
ls /etc/netplan/
|
||||
```
|
||||
|
||||
- Open the original config in a text editor:
|
||||
```bash
|
||||
nano /etc/netplan/50-cloud-init.yaml
|
||||
# or
|
||||
nano /etc/netplan/00-installer.yaml
|
||||
# or
|
||||
nano /etc/netplan/00-installer-config.yaml
|
||||
@@ -380,12 +389,13 @@ netplan --debug apply
|
||||
```bash
|
||||
apt install yamllint -y
|
||||
|
||||
yamllint /etc/netplan/50-cloud-init.yaml
|
||||
# or
|
||||
yamllint /etc/netplan/00-installer.yaml
|
||||
# or
|
||||
yamllint /etc/netplan/00-installer-config.yaml
|
||||
|
||||
|
||||
```
|
||||
|
||||
- Apply correct permissions:
|
||||
```bash
|
||||
chmod 600 /etc/netplan/00-installer.yaml
|
||||
@@ -410,9 +420,12 @@ systemctl enable --now systemd-networkd
|
||||
|
||||
- If things went wrong, you can always revert from the backed up file:
|
||||
```bash
|
||||
cp /etc/netplan/50-cloud-init.yaml.bak /etc/netplan/50-cloud-init.yaml
|
||||
# or
|
||||
cp /etc/netplan/00-installer-config.yaml.bak /etc/netplan/00-installer-config.yaml
|
||||
# or
|
||||
cp /etc/netplan/00-installer.yaml.bak /etc/netplan/00-installer.yaml
|
||||
|
||||
# and
|
||||
netplan apply
|
||||
```
|
||||
@@ -535,19 +548,50 @@ Using the scripts is a two-step process. First, initialisation part is done from
|
||||
<Steps>
|
||||
##### 1. Initialise VM from the host machine
|
||||
- Log in to your host as `root`
|
||||
- Run this block and follow the prompts carefully:
|
||||
- Get the script:
|
||||
```bash
|
||||
wget "https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/kvm-setup/initialise-vm.sh"
|
||||
chmod +x ./initialise-vm.sh
|
||||
./initialise-vm.sh
|
||||
```
|
||||
|
||||
- Run this block and follow the prompts carefully or provide with arguments:
|
||||
```sh
|
||||
# interactive CLI
|
||||
./initialise-vm.sh
|
||||
|
||||
# arguments - see --help menu
|
||||
./initialise-vm.sh --help
|
||||
|
||||
# example
|
||||
# ./initialise-vm.sh --name ubuntu1 --password topsecretrootpassword --cpus 4 --ram 8192 --size 60
|
||||
```
|
||||
|
||||
|
||||
##### 2. Configure VM from within
|
||||
- After logging into your VM run this block and follow the prompts carefully:
|
||||
- After logging into your VM, using `login: root` and `password: <YOUR_PASSWORD>`, get second script to configure the VM from within:
|
||||
```bash
|
||||
wget "https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/kvm-setup/configure-vm.sh"
|
||||
chmod +x ./configure-vm.sh
|
||||
```
|
||||
|
||||
- Likely your connection won't work and therefore you need to create the script manually, open a text editor:
|
||||
```sh
|
||||
nano configure-vm.sh
|
||||
```
|
||||
|
||||
- Paste there [this content](https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/kvm-setup/configure-vm.sh)
|
||||
- Save and exit
|
||||
- Run this block and follow the prompts carefully, or provide with arguments:
|
||||
|
||||
```sh
|
||||
# interactive CLI
|
||||
./configure-vm.sh
|
||||
|
||||
# arguments - see --help menu
|
||||
./configure-vm.sh --help
|
||||
|
||||
# example
|
||||
# ./configure-vm.sh --interface enp1s0 --ipv4 192.168.1.100 --gateway4 192.168.1.1 --ipv6 2001:db8::1 --gateway6 2001:db8::fffe
|
||||
```
|
||||
</ Steps>
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Tabs } from 'nextra/components';
|
||||
import { Steps } from 'nextra/components';
|
||||
import { RunTabs } from 'components/operators/nodes/node-run-command-tabs';
|
||||
import { VarInfo } from 'components/variable-info.tsx';
|
||||
import { AccordionTemplate } from 'components/accordion-template.tsx';
|
||||
|
||||
# Orchestrating Nym Nodes with Ansible
|
||||
|
||||
@@ -95,14 +96,13 @@ Before starting Ansible, ensure that your `A` and `AAAA` records are pointed to
|
||||
<Steps>
|
||||
###### 1. Configure global variables:
|
||||
- Open `playbooks/group_vars/all.yml`
|
||||
- Setup any variables which you want to have propagated on all your nodes globally
|
||||
- Define all values under the section labeled as `## MANDATORY - uncomment & define` - these values will be propagated on all your nodes globally
|
||||
- Optionally define values of your choice under the section `## OPTIONAL - uncomment & define`
|
||||
- Note that in the next step we will be setting up a node inventory, where each of the variable can be configured per node, taking priority over the global ones.
|
||||
- Setup a correct path for your SSH kety to `ansible_ssh_private_key_file:`
|
||||
- Use these variables or comment them out with `#`:
|
||||
- `ansible_user`
|
||||
- `email`
|
||||
- `website`
|
||||
- `description`
|
||||
- Setup a correct path for your SSH kety to `ansible_ssh_private_key_file:`, alternatively export your SSH key as an env var and use this:
|
||||
```sh
|
||||
ansible_ssh_private_key_file: "{{ lookup('env', '<YOUR_ANSIBLE SSH_KEY_ENV_VAR>') }}"
|
||||
```
|
||||
- Keep `hostname=""` as a fallback for nodes without a hostname
|
||||
|
||||
###### 2. Create node inventory:
|
||||
@@ -111,11 +111,11 @@ Before starting Ansible, ensure that your `A` and `AAAA` records are pointed to
|
||||
```sh
|
||||
node1 ansible_host=<YOUR_SERVER_IP> ansible_user=<USER> hostname=<HOSTNAME> location=<LOCATION> email=<EMAIL> mode=<MODE> wireguard_enabled=<true/false> moniker=<MONIKER> description=<DESCRIPTION>
|
||||
```
|
||||
- These are mandatory values specific for each node - must be defined in the inventory:
|
||||
- Mandatory values specific for each node - must be defined in the inventory:
|
||||
- `ansible_host`: IPv4 host address
|
||||
- `hostname`: node domain, otherwise fallbacks to `""` for nodes without domain
|
||||
- `location`: node server location
|
||||
- These are mandatory values which can be setup per node or in `group_vars/all` globally:
|
||||
- Mandatory values which can be setup per node or in `group_vars/all` globally:
|
||||
- `ansible_user`
|
||||
- `email`
|
||||
- `website`
|
||||
@@ -123,6 +123,7 @@ node1 ansible_host=<YOUR_SERVER_IP> ansible_user=<USER> hostname=<HOSTNAME> loca
|
||||
- `description`
|
||||
- `mode`
|
||||
- `wireguard_enabled`
|
||||
- `accept_operator_terms` - **Make sure to read [Nym Operators Terms & Conditions](/operators/nodes/nym-node/setup#terms--conditions) first!**
|
||||
|
||||
###### 3. Test your setup
|
||||
Run this command to check if everything is configured correctly in your inventory:
|
||||
@@ -131,17 +132,12 @@ cd playbooks
|
||||
ansible-inventory --graph
|
||||
```
|
||||
|
||||
###### 4. Configure `nym-node run` command arguments
|
||||
###### 4. Optional: remove some of `nym-node run` command arguments
|
||||
These variables are read by the main task for `nym-node` installation: `roles/nym/tasks/config.yaml`
|
||||
|
||||
Open `roles/nym/defaults/main.yml` and have a look on the variables used:
|
||||
|
||||
- If you agree with [Terms and conditions](/operators/nodes/nym-node/setup#terms--conditions) uncomment the line: `accept_operator_terms: true` without which your node can never take part in Nym Network.
|
||||
- The rest is up to your configuration but generally these flags workflows
|
||||
|
||||
These variables are read by the main task for `nym-node` installation: `roles/nym/tasks/config.yaml`
|
||||
- Open that yaml and have a look on the flags
|
||||
- In case of not needing some of the, delete them (ie when running `--mode mixnode` you can delete everything from `--hostname` to `--announce-wss-port`)
|
||||
|
||||
###### 5. Configure `deploy.yml` playbook
|
||||
###### 5. Optional: Configure `deploy.yml` playbook
|
||||
Open `playbooks/deploy.yml` and comment out `tunnel` and `quic` roles in case of running your playbook for nodes in a mode `mixnode`.
|
||||
|
||||
Save all the files and test with:
|
||||
@@ -159,11 +155,13 @@ This chapter describes fundamental commands for using Ansible playbooks in relat
|
||||
|
||||
### Logic
|
||||
|
||||
<AccordionTemplate name="See Ansible logic description">
|
||||
|
||||
The main logic of the playbook flow when running with a basic command and playbook like this:
|
||||
```sh
|
||||
ansible-playbook <PLAYBOOK>.yml
|
||||
```
|
||||
<Steps>
|
||||
<Steps>
|
||||
###### 1. Read inventory
|
||||
Ansible parses `inventory/all` and performs the playbook on all entries in it, unless specified otherwise
|
||||
|
||||
@@ -175,7 +173,8 @@ Ansible parses `group_vars/all.yml` and asigns global variables to all inventory
|
||||
###### 3. Follow roles in the playbook
|
||||
Ansible reads the roles defined in `<PLAYBOOK>.yml` passed with the command and executes the tasks defined under each role
|
||||
|
||||
</ Steps>
|
||||
</ Steps>
|
||||
</AccordionTemplate>
|
||||
|
||||
### Usage
|
||||
|
||||
@@ -237,6 +236,17 @@ cd playbooks
|
||||
ansible-playbook system-maintenance.yml
|
||||
```
|
||||
|
||||
###### 5. Mitigate kernel CVE
|
||||
|
||||
This playbook is to mitigate some of the Kernel issues found in April and May 2026.
|
||||
|
||||
This playbook will run roles on all the inventory entries in parallel by default.
|
||||
|
||||
```sh
|
||||
cd playbooks
|
||||
ansible-playbook mitigate_kernel_CVE.yml
|
||||
```
|
||||
|
||||
</ Steps>
|
||||
|
||||
|
||||
@@ -248,7 +258,7 @@ ansible-playbook system-maintenance.yml
|
||||
|
||||
<Steps>
|
||||
|
||||
###### One node at a time
|
||||
###### Node limit
|
||||
To test new configuration, it's advised to try it on one server at first. Of course you can comment out any entries in the inventory, but there are easier ways to do it.
|
||||
|
||||
- Provide flag `-l` followed by inventory entry and Ansible will change state only of that entry:
|
||||
@@ -261,11 +271,14 @@ ansible-playbook upgrade.yml -l node1
|
||||
# point to multiple entries
|
||||
ansible-playbook upgrade.yml -l "node1,node2"
|
||||
|
||||
# use regex
|
||||
# use regex - ie all exit nodes
|
||||
ansible-playbook upgrade.yml -l "*exit*"
|
||||
|
||||
# use group in inventory labeled as [group]
|
||||
ansible-playbook deploy.yml -l new_nodes
|
||||
```
|
||||
|
||||
###### Role limit
|
||||
###### Tag selection
|
||||
|
||||
<Callout>
|
||||
To update your exit policy by using the newest [NTM](https://github.com/nymtech/nym/blob/develop/scripts/nym-node-setup/network-tunnel-manager.sh) via Ansible, just run:
|
||||
|
||||
@@ -1,36 +1,101 @@
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
# detect active network interface
|
||||
INTERFACE=$(ip -o link show | awk -F': ' '{print $2}' | grep -v lo | head -n 1)
|
||||
usage() {
|
||||
local code="${1:-0}"
|
||||
cat <<EOF
|
||||
Usage: $0 [OPTIONS]
|
||||
|
||||
echo "Detected active network interface: $INTERFACE"
|
||||
read -p "Is this correct? (y/n): " CONFIRM
|
||||
if [[ "$CONFIRM" != "y" ]]; then
|
||||
echo "Exiting. Please manually specify the correct network interface."
|
||||
Options:
|
||||
-i, --interface Network interface (optional; auto-detected if omitted)
|
||||
-4, --ipv4 IPv4 address for the VM (optional)
|
||||
-6, --ipv6 IPv6 address for the VM (optional)
|
||||
-g, --gateway4 IPv4 gateway of the host server (optional)
|
||||
-G, --gateway6 IPv6 gateway of the host server (optional)
|
||||
-y, --yes Skip all confirmation prompts (auto-confirm)
|
||||
-h, --help Show this help message
|
||||
|
||||
Example:
|
||||
$0 --ipv4 192.168.1.100 --gateway4 192.168.1.1 --ipv6 2001:db8::1 --gateway6 2001:db8::fffe
|
||||
$0 --ipv4 192.168.1.100 --gateway4 192.168.1.1 --yes
|
||||
EOF
|
||||
exit "$code"
|
||||
}
|
||||
|
||||
# --- parse flags ---
|
||||
INTERFACE=""
|
||||
IPv4_VM=""
|
||||
IPv6_VM=""
|
||||
IPv4_GATEWAY_HOST_SERVER=""
|
||||
IPv6_GATEWAY_HOST_SERVER=""
|
||||
AUTO_YES=false
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-i|--interface)
|
||||
[[ -n "${2:-}" && "${2:0:1}" != "-" ]] || { echo "Error: --interface requires a value."; exit 1; }
|
||||
INTERFACE="$2"; shift 2 ;;
|
||||
-4|--ipv4)
|
||||
[[ -n "${2:-}" && "${2:0:1}" != "-" ]] || { echo "Error: --ipv4 requires a value."; exit 1; }
|
||||
IPv4_VM="$2"; shift 2 ;;
|
||||
-6|--ipv6)
|
||||
[[ -n "${2:-}" && "${2:0:1}" != "-" ]] || { echo "Error: --ipv6 requires a value."; exit 1; }
|
||||
IPv6_VM="$2"; shift 2 ;;
|
||||
-g|--gateway4)
|
||||
[[ -n "${2:-}" && "${2:0:1}" != "-" ]] || { echo "Error: --gateway4 requires a value."; exit 1; }
|
||||
IPv4_GATEWAY_HOST_SERVER="$2"; shift 2 ;;
|
||||
-G|--gateway6)
|
||||
[[ -n "${2:-}" && "${2:0:1}" != "-" ]] || { echo "Error: --gateway6 requires a value."; exit 1; }
|
||||
IPv6_GATEWAY_HOST_SERVER="$2"; shift 2 ;;
|
||||
-y|--yes) AUTO_YES=true; shift ;;
|
||||
-h|--help) usage ;;
|
||||
*)
|
||||
echo "Error: Unknown option: $1"
|
||||
usage 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# at least one of IPv4 or IPv6 must be provided
|
||||
if [[ -z "$IPv4_VM" && -z "$IPv6_VM" ]]; then
|
||||
echo "Error: At least one of --ipv4 or --ipv6 must be provided."
|
||||
echo "Run '$0 --help' for usage."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# prompt for network settings
|
||||
read -p "Enter IPv4 address for VM (leave blank if not used): " IPv4_VM
|
||||
read -p "Enter IPv6 address for VM (leave blank if not used): " IPv6_VM
|
||||
read -p "Enter IPv4 gateway (host server, leave blank if not used): " IPv4_GATEWAY_HOST_SERVER
|
||||
read -p "Enter IPv6 gateway (host server, leave blank if not used): " IPv6_GATEWAY_HOST_SERVER
|
||||
confirm() {
|
||||
local prompt="$1"
|
||||
if $AUTO_YES; then
|
||||
echo "${prompt} [Y/n] (auto-confirmed)"
|
||||
return 0
|
||||
fi
|
||||
read -p "${prompt} [Y/n]: " REPLY
|
||||
[[ -z "$REPLY" || "$REPLY" == "y" || "$REPLY" == "Y" ]]
|
||||
}
|
||||
|
||||
# resize partition
|
||||
# --- detect or validate interface ---
|
||||
if [[ -z "$INTERFACE" ]]; then
|
||||
INTERFACE=$(ip -o link show | awk -F': ' '{print $2}' | grep -v lo | head -n 1)
|
||||
echo "Detected active network interface: $INTERFACE"
|
||||
if ! confirm "Is this correct?"; then
|
||||
echo "Exiting. Re-run with --interface <name> to specify one manually."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "Using network interface: $INTERFACE"
|
||||
fi
|
||||
|
||||
# --- resize partition ---
|
||||
echo "Expanding partition and resizing filesystem..."
|
||||
growpart /dev/vda 1
|
||||
resize2fs /dev/vda1
|
||||
df -h
|
||||
|
||||
# ask before continuing
|
||||
read -p "Continue with network configuration? (y/n): " CONTINUE
|
||||
if [[ "$CONTINUE" != "y" ]]; then
|
||||
if ! confirm "Continue with network configuration?"; then
|
||||
echo "Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# generate Netplan config
|
||||
# --- generate Netplan config ---
|
||||
NETPLAN_CONFIG="/etc/netplan/01-network-config.yaml"
|
||||
echo "Creating Netplan configuration at $NETPLAN_CONFIG..."
|
||||
|
||||
@@ -45,28 +110,19 @@ network:
|
||||
addresses:
|
||||
EOF
|
||||
|
||||
# append IPv4 address if provided
|
||||
if [[ -n "$IPv4_VM" ]]; then
|
||||
echo " - $IPv4_VM/24" >> $NETPLAN_CONFIG
|
||||
fi
|
||||
[[ -n "$IPv4_VM" ]] && echo " - $IPv4_VM/24" >> $NETPLAN_CONFIG
|
||||
[[ -n "$IPv6_VM" ]] && echo " - $IPv6_VM/64" >> $NETPLAN_CONFIG
|
||||
|
||||
# append IPv6 address if provided
|
||||
if [[ -n "$IPv6_VM" ]]; then
|
||||
echo " - $IPv6_VM/64" >> $NETPLAN_CONFIG
|
||||
fi
|
||||
|
||||
echo " routes:" >> $NETPLAN_CONFIG
|
||||
|
||||
# append IPv4 route if provided
|
||||
if [[ -n "$IPv4_GATEWAY_HOST_SERVER" ]]; then
|
||||
echo " - to: default" >> $NETPLAN_CONFIG
|
||||
echo " via: $IPv4_GATEWAY_HOST_SERVER" >> $NETPLAN_CONFIG
|
||||
fi
|
||||
|
||||
# append IPv6 route if provided
|
||||
if [[ -n "$IPv6_GATEWAY_HOST_SERVER" ]]; then
|
||||
echo " - to: default" >> $NETPLAN_CONFIG
|
||||
echo " via: $IPv6_GATEWAY_HOST_SERVER" >> $NETPLAN_CONFIG
|
||||
if [[ -n "$IPv4_GATEWAY_HOST_SERVER" || -n "$IPv6_GATEWAY_HOST_SERVER" ]]; then
|
||||
echo " routes:" >> $NETPLAN_CONFIG
|
||||
if [[ -n "$IPv4_GATEWAY_HOST_SERVER" ]]; then
|
||||
echo " - to: default" >> $NETPLAN_CONFIG
|
||||
echo " via: $IPv4_GATEWAY_HOST_SERVER" >> $NETPLAN_CONFIG
|
||||
fi
|
||||
if [[ -n "$IPv6_GATEWAY_HOST_SERVER" ]]; then
|
||||
echo " - to: default" >> $NETPLAN_CONFIG
|
||||
echo " via: $IPv6_GATEWAY_HOST_SERVER" >> $NETPLAN_CONFIG
|
||||
fi
|
||||
fi
|
||||
|
||||
cat <<EOF >> $NETPLAN_CONFIG
|
||||
@@ -78,58 +134,43 @@ cat <<EOF >> $NETPLAN_CONFIG
|
||||
- 2001:4860:4860::8888 # Google IPv6 DNS
|
||||
EOF
|
||||
|
||||
# secure Netplan config
|
||||
chmod 600 $NETPLAN_CONFIG
|
||||
|
||||
# generate Netplan configuration
|
||||
netplan generate
|
||||
|
||||
# ask before applying Netplan
|
||||
read -p "Apply Netplan changes? (y/n): " CONTINUE
|
||||
if [[ "$CONTINUE" != "y" ]]; then
|
||||
if ! confirm "Apply Netplan changes?"; then
|
||||
echo "Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# apply Netplan and verify settings
|
||||
netplan --debug apply
|
||||
|
||||
# show IP configurations
|
||||
ip -4 a
|
||||
ip -6 a
|
||||
ip -4 r
|
||||
ip -6 r
|
||||
|
||||
# test network connectivity
|
||||
echo "Testing IPv4 connectivity for 10 seconds..."
|
||||
timeout 10 ping -4 google.com
|
||||
|
||||
echo "Testing IPv6 connectivity for 10 seconds..."
|
||||
timeout 10 ping -6 google.com
|
||||
|
||||
# ask before updating system
|
||||
read -p "Proceed with system update and upgrade? (y/n): " CONTINUE
|
||||
if [[ "$CONTINUE" != "y" ]]; then
|
||||
echo "Skipping updates."
|
||||
else
|
||||
if confirm "Proceed with system update and upgrade?"; then
|
||||
apt update && apt upgrade -y
|
||||
else
|
||||
echo "Skipping updates."
|
||||
fi
|
||||
|
||||
# generate SSH host keys without password
|
||||
# --- SSH setup ---
|
||||
echo "Generating SSH host keys..."
|
||||
ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N ""
|
||||
ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N ""
|
||||
ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N ""
|
||||
ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N ""
|
||||
ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N ""
|
||||
ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N ""
|
||||
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""
|
||||
|
||||
# restart SSH service
|
||||
systemctl restart ssh.service
|
||||
|
||||
# ensure ~/.ssh directory exists
|
||||
mkdir -p ~/.ssh
|
||||
|
||||
# Open authorized_keys file for user input
|
||||
echo "# Add your admin SSH keys here, save and exit!" > ~/.ssh/authorized_keys
|
||||
nano ~/.ssh/authorized_keys
|
||||
|
||||
echo "Setup complete! Try to ping and ssh from the outside before killing this console"
|
||||
echo "Setup complete! Try to ping and ssh from the outside before killing this console"
|
||||
@@ -1,6 +1,86 @@
|
||||
#!/bin/bash
|
||||
|
||||
# check if noble-server-cloudimg-amd64.img is in working dir - if not, wget it
|
||||
usage() {
|
||||
local code="${1:-0}"
|
||||
cat <<EOF
|
||||
Usage: $0 [OPTIONS]
|
||||
|
||||
Options:
|
||||
-n, --name VM name (required)
|
||||
-p, --password Root password (required)
|
||||
-c, --cpus Number of vCPUs (required)
|
||||
-r, --ram RAM in MB (required); e.g. 2048, 4096, 8192
|
||||
-s, --size Disk size to add in GB (required); e.g. 50, 100, 200
|
||||
-h, --help Show this help message
|
||||
|
||||
Example:
|
||||
$0 --name myvm --password secret --cpus 4 --ram 8192 --size 100
|
||||
EOF
|
||||
exit "$code"
|
||||
}
|
||||
|
||||
# --- parse flags ---
|
||||
VM_NAME=""
|
||||
PASSWORD=""
|
||||
VCPUS=""
|
||||
RAM=""
|
||||
SIZE=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-n|--name)
|
||||
[[ -n "${2:-}" && "${2:0:1}" != "-" ]] || { echo "Error: --name requires a value."; exit 1; }
|
||||
VM_NAME="$2"; shift 2 ;;
|
||||
-p|--password)
|
||||
[[ -n "${2:-}" && "${2:0:1}" != "-" ]] || { echo "Error: --password requires a value."; exit 1; }
|
||||
PASSWORD="$2"; shift 2 ;;
|
||||
-c|--cpus)
|
||||
[[ -n "${2:-}" && "${2:0:1}" != "-" ]] || { echo "Error: --cpus requires a value."; exit 1; }
|
||||
VCPUS="$2"; shift 2 ;;
|
||||
-r|--ram)
|
||||
[[ -n "${2:-}" && "${2:0:1}" != "-" ]] || { echo "Error: --ram requires a value."; exit 1; }
|
||||
RAM="$2"; shift 2 ;;
|
||||
-s|--size)
|
||||
[[ -n "${2:-}" && "${2:0:1}" != "-" ]] || { echo "Error: --size requires a value."; exit 1; }
|
||||
SIZE="$2"; shift 2 ;;
|
||||
-h|--help) usage ;;
|
||||
*)
|
||||
echo "Error: Unknown option: $1"
|
||||
usage 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# --- validate required flags ---
|
||||
MISSING=()
|
||||
[[ -z "$VM_NAME" ]] && MISSING+=("--name")
|
||||
[[ -z "$PASSWORD" ]] && MISSING+=("--password")
|
||||
[[ -z "$VCPUS" ]] && MISSING+=("--cpus")
|
||||
[[ -z "$RAM" ]] && MISSING+=("--ram")
|
||||
[[ -z "$SIZE" ]] && MISSING+=("--size")
|
||||
|
||||
if [[ ${#MISSING[@]} -gt 0 ]]; then
|
||||
echo "Error: Missing required flags: ${MISSING[*]}"
|
||||
echo "Run '$0 --help' for usage."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! "$VCPUS" =~ ^[0-9]+$ || "$VCPUS" -lt 1 ]]; then
|
||||
echo "Error: --cpus must be a positive integer."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! "$RAM" =~ ^[0-9]+$ || "$RAM" -lt 256 ]]; then
|
||||
echo "Error: --ram must be a positive integer (minimum 256 MB)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! "$SIZE" =~ ^[0-9]+$ || "$SIZE" -lt 1 ]]; then
|
||||
echo "Error: --size must be a positive integer in GB."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- check / download base image ---
|
||||
if [[ ! -f noble-server-cloudimg-amd64.img ]]; then
|
||||
echo "Base image not found. Downloading noble-server-cloudimg-amd64.img..."
|
||||
wget https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
|
||||
@@ -10,99 +90,40 @@ if [[ ! -f noble-server-cloudimg-amd64.img ]]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# prompt for VM_NAME
|
||||
read -p "Enter VM name: " VM_NAME
|
||||
if [[ -z "$VM_NAME" ]]; then
|
||||
echo "Error: VM_NAME cannot be empty. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# prompt for PASSWORD w silent input
|
||||
read -s -p "Enter password for the VM: " PASSWORD
|
||||
echo
|
||||
if [[ -z "$PASSWORD" ]]; then
|
||||
echo "Error: PASSWORD cannot be empty. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# prompt for number of vCPUs
|
||||
read -p "Enter the number of vCPUs for the VM: " VCPUS
|
||||
if [[ -z "$VCPUS" || ! "$VCPUS" =~ ^[0-9]+$ ]]; then
|
||||
echo "Error: Invalid number of vCPUs. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# prompt for RAM size with suggestions
|
||||
DEFAULT_RAM=4096
|
||||
HALF_RAM=$((DEFAULT_RAM / 2))
|
||||
DOUBLE_RAM=$((DEFAULT_RAM * 2))
|
||||
TRIPLE_RAM=$((DEFAULT_RAM * 3))
|
||||
FOUR_TIMES_RAM=$((DEFAULT_RAM * 4))
|
||||
SIX_TIMES_RAM=$((DEFAULT_RAM * 6))
|
||||
EIGHT_TIMES_RAM=$((DEFAULT_RAM * 8))
|
||||
|
||||
echo "Choose the amount of RAM for the VM:"
|
||||
echo "1) $HALF_RAM MB"
|
||||
echo "2) $DEFAULT_RAM MB (recommended)"
|
||||
echo "3) $DOUBLE_RAM MB"
|
||||
echo "4) $TRIPLE_RAM MB"
|
||||
echo "5) $FOUR_TIMES_RAM MB"
|
||||
echo "6) $SIX_TIMES_RAM MB"
|
||||
echo "7) $EIGHT_TIMES_RAM MB"
|
||||
read -p "Enter your choice (1-7) or specify a custom amount in MB: " RAM_CHOICE
|
||||
|
||||
case $RAM_CHOICE in
|
||||
1) RAM=$HALF_RAM ;;
|
||||
2) RAM=$DEFAULT_RAM ;;
|
||||
3) RAM=$DOUBLE_RAM ;;
|
||||
4) RAM=$TRIPLE_RAM ;;
|
||||
5) RAM=$FOUR_TIMES_RAM ;;
|
||||
6) RAM=$SIX_TIMES_RAM ;;
|
||||
7) RAM=$EIGHT_TIMES_RAM ;;
|
||||
*)
|
||||
if [[ "$RAM_CHOICE" =~ ^[0-9]+$ ]]; then
|
||||
RAM=$RAM_CHOICE
|
||||
else
|
||||
echo "Invalid choice. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# define image path
|
||||
IMAGE_PATH="/var/lib/libvirt/images/${VM_NAME}.img"
|
||||
|
||||
# copy the base image
|
||||
|
||||
if [[ -e "$IMAGE_PATH" ]]; then
|
||||
echo "Error: $IMAGE_PATH already exists. Choose a different --name or remove the old image first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Copying the base image to $IMAGE_PATH..."
|
||||
cp noble-server-cloudimg-amd64.img "$IMAGE_PATH"
|
||||
|
||||
# install guestfs-tools if missing
|
||||
echo "Checking and installing guestfs-tools if needed..."
|
||||
if ! dpkg -l | grep -q guestfs-tools; then
|
||||
sudo apt update && sudo apt install guestfs-tools -y
|
||||
fi
|
||||
|
||||
# set root password inside the image
|
||||
echo "Setting root password inside the VM image..."
|
||||
virt-customize -a "$IMAGE_PATH" --root-password password:"$PASSWORD"
|
||||
|
||||
# resize the image
|
||||
echo "Resizing the image by +100G..."
|
||||
qemu-img resize "$IMAGE_PATH" +100G
|
||||
echo "Resizing the image by +${SIZE}G..."
|
||||
qemu-img resize "$IMAGE_PATH" +${SIZE}G
|
||||
|
||||
# install the VM and run log in prompt
|
||||
echo "Starting VM installation..."
|
||||
virt-install \
|
||||
--name "$VM_NAME" \
|
||||
--ram="$RAM" \
|
||||
--vcpus="$VCPUS" \
|
||||
--cpu host \
|
||||
--hvm \
|
||||
--disk bus=virtio,path="$IMAGE_PATH" \
|
||||
--network bridge=br0 \
|
||||
--graphics none \
|
||||
--console pty,target_type=serial \
|
||||
--osinfo ubuntunoble \
|
||||
--import
|
||||
--name "$VM_NAME" \
|
||||
--ram="$RAM" \
|
||||
--vcpus="$VCPUS" \
|
||||
--cpu host \
|
||||
--hvm \
|
||||
--disk bus=virtio,path="$IMAGE_PATH" \
|
||||
--network bridge=br0 \
|
||||
--graphics none \
|
||||
--console pty,target_type=serial \
|
||||
--osinfo ubuntunoble \
|
||||
--import
|
||||
|
||||
echo "VM $VM_NAME has been successfully installed!"
|
||||
echo "VM $VM_NAME has been successfully installed!"
|
||||
Reference in New Issue
Block a user