Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Archive/Restore playbooks and documentation #75

Merged
merged 2 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 42 additions & 3 deletions ansible/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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: `<node-name>_<network-name>.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.
Expand Down Expand Up @@ -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.

Expand All @@ -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.
- Automate the collection of the information needed to fill out the Steward Genesis spreadsheet.
8 changes: 8 additions & 0 deletions ansible/indy_node/archive.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
- name: Generate Network Archive
hosts: "{{ host | default('nodes') }}"
become: yes
become_method: sudo
gather_facts: false
roles:
- archive
8 changes: 8 additions & 0 deletions ansible/indy_node/restore.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
- name: Restore Network Archive
hosts: "{{ host | default('nodes') }}"
become: yes
become_method: sudo
gather_facts: false
roles:
- restore
4 changes: 4 additions & 0 deletions ansible/indy_node/roles/archive/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
# Configuration Parameters
data_volume_mount: /var/lib/indy/
network_name: candy-dev
44 changes: 44 additions & 0 deletions ansible/indy_node/roles/archive/tasks/archive.yml
Original file line number Diff line number Diff line change
@@ -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
5 changes: 5 additions & 0 deletions ansible/indy_node/roles/archive/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
- name: Archive
include_tasks: archive.yml
tags:
- archive
4 changes: 4 additions & 0 deletions ansible/indy_node/roles/restore/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
# Configuration Parameters
data_volume_mount: /var/lib/indy/
network_name: candy-dev
5 changes: 5 additions & 0 deletions ansible/indy_node/roles/restore/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
- name: Restore
include_tasks: restore.yml
tags:
- restore
59 changes: 59 additions & 0 deletions ansible/indy_node/roles/restore/tasks/restore.yml
Original file line number Diff line number Diff line change
@@ -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