summaryrefslogtreecommitdiff
path: root/roles/radicle_node
diff options
context:
space:
mode:
Diffstat (limited to 'roles/radicle_node')
-rw-r--r--roles/radicle_node/README.md2
-rw-r--r--roles/radicle_node/files/rad-config-pin23
-rw-r--r--roles/radicle_node/files/rad-config-update34
-rw-r--r--roles/radicle_node/tasks/main.yml250
-rw-r--r--roles/radicle_node/templates/Caddyfile.j218
-rw-r--r--roles/radicle_node/templates/radicle-ci-broker.service.j218
-rw-r--r--roles/radicle_node/templates/radicle-httpd.service.j216
-rw-r--r--roles/radicle_node/templates/radicle-node.service.j216
8 files changed, 377 insertions, 0 deletions
diff --git a/roles/radicle_node/README.md b/roles/radicle_node/README.md
new file mode 100644
index 0000000..b653160
--- /dev/null
+++ b/roles/radicle_node/README.md
@@ -0,0 +1,2 @@
+This role, `radicle_node`, sets up a Debian system to be a
+[Radicle](https://radicle.xyz/) node.
diff --git a/roles/radicle_node/files/rad-config-pin b/roles/radicle_node/files/rad-config-pin
new file mode 100644
index 0000000..0e40f00
--- /dev/null
+++ b/roles/radicle_node/files/rad-config-pin
@@ -0,0 +1,23 @@
+#!/usr/bin/python3
+
+import json, os, subprocess, sys
+
+rid = sys.argv[1]
+
+p = subprocess.run(["rad", "config", "show"], check=True, capture_output=True)
+if p.returncode != 0:
+ sys.exit("rad config show failed")
+config = json.loads(p.stdout.decode())
+
+config["web"]["pinned"]["repositories"].append(rid)
+
+p = subprocess.run(["rad", "self", "--home"], check=True, capture_output=True)
+if p.returncode != 0:
+ sys.exit("rad self --home failed")
+
+home = p.stdout.decode().strip()
+filename = os.path.join(home, "config.json")
+if os.path.exists(filename):
+ os.rename(filename, filename + ".bak")
+with open(filename, "w") as f:
+ f.write(json.dumps(config, indent=4))
diff --git a/roles/radicle_node/files/rad-config-update b/roles/radicle_node/files/rad-config-update
new file mode 100644
index 0000000..40dd1a9
--- /dev/null
+++ b/roles/radicle_node/files/rad-config-update
@@ -0,0 +1,34 @@
+#!/usr/bin/python3
+
+import json, os, subprocess, sys
+
+alias = sys.argv[1]
+ext = sys.argv[2]
+policy = sys.argv[3]
+scope = sys.argv[4]
+peer = sys.argv[5]
+
+p = subprocess.run(["rad", "config", "show"], capture_output=True)
+if p.returncode != 0:
+ sys.exit("rad config show failed")
+config = json.loads(p.stdout.decode())
+
+config["node"]["alias"] = alias
+config["node"]["externalAddresses"] = [ext]
+config["node"]["policy"] = policy
+config["node"]["scope"] = scope
+
+nodes = config["node"]["connect"]
+if peer not in nodes:
+ nodes.append(peer)
+
+p = subprocess.run(["rad", "self", "--home"], check=True, capture_output=True)
+if p.returncode != 0:
+ sys.exit("rad self --home failed")
+
+home = p.stdout.decode().strip()
+filename = os.path.join(home, "config.json")
+if os.path.exists(filename):
+ os.rename(filename, filename + ".bak")
+with open(filename, "w") as f:
+ f.write(json.dumps(config, indent=4))
diff --git a/roles/radicle_node/tasks/main.yml b/roles/radicle_node/tasks/main.yml
new file mode 100644
index 0000000..e9c203a
--- /dev/null
+++ b/roles/radicle_node/tasks/main.yml
@@ -0,0 +1,250 @@
+- name: "check radicle_node_version"
+ shell: |
+ [ "{{ radicle_node_version }}" = "1" ] || \
+ (echo "Unexpected version {{ radicle_node_version }}" 1>&2; exit 1)
+
+- name: "check that radicle_node_key is set"
+ shell: |
+ echo radicle_node_key Ansible variable is not set
+ exit 1
+ when: radicle_node_key is not defined
+
+- name: "check that radicle_node_key_pub is set"
+ shell: |
+ echo radicle_node_key_pub Ansible variable is not set
+ exit 1
+ when: radicle_node_key_pub is not defined
+
+- name: "install important additional packages for Radicle"
+ apt:
+ name:
+ # For the Radicle installer
+ - curl
+
+ # Radicle is built on git.
+ - git
+
+ # Rsync for backups.
+ - rsync
+
+ # Web server for the web UI.
+ - caddy
+
+ # Radicle components.
+ - radicle
+ - radicle-ci-broker
+ - radicle-native-ci
+
+- name: "stop Radicle node if it's running"
+ shell: |
+ systemctl stop radicle-node || true
+
+- name: "stop Radicle CI broker if it's running"
+ shell: |
+ systemctl stop radicle-ci-broker || true
+
+- name: "configure git for _rad user"
+ shell: |
+ sudo -u _rad git config --global user.name "_rad"
+ sudo -u _rad git config --global user.email "liw@liw.fi"
+
+- name: "create directory for Radicle for the _rad user"
+ file:
+ state: directory
+ path: /home/_rad/.radicle
+ owner: _rad
+ group: _rad
+ mode: 0755
+
+- name: "create directory for web pages"
+ file:
+ state: directory
+ path: /srv/http
+ owner: _rad
+ group: _rad
+ mode: 0755
+
+- name: "create directory for pages from repositories"
+ file:
+ state: directory
+ path: /srv/pages
+ owner: _rad
+ group: _rad
+ mode: 0755
+
+- name: "create directory for Radicle backup"
+ when: radicle_node_backup is defined
+ file:
+ state: directory
+ path: radicle-backup
+ owner: root
+ group: root
+ mode: 0755
+
+- name: "restore from backup (step 1 or 2)"
+ when: radicle_node_backup is defined
+ synchronize:
+ src: "{{ radicle_node_backup }}/."
+ dest: radicle-backup/.
+ group: no
+ owner: no
+
+- name: "restore from backup (step 2 or 2)"
+ when: radicle_node_backup is defined
+ shell: |
+ find radicle-backup -name control.sock -delete
+ rsync -a --del radicle-backup/home/_rad/.radicle/. /home/_rad/.radicle/.
+ rsync -a --del radicle-backup/srv/http/. /srv/http/.
+ chown -R _rad:_rad /home/_rad/.radicle/. /srv/http/.
+
+- name: "create directory for Radicle keys"
+ file:
+ state: directory
+ path: /home/_rad/.radicle/keys
+ owner: _rad
+ group: _rad
+ mode: 0755
+
+- name: "install Radicle private key"
+ copy:
+ content: "{{ radicle_node_key }}"
+ dest: /home/_rad/.radicle/keys/radicle
+ owner: _rad
+ group: _rad
+ mode: 0600
+
+- name: "install Radicle public key"
+ copy:
+ content: "{{ radicle_node_key_pub }}"
+ dest: /home/_rad/.radicle/keys/radicle.pub
+ owner: _rad
+ group: _rad
+ mode: 0644
+
+- name: "install systemd unit for Radicle node"
+ template:
+ src: radicle-node.service.j2
+ dest: /lib/systemd/system/radicle-node.service
+
+- name: "init Radicle node config"
+ shell: |
+ if [ ! -e /home/_rad/.radicle/config.json ]; then
+ sudo -u _rad -i rad config init --alias "{{ radicle_node_domain_name }}"
+ fi
+
+- name: "(re)start systemd unit for Radicle node"
+ systemd:
+ name: radicle-node
+ state: restarted
+ masked: no
+ enabled: yes
+ daemon_reload: yes
+
+- name: "install script to add update Radicle config file"
+ when: radicle_node_connections is defined
+ copy:
+ src: rad-config-update
+ dest: /home/_rad/rad-config-update
+ owner: _rad
+ group: _rad
+ mode: 0755
+
+- name: "connect to other Radicle nodes"
+ when: radicle_node_connections is defined
+ with_items: "{{ radicle_node_connections }}"
+ shell: |
+ sudo -u _rad -i ./rad-config-update \
+ "{{ radicle_node_domain_name }}" \
+ "{{ radicle_node_domain_name }}:8776" \
+ "{{ radicle_node_policy }}" \
+ "{{ radicle_node_scope }}" \
+ "{{ item.nid }}@{{ item.host }}:{{ item.port }}"
+
+- name: "install script to add update Radicle repository pinning"
+ when: radicle_node_repositories is defined
+ copy:
+ src: rad-config-pin
+ dest: /home/_rad/rad-config-pin
+ owner: _rad
+ group: _rad
+ mode: 0755
+
+- name: "seed Radicle repositories"
+ when: radicle_node_repositories is defined
+ with_items: "{{ radicle_node_repositories }}"
+ shell: |
+ sudo -u _rad rad seed "{{ item.rid }}"
+ sudo -u _rad -i ./rad-config-pin "{{ item.rid }}"
+
+- name: "install Caddy configuation file"
+ template:
+ src: Caddyfile.j2
+ dest: /etc/caddy/Caddyfile
+
+- name: "create directory for CI logs"
+ file:
+ state: directory
+ path: /srv/http
+ owner: _rad
+ group: _rad
+
+- name: "restart Caddy"
+ systemd:
+ name: caddy
+ state: restarted
+ masked: no
+ enabled: yes
+ daemon_reload: yes
+
+- name: "install systemd unit for Radicle HTTPD"
+ template:
+ src: radicle-httpd.service.j2
+ dest: /lib/systemd/system/radicle-httpd.service
+
+- name: "enable systemd unit for Radicle HTTPD"
+ systemd:
+ name: radicle-httpd
+ state: restarted
+ masked: no
+ enabled: yes
+ daemon_reload: yes
+
+- name: "install Radicle CI broker config"
+ copy:
+ content: |
+ {{ radicle_node_ci_broker_config }}
+ dest: /home/_rad/ci-broker.yaml
+ owner: _rad
+ group: _rad
+ mode: 0644
+
+- name: "create state directory for Radicle native CI"
+ file:
+ state: directory
+ path: /home/_rad/native-ci.state
+ owner: _rad
+ group: _rad
+ mode: 0755
+
+- name: "install Radicle native CI config"
+ copy:
+ content: |
+ state: /srv/http
+ log: /home/_rad/native-ci.log
+ dest: /home/_rad/native-ci.yaml
+ owner: _rad
+ group: _rad
+ mode: 0644
+
+- name: "install systemd unit for Radicle CI broker"
+ template:
+ src: radicle-ci-broker.service.j2
+ dest: /lib/systemd/system/radicle-ci-broker.service
+
+- name: "enable systemd unit for Radicle CI broker"
+ systemd:
+ name: radicle-ci-broker
+ state: restarted
+ masked: no
+ enabled: yes
+ daemon_reload: yes
diff --git a/roles/radicle_node/templates/Caddyfile.j2 b/roles/radicle_node/templates/Caddyfile.j2
new file mode 100644
index 0000000..0271f48
--- /dev/null
+++ b/roles/radicle_node/templates/Caddyfile.j2
@@ -0,0 +1,18 @@
+:80 {
+ root * /usr/share/caddy
+}
+{{ radicle_node_domain_name }}:443 {
+ reverse_proxy 127.0.0.1:8080
+}
+{{ radicle_node_ci_domain_name }}:443 {
+ root * /srv/http/
+ file_server browse
+}
+{{ radicle_node_pages_domain_name }}:443 {
+ root * /srv/pages/
+ file_server browse
+}
+{{ radicle_node_wumpus_domain_name }}:443 {
+ root * /srv/wumpus/
+ file_server browse
+}
diff --git a/roles/radicle_node/templates/radicle-ci-broker.service.j2 b/roles/radicle_node/templates/radicle-ci-broker.service.j2
new file mode 100644
index 0000000..239ccc5
--- /dev/null
+++ b/roles/radicle_node/templates/radicle-ci-broker.service.j2
@@ -0,0 +1,18 @@
+[Unit]
+After=radicle-node.service
+Description=Radicle CI broker
+
+[Service]
+Type=simple
+Environment=RAD_HOME=/home/_rad/.radicle
+Environment=PATH=/home/_rad/.cargo/bin:/bin:/usr/bin:/sbin:/usr/sbin
+Environment=RUST_LOG=info
+ExecStart=/bin/ci-broker /home/_rad/ci-broker.yaml
+KillMode=control-group
+Restart=always
+RestartSec=1
+User=_rad
+Group=_rad
+
+[Install]
+WantedBy=default.target
diff --git a/roles/radicle_node/templates/radicle-httpd.service.j2 b/roles/radicle_node/templates/radicle-httpd.service.j2
new file mode 100644
index 0000000..32b2ecf
--- /dev/null
+++ b/roles/radicle_node/templates/radicle-httpd.service.j2
@@ -0,0 +1,16 @@
+[Unit]
+Description=Radicle HTTP Daemon
+After=network.target network-online.target
+Requires=network-online.target
+
+[Service]
+User=_rad
+Group=_rad
+ExecStart=/usr/bin/radicle-httpd --listen 127.0.0.1:8080
+Environment=RAD_HOME=/home/_rad/.radicle RUST_BACKTRACE=1 RUST_LOG=info
+KillMode=process
+Restart=always
+RestartSec=1
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/radicle_node/templates/radicle-node.service.j2 b/roles/radicle_node/templates/radicle-node.service.j2
new file mode 100644
index 0000000..ae2af8c
--- /dev/null
+++ b/roles/radicle_node/templates/radicle-node.service.j2
@@ -0,0 +1,16 @@
+[Unit]
+Description=Radicle Node
+After=network.target network-online.target
+Requires=network-online.target
+
+[Service]
+User=_rad
+Group=_rad
+ExecStart=/usr/bin/radicle-node --listen 0.0.0.0:8776 --force
+Environment=RAD_HOME=/home/_rad/.radicle RUST_BACKTRACE=1 RUST_LOG=info
+KillMode=process
+Restart=always
+RestartSec=3
+
+[Install]
+WantedBy=multi-user.target