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

feat: deploy faucet as a service #4

Merged
merged 6 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,21 @@ cargo run -- clean --name beta --provider digital-ocean

This will use Terraform to tear down all the droplets it created.

## Building VM Images

This repository also contains a [Packer](https://www.packer.io/) template for constructing a VM image that has tools on it for building Rust code. With the tools preinstalled, the time to deploy the testnet is significantly reduced.

Regenerating the image should be something that's infrequent, so as of yet there's no command in the deploy binary for generating it. However, it's a simple process. First, install Packer on your system; like Terraform, it's widely available in package managers. Then after that:

```
export DIGITALOCEAN_TOKEN=<your PAT>
cd resources/packer
packer init
jacderida marked this conversation as resolved.
Show resolved Hide resolved
packer build build.pkr.hcl
```

This will produce a VM image that can now be launched as a droplet.

## License

This repository is licensed under the BSD-3-Clause license.
Expand Down
2 changes: 1 addition & 1 deletion resources/ansible/ansible.cfg
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[defaults]
host_key_checking = False
forks = 10
forks = 20
16 changes: 11 additions & 5 deletions resources/ansible/build.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
---
- name: build a custom node binary
# We always build the faucet binary, but safenode only applies for using a custom branch.
- name: build binaries
hosts: all
become: False
roles:
- role: prerequisites
become: True
- role: rust
- role: build_node
- {
role: build_safe_network_binary,
bin_name: "faucet"
}
- {
role: build_safe_network_binary,
bin_name: "safenode",
when: custom_safenode == "true"
}
8 changes: 8 additions & 0 deletions resources/ansible/create_build_image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
- name: build a custom node binary
hosts: all
become: False
roles:
- role: prerequisites
become: True
- role: rust
9 changes: 9 additions & 0 deletions resources/ansible/create_node_image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
- name: build a custom node image
hosts: all
become: False
roles:
- role: prerequisites
become: True
- role: logstash
become: True
34 changes: 34 additions & 0 deletions resources/ansible/faucet.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
- name: deploy faucet to genesis node
hosts: all
become: False
roles:
- role: prerequisites
become: True
- {
role: format_disk,
become: True,
block_device: "{{ block_device }}",
mount_info:
{ name: "{{ node_data_mount_path }}", owner: "root", group: "root", mode: 0755 },
when: provider == "aws"
}
- faucet
tasks:
# Something is wrong with the journal service on Ubuntu that causes no
# output to be produced when running `journalctl`. The solution seemed
# to be restarting the service.
- name: restart systemd-journald
become: True
ansible.builtin.systemd:
name: systemd-journald
state: restarted
enabled: yes
# For reasons not clear, the faucet service just does not run correctly
# on first try.
- name: restart faucet
become: True
ansible.builtin.systemd:
name: faucet
state: restarted
enabled: yes
1 change: 0 additions & 1 deletion resources/ansible/roles/build_node/defaults/main.yml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
bin_name: safenode
org: maidsafe
branch: main
bin_archive_filename: "{{ bin_name }}-{{ testnet_name }}-x86_64-unknown-linux-musl.tar.gz"
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,31 @@
version: "{{ branch }}"
dest: "{{ ansible_env.HOME }}/safe_network"

- name: build safenode
- name: "build {{ bin_name }} binary"
ansible.builtin.shell: |
source $HOME/.cargo/env
cargo build --target x86_64-unknown-linux-musl --release --bin safenode
cargo build --target x86_64-unknown-linux-musl --release --bin {{bin_name}}
args:
chdir: "{{ ansible_env.HOME }}/safe_network"
creates: "{{ ansible_env.HOME }}/safe_network/target/x86_64-unknown-linux-musl/release/safenode"
creates: "{{ ansible_env.HOME }}/safe_network/target/x86_64-unknown-linux-musl/release/{{bin_name}}"
executable: /bin/bash

- name: copy safenode binary to tmp directory
- name: copy binary to tmp directory
ansible.builtin.command:
chdir: "{{ ansible_env.HOME }}/safe_network/target/x86_64-unknown-linux-musl/release"
cmd: cp safenode /tmp/
cmd: cp {{bin_name}} /tmp/

- name: archive binary
ansible.builtin.command:
chdir: /tmp/
cmd: tar -zcvf {{ node_archive_filename }} safenode
cmd: tar -zcvf {{ bin_archive_filename }} {{ bin_name }}

- name: upload safenode archive to S3
- name: upload archive to S3
amazon.aws.s3_object:
access_key: AKIAVVODCRMSELAPBQHK
secret_key: "{{ aws_secret_key }}"
bucket: sn-node
object: /{{ org }}/{{ branch }}/{{ node_archive_filename }}
src: /tmp/{{ node_archive_filename }}
object: /{{ org }}/{{ branch }}/{{ bin_archive_filename }}
src: /tmp/{{ bin_archive_filename }}
mode: put
permission: public-read
6 changes: 6 additions & 0 deletions resources/ansible/roles/faucet/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
org: maidsafe
branch: main
faucet_archive_filename: faucet-{{ testnet_name }}-x86_64-unknown-linux-musl.tar.gz
faucet_archive_url: https://sn-node.s3.eu-west-2.amazonaws.com/{{ org }}/{{ branch }}/{{ faucet_archive_filename }}
faucet_archive_dest_path: /usr/local/bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
$ANSIBLE_VAULT;1.1;AES256
39346266333761643830393437663034646132346465343137613862623636653237336466633539
3766633536326162626533316633363938363966353639340a333130363935383339646539363264
39303235316330613065616334386238633436336436326532333762663434363761636566323865
3565616363316536660a386163626466393230376561373236653063623530613765333061383136
30323638303962353065646434323463626334326337383764616163326539396365303038343835
3535313466316230313336633566323130613834376337323832
31 changes: 31 additions & 0 deletions resources/ansible/roles/faucet/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
- name: get the faucet archive
ansible.builtin.get_url:
url: "{{ faucet_archive_url }}"
dest: /tmp/{{ faucet_archive_filename }}

- name: extract the node binary
jacderida marked this conversation as resolved.
Show resolved Hide resolved
become: True
ansible.builtin.unarchive:
src: "/tmp/{{ faucet_archive_filename }}"
dest: "{{ faucet_archive_dest_path }}"
remote_src: True

- name: copy service file
become: True
template:
src: faucet.service.j2
dest: /etc/systemd/system/faucet.service
register: service_template_created

- name: reload the system manager configuration
become: True
command: systemctl daemon-reload
when: service_template_created.changed

- name: start the faucet service
become: True
systemd:
name: faucet
state: started
enabled: yes
13 changes: 13 additions & 0 deletions resources/ansible/roles/faucet/templates/faucet.service.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[Unit]
Description=Safe Faucet Service

[Service]
ExecStart={{ faucet_archive_dest_path }}/faucet \
--peer {{ genesis_multiaddr }} \
server
StandardOutput=journal
StandardError=inherit
User=safe

[Install]
WantedBy=multi-user.target
35 changes: 0 additions & 35 deletions resources/ansible/roles/log_forwarding/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,39 +1,4 @@
---
- name: install dependencies
apt:
name: apt-transport-https
state: present
update_cache: yes
register: result
until: result is succeeded
retries: 5
delay: 10

- name: import gpg key for logstash
apt_key:
url: https://artifacts.elastic.co/GPG-KEY-elasticsearch
state: present

- name: add logstash repository
apt_repository:
repo: "deb https://artifacts.elastic.co/packages/8.x/apt stable main"
state: present

- name: install logstash
apt:
name: logstash
state: latest
update_cache: yes

- name: check if aws integration plugin is installed
command: /usr/share/logstash/bin/logstash-plugin list
register: plugin_list
changed_when: false # this command does not change the state

- name: install aws integration plugin
command: /usr/share/logstash/bin/logstash-plugin install logstash-integration-aws
when: "'logstash-integration-aws' not in plugin_list.stdout_lines"

- name: include aws keys
include_vars: secrets.yml
no_log: true
Expand Down
35 changes: 35 additions & 0 deletions resources/ansible/roles/logstash/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
- name: install dependencies
apt:
name: apt-transport-https
state: present
update_cache: yes
register: result
until: result is succeeded
retries: 5
delay: 10

- name: import gpg key for logstash
apt_key:
url: https://artifacts.elastic.co/GPG-KEY-elasticsearch
state: present

- name: add logstash repository
apt_repository:
repo: "deb https://artifacts.elastic.co/packages/8.x/apt stable main"
state: present

- name: install logstash
apt:
name: logstash
state: latest
update_cache: yes

- name: check if aws integration plugin is installed
command: /usr/share/logstash/bin/logstash-plugin list
register: plugin_list
changed_when: false # this command does not change the state

- name: install aws integration plugin
command: /usr/share/logstash/bin/logstash-plugin install logstash-integration-aws
when: "'logstash-integration-aws' not in plugin_list.stdout_lines"
1 change: 1 addition & 0 deletions resources/ansible/roles/prerequisites/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- heaptrack
- python3
- python3-pip
- ripgrep
- zip
register: result
until: result is succeeded
Expand Down
71 changes: 71 additions & 0 deletions resources/packer/build.pkr.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
packer {
required_plugins {
digitalocean = {
version = ">= 1.0.4"
source = "github.com/digitalocean/digitalocean"
}
ansible = {
source = "github.com/hashicorp/ansible"
version = "~> 1"
}
}
}

variable "user_home" {
default = env("HOME")
}

variable "droplet_image" {
type = string
default = "ubuntu-22-10-x64"
description = ""
}

variable "region" {
type = string
default = "lon1"
description = "This is quite a powerful image but it means the build time will be fast"
}

variable "size" {
type = string
default = "s-8vcpu-16gb"
description = "This is quite a powerful image but it means the build time will be fast"
}

variable "ssh_username" {
type = string
default = "root"
description = "On DO the root user is used"
}

source "digitalocean" "build" {
image = var.droplet_image
region = var.region
size = var.size
snapshot_name = "safe_network-build-{{timestamp}}"
ssh_username = var.ssh_username
}

build {
name = "build-testnet-deploy"
sources = [
"source.digitalocean.build"
]
provisioner "file" {
source = "${var.user_home}/.ansible/vault-password"
destination = "/tmp/ansible-vault-password"
}
provisioner "shell" {
script = "../scripts/install_ansible.sh"
}
provisioner "ansible-local" {
playbook_dir = "../ansible"
playbook_file = "../ansible/create_build_image.yml"
extra_arguments = [
"--vault-password-file=/tmp/ansible-vault-password",
"--extra-vars",
"provider=digital-ocean",
]
}
}