From 6a00ff68f47241c741a9ca30031591b77699b6ae Mon Sep 17 00:00:00 2001 From: Wade Barnes Date: Mon, 13 Mar 2023 13:13:10 -0700 Subject: [PATCH 1/2] Add archive and restore scripts. - Ansible scripts for archiving and restoring the network configuration, keys, and ledgers for a node. Signed-off-by: Wade Barnes --- ansible/indy_node/archive.yml | 8 +++ ansible/indy_node/restore.yml | 8 +++ .../indy_node/roles/archive/defaults/main.yml | 4 ++ .../indy_node/roles/archive/tasks/archive.yml | 44 ++++++++++++++ .../indy_node/roles/archive/tasks/main.yml | 5 ++ .../indy_node/roles/restore/defaults/main.yml | 4 ++ .../indy_node/roles/restore/tasks/main.yml | 5 ++ .../indy_node/roles/restore/tasks/restore.yml | 59 +++++++++++++++++++ 8 files changed, 137 insertions(+) create mode 100644 ansible/indy_node/archive.yml create mode 100644 ansible/indy_node/restore.yml create mode 100644 ansible/indy_node/roles/archive/defaults/main.yml create mode 100644 ansible/indy_node/roles/archive/tasks/archive.yml create mode 100644 ansible/indy_node/roles/archive/tasks/main.yml create mode 100644 ansible/indy_node/roles/restore/defaults/main.yml create mode 100644 ansible/indy_node/roles/restore/tasks/main.yml create mode 100644 ansible/indy_node/roles/restore/tasks/restore.yml diff --git a/ansible/indy_node/archive.yml b/ansible/indy_node/archive.yml new file mode 100644 index 0000000..08c2f97 --- /dev/null +++ b/ansible/indy_node/archive.yml @@ -0,0 +1,8 @@ +--- +- name: Generate Network Archive + hosts: "{{ host | default('nodes') }}" + become: yes + become_method: sudo + gather_facts: false + roles: + - archive \ No newline at end of file diff --git a/ansible/indy_node/restore.yml b/ansible/indy_node/restore.yml new file mode 100644 index 0000000..9dc6cf8 --- /dev/null +++ b/ansible/indy_node/restore.yml @@ -0,0 +1,8 @@ +--- +- name: Restore Network Archive + hosts: "{{ host | default('nodes') }}" + become: yes + become_method: sudo + gather_facts: false + roles: + - restore \ No newline at end of file diff --git a/ansible/indy_node/roles/archive/defaults/main.yml b/ansible/indy_node/roles/archive/defaults/main.yml new file mode 100644 index 0000000..8f4f669 --- /dev/null +++ b/ansible/indy_node/roles/archive/defaults/main.yml @@ -0,0 +1,4 @@ +--- +# Configuration Parameters +data_volume_mount: /var/lib/indy/ +network_name: candy-dev \ No newline at end of file diff --git a/ansible/indy_node/roles/archive/tasks/archive.yml b/ansible/indy_node/roles/archive/tasks/archive.yml new file mode 100644 index 0000000..fbb64c4 --- /dev/null +++ b/ansible/indy_node/roles/archive/tasks/archive.yml @@ -0,0 +1,44 @@ +# ============================================================ +# Auto detect the hostname +# ------------------------------------------------------------ +- name: Get hostname + shell: hostname + register: hostname + +- name: Set node_name variable + set_fact: + node_name: "{{ hostname.stdout }}" +# ============================================================ + +- name: Populate service facts + service_facts: + +# Stop the indy-node service if it is running. +- name: Stop the indy-node service + service: + name: indy-node + state: stopped + when: ansible_facts.services['indy-node.service'].state == 'running' + +- name: Generate Archive + community.general.archive: + path: "{{ data_volume_mount }}{{ network_name }}" + dest: "{{ data_volume_mount }}{{ node_name }}_{{ network_name }}.gz" + +# Start the indy-node service if it was originally running +- name: Start the indy-node service + service: + name: indy-node + state: started + when: ansible_facts.services['indy-node.service'].state == 'running' + +- name: Fetch the archive + fetch: + src: "{{ data_volume_mount }}{{ node_name }}_{{ network_name }}.gz" + dest: "../{{ node_name }}_{{ network_name }}.gz" + flat: true + +- name: Remove the archive from the server + file: + path: "{{ data_volume_mount }}{{ node_name }}_{{ network_name }}.gz" + state: absent \ No newline at end of file diff --git a/ansible/indy_node/roles/archive/tasks/main.yml b/ansible/indy_node/roles/archive/tasks/main.yml new file mode 100644 index 0000000..5c0f836 --- /dev/null +++ b/ansible/indy_node/roles/archive/tasks/main.yml @@ -0,0 +1,5 @@ +--- +- name: Archive + include_tasks: archive.yml + tags: + - archive \ No newline at end of file diff --git a/ansible/indy_node/roles/restore/defaults/main.yml b/ansible/indy_node/roles/restore/defaults/main.yml new file mode 100644 index 0000000..8f4f669 --- /dev/null +++ b/ansible/indy_node/roles/restore/defaults/main.yml @@ -0,0 +1,4 @@ +--- +# Configuration Parameters +data_volume_mount: /var/lib/indy/ +network_name: candy-dev \ No newline at end of file diff --git a/ansible/indy_node/roles/restore/tasks/main.yml b/ansible/indy_node/roles/restore/tasks/main.yml new file mode 100644 index 0000000..84091c3 --- /dev/null +++ b/ansible/indy_node/roles/restore/tasks/main.yml @@ -0,0 +1,5 @@ +--- +- name: Restore + include_tasks: restore.yml + tags: + - restore \ No newline at end of file diff --git a/ansible/indy_node/roles/restore/tasks/restore.yml b/ansible/indy_node/roles/restore/tasks/restore.yml new file mode 100644 index 0000000..7cd8cb0 --- /dev/null +++ b/ansible/indy_node/roles/restore/tasks/restore.yml @@ -0,0 +1,59 @@ +# ============================================================ +# Auto detect the hostname +# ------------------------------------------------------------ +- name: Get hostname + shell: hostname + register: hostname + +- name: Set node_name variable + set_fact: + node_name: "{{ hostname.stdout }}" +# ============================================================ + +- name: Copy the archive to the server + copy: + src: "{{ playbook_dir }}/../{{ node_name }}_{{ network_name }}.gz" + dest: "{{ data_volume_mount }}{{ node_name }}_{{ network_name }}.gz" + +- name: Populate service facts + service_facts: + +# Stop the indy-node service if it is running. +- name: Stop the indy-node service + service: + name: indy-node + state: stopped + when: ansible_facts.services['indy-node.service'].state == 'running' + +- name: Delete the existing network directory + file: + path: "{{ data_volume_mount }}{{ network_name }}" + state: absent + +- name: Extract the archive to the network directory + unarchive: + src: "{{ data_volume_mount }}{{ node_name }}_{{ network_name }}.gz" + dest: "{{ data_volume_mount }}" + copy: false + +- name: Ensure network directory has the correct ownership + file: + path: "{{ item }}" + state: directory + owner: indy + group: indy + become: true + with_items: + - "{{ data_volume_mount }}{{ network_name }}" + +# Start the indy-node service if it was originally running +- name: Start indy-node service + service: + name: indy-node + state: started + when: ansible_facts.services['indy-node.service'].state == 'running' + +- name: Remove the archive from the server + file: + path: "{{ data_volume_mount }}{{ node_name }}_{{ network_name }}.gz" + state: absent \ No newline at end of file From a29a5acd92d391f085b37d8be029b6a5d96c1a6b Mon Sep 17 00:00:00 2001 From: Wade Barnes Date: Thu, 2 May 2024 08:00:23 -0700 Subject: [PATCH 2/2] Add archive/restore documentation Signed-off-by: Wade Barnes --- ansible/README.md | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/ansible/README.md b/ansible/README.md index 20f0c79..9ac7464 100644 --- a/ansible/README.md +++ b/ansible/README.md @@ -92,7 +92,7 @@ The cloud provider is defined by setting the `cloud` variable in `--extra-vars` Following network configuration the packages are installed and configured. The playbook is capable of configuring the node(s) as a genesis node, or as a new node connecting to an existing network. Node initialization occurs only once, subsequent runs of the script will detect the existing configuration and skip over any steps that have already been completed to ensure the node's configuration is not inadvertently modified. > Node Initialization: -> +> > Node initialization depends on a few things: > - **Network name** - You **MUST** supply a network name via the `network_name` variable. The name should be consistent across all nodes within the same network. The network name defines the name of the directory on the node where all of the files, keys, and data will be stored. > - **Node Alias** - The node alias is a human readable name for the node. The configuration tasks read the hostname from the node and use the value as the node alias. @@ -111,6 +111,45 @@ Following network configuration the packages are installed and configured. The There are several playbook variables that can be used to control the behaviour of the scripts. Refer to the [Playbook options](./README.md#playbook-options) section below for details. + +## Archive / Restore + +The archive and restore playbooks allow you to archive and restore the network data volumes on one or more of your nodes. The playbooks automatically stop and start the indy-node service if it is running and leave it in the state it was found once complete. + +You should explicitly define `network_name` when running the scripts to ensure it is clear which network is being archived or restored. + +:warning: _**Ensure you generate a recent archive before performing a restore operation as the files on the node will be completely replaced with the content from the specified archive set during a restore operation.**_ + +Archive files are named using the following format: `_.gz` + +### Archive + +Generates an archive containing the content of a given network contained on a node's data volume, which typically includes the genesis files, keys, and ledger data for the given network. + +The archive is generated remotely on the node and then downloaded locally before finally being removed from the node. + +Example use: +``` +ansible-playbook --user ubuntu -i beta-aws-inventory.yml --extra-vars "network_name=candy-beta" indy_node/archive.yml +``` + +### Restore + +Restores the content of an archive containing the content of a given network to a node's data volume. + +Place the archive files to be restored in the root folder (e.g. `./ansible`) where the scripts will be run. + +The archive is uploaded to the node before being extracted and finally removed from the node. + +The existing network data on the node is completely replaced by the content of the archive. In order words, the existing network data on the node is deleted before the uploaded archive is extracted. + +:warning: _**Ensure you have a recent archive before performing a restore operation as the files on the node will be completely replaced with the content from the specified archive set during a restore operation.**_ + +Example use: +``` +ansible-playbook --user ubuntu -i beta-aws-inventory.yml --extra-vars "network_name=candy-beta" indy_node/restore.yml +``` + ## Playbook options The following variables can be used to control various settings and behaviours of the playbook. The variables listed as **_required_** have defaults, however it is best to review these key variables and set them explicitly based on your environment. @@ -154,7 +193,7 @@ The following variables can be used to control various settings and behaviours o `client_port` - **_optional_** (default=`9702`) - Defines the port on which the node(s) will communicate with clients. - + `network_configuration` - **_optional_** (default=`true`) - Boolean value indicating whether or not the network configuration tasks should be run. @@ -172,4 +211,4 @@ The following variables can be used to control various settings and behaviours o - Boolean value indicating whether or not to enable and start the indy-node service. ## ToDo: -- Automate the collection of the information needed to fill out the Steward Genesis spreadsheet. \ No newline at end of file +- Automate the collection of the information needed to fill out the Steward Genesis spreadsheet.