diff options
-rwxr-xr-x | check | 2 | ||||
-rw-r--r-- | roles/gitano_server/tasks/main.yml | 9 | ||||
-rw-r--r-- | roles/radicle_node/README.md | 2 | ||||
-rw-r--r-- | roles/radicle_node/files/rad-config-pin | 23 | ||||
-rw-r--r-- | roles/radicle_node/files/rad-config-update | 34 | ||||
-rw-r--r-- | roles/radicle_node/tasks/main.yml | 242 | ||||
-rw-r--r-- | roles/radicle_node/templates/Caddyfile.j2 | 14 | ||||
-rw-r--r-- | roles/radicle_node/templates/radicle-ci-broker.service.j2 | 18 | ||||
-rw-r--r-- | roles/radicle_node/templates/radicle-httpd.service.j2 | 16 | ||||
-rw-r--r-- | roles/radicle_node/templates/radicle-node.service.j2 | 16 | ||||
-rw-r--r-- | roles/sane_debian_system/subplot.md | 6 | ||||
-rw-r--r-- | roles/sane_debian_system/tasks/apt.yml | 5 | ||||
-rw-r--r-- | roles/sane_debian_system/tasks/env.yml | 8 | ||||
-rw-r--r-- | roles/sane_debian_system/tasks/main.yml | 7 | ||||
-rw-r--r-- | roles/sshd/tasks/main.yml | 4 | ||||
-rw-r--r-- | subplot.subplot | 3 |
16 files changed, 395 insertions, 14 deletions
@@ -45,7 +45,7 @@ chmod 0600 ssh/id # Create configuration for the test VMs used by the test suite. cat >test.cfg <<EOF name: debian-ansible-test -base_image: "$HOME/tmp/debian-10-openstack-amd64.qcow2" +base_image: "$HOME/tmp/debian.qcow2" username: debian cpus: 2 memory: 1024 diff --git a/roles/gitano_server/tasks/main.yml b/roles/gitano_server/tasks/main.yml index 08486fa..b25d142 100644 --- a/roles/gitano_server/tasks/main.yml +++ b/roles/gitano_server/tasks/main.yml @@ -1,3 +1,6 @@ -- include: gitano.yml -- include: git-daemon.yml -- include: cgit.yml +- ansible.builtin.import_tasks: + file: gitano.yml +- ansible.builtin.import_tasks: + file: git-daemon.yml +- ansible.builtin.import_tasks: + file: cgit.yml 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..8e04a83 --- /dev/null +++ b/roles/radicle_node/tasks/main.yml @@ -0,0 +1,242 @@ +- 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 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..1954b4d --- /dev/null +++ b/roles/radicle_node/templates/Caddyfile.j2 @@ -0,0 +1,14 @@ +: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_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 diff --git a/roles/sane_debian_system/subplot.md b/roles/sane_debian_system/subplot.md index 56cc66f..be05984 100644 --- a/roles/sane_debian_system/subplot.md +++ b/roles/sane_debian_system/subplot.md @@ -20,7 +20,7 @@ and I run the playbook then the host has the sudo package installed and the host has the apt-transport-https package installed and the host has the locales package installed -and the host has the ntp package installed +and the host has the systemd-timesyncd package installed and the host has an empty /etc/apt/sources.list.d directory and the host has hostname saneone ~~~ @@ -29,7 +29,7 @@ and the host has hostname saneone ansible_python_interpreter: /usr/bin/python3 sane_debian_system_version: 2 -sane_debian_system_codename: buster +sane_debian_system_codename: bullseye sane_debian_system_hostname: saneone ~~~ @@ -47,7 +47,7 @@ and the host has hostname debian-ansible-test ~~~{#sane-without-hostname.yml .file .yaml} sane_debian_system_version: 2 -sane_debian_system_codename: buster +sane_debian_system_codename: bullseye ~~~ ## Checks that debian codename is set diff --git a/roles/sane_debian_system/tasks/apt.yml b/roles/sane_debian_system/tasks/apt.yml index 9bf6086..0da3332 100644 --- a/roles/sane_debian_system/tasks/apt.yml +++ b/roles/sane_debian_system/tasks/apt.yml @@ -16,8 +16,6 @@ - name: update package lists shell: | apt-get update --allow-releaseinfo-change - args: - warn: false - name: update package lists ignore_errors: yes @@ -74,8 +72,7 @@ - name: update package lists shell: | apt-get update --allow-releaseinfo-change - args: - warn: false + - name: add archive keyrings with_items: "{{ sane_debian_system_sources_lists }}" diff --git a/roles/sane_debian_system/tasks/env.yml b/roles/sane_debian_system/tasks/env.yml index 0539fee..eedd864 100644 --- a/roles/sane_debian_system/tasks/env.yml +++ b/roles/sane_debian_system/tasks/env.yml @@ -24,6 +24,14 @@ name: - locales +- name: install systemd-timesyncd or ntp + shell: | + if apt-cache show systemd-timesyncd > /dev/null; then + DEBIAN_FRONTEND=noninteractife apt-get install -y systemd-timesyncd + else + DEBIAN_FRONTEND=noninteractife apt-get install -y ntp + fi + - name: generate locales locale_gen: name: "{{ item }}" diff --git a/roles/sane_debian_system/tasks/main.yml b/roles/sane_debian_system/tasks/main.yml index 30a3f0c..bc8c6d3 100644 --- a/roles/sane_debian_system/tasks/main.yml +++ b/roles/sane_debian_system/tasks/main.yml @@ -3,5 +3,8 @@ [ "{{ sane_debian_system_version }}" = "2" ] || \ (echo "Unexpected version {{ sane_debian_system_version }}" 1>&2; exit 1) -- include: apt.yml -- include: env.yml +- ansible.builtin.import_tasks: + file: apt.yml + +- ansible.builtin.import_tasks: + file: env.yml diff --git a/roles/sshd/tasks/main.yml b/roles/sshd/tasks/main.yml index 66f9103..ff77c40 100644 --- a/roles/sshd/tasks/main.yml +++ b/roles/sshd/tasks/main.yml @@ -15,6 +15,7 @@ regexp: "Include /etc/ssh/sshd_config.d" line: "Include /etc/ssh/sshd_config.d/*.conf" insertbefore: BOF + notify: sshd_restart - name: "Set SSH host identity" when: sshd_host_key is defined and sshd_host_cert is defined @@ -106,3 +107,6 @@ AuthorizedKeysFile none dest: /etc/ssh/sshd_config.d/authorized_keys.conf notify: sshd_restart + +- name: "Run handlers" + meta: flush_handlers diff --git a/subplot.subplot b/subplot.subplot index 7cc234d..5d8083f 100644 --- a/subplot.subplot +++ b/subplot.subplot @@ -1,5 +1,6 @@ title: "debian-ansible—Ansible roles for Debian systems" -author: Lars Wirzenius +authors: + - Lars Wirzenius markdowns: - subplot.md bindings: |