summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcheck47
-rw-r--r--roles/apache_server/tasks/main.yml6
-rw-r--r--roles/gitano_server/tasks/main.yml9
-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.yml242
-rw-r--r--roles/radicle_node/templates/Caddyfile.j214
-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
-rw-r--r--roles/sane_debian_system/subplot.md7
-rw-r--r--roles/sane_debian_system/tasks/apt.yml5
-rw-r--r--roles/sane_debian_system/tasks/env.yml15
-rw-r--r--roles/sane_debian_system/tasks/main.yml7
-rw-r--r--roles/sshd/defaults/main.yml9
-rw-r--r--roles/sshd/tasks/main.yml41
-rw-r--r--subplot.md12
-rw-r--r--subplot.subplot11
19 files changed, 477 insertions, 57 deletions
diff --git a/check b/check
index 11b7d77..225aa7e 100755
--- a/check
+++ b/check
@@ -4,24 +4,21 @@
set -eu -o pipefail
-cat_with_sep()
-{
- for x in "$@"
- do
- cat "$x"
- echo
- done
+cat_with_sep() {
+ for x in "$@"; do
+ cat "$x"
+ echo
+ done
}
hideok=chronic
-if [ "$#" -gt 0 ]
-then
- case "$1" in
+if [ "$#" -gt 0 ]; then
+ case "$1" in
verbose | -v | --verbose)
- hideok=
- shift 1
- ;;
- esac
+ hideok=
+ shift 1
+ ;;
+ esac
fi
dir="$(mktemp -d -p .)"
@@ -29,26 +26,26 @@ dir="$(mktemp -d -p .)"
trap 'rm -rf "$dir"' EXIT
rm -f test.log test.py
-cp subplot.md "$dir"
-cat_with_sep subplot.md roles/*/subplot.md > "$dir/subplot.md"
-cat_with_sep subplot/*.py roles/*/subplot.py > "$dir/subplot.py"
-cat_with_sep subplot/*.yaml roles/*/subplot.yaml > "$dir/subplot.yaml"
+cp subplot.subplot subplot.md "$dir"
+cat_with_sep subplot.md roles/*/subplot.md >"$dir/subplot.md"
+cat_with_sep subplot/*.py roles/*/subplot.py >"$dir/subplot.py"
+cat_with_sep subplot/*.yaml roles/*/subplot.yaml >"$dir/subplot.yaml"
(
- set -eu -o pipefail
- cd "$dir"
- subplot docgen subplot.md -o ../subplot.pdf
- subplot docgen subplot.md -o ../subplot.html
- subplot codegen subplot.md -o ../test.py
+ set -eu -o pipefail
+ cd "$dir"
+ subplot docgen subplot.subplot -o ../subplot.pdf
+ subplot docgen subplot.subplot -o ../subplot.html
+ subplot codegen subplot.subplot -o ../test.py
)
# Fix private key permissions. git doesn't preserve them.
chmod 0600 ssh/id
# Create configuration for the test VMs used by the test suite.
-cat > test.cfg <<EOF
+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/apache_server/tasks/main.yml b/roles/apache_server/tasks/main.yml
index c4f348a..5509818 100644
--- a/roles/apache_server/tasks/main.yml
+++ b/roles/apache_server/tasks/main.yml
@@ -102,6 +102,12 @@
notify:
- restart apache
+- name: set default charset to utf8
+ copy:
+ content: |
+ AddDefaultCharset UTF-8
+ dest: /etc/apache2/conf-available/charset.conf
+
- name: "install htpasswd files"
copy:
content: "{{ item.htpasswd }}"
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 81bab9e..be05984 100644
--- a/roles/sane_debian_system/subplot.md
+++ b/roles/sane_debian_system/subplot.md
@@ -20,17 +20,16 @@ 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
-and the host has saneone in /etc/hosts for 127.0.1.1
~~~
~~~{#sane1.yml .file .yaml}
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
~~~
@@ -48,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 20f93ef..eedd864 100644
--- a/roles/sane_debian_system/tasks/env.yml
+++ b/roles/sane_debian_system/tasks/env.yml
@@ -14,13 +14,6 @@
name: "{{ sane_debian_system_hostname }}"
when: sane_debian_system_hostname != ""
-- name: add hostname to /etc/hosts
- lineinfile:
- dest: /etc/hosts
- regexp: '^127\.0\.1\.1 '
- line: "127.0.1.1 {{ sane_debian_system_hostname }}"
- when: sane_debian_system_hostname is defined
-
- name: set timezone
timezone:
name: "{{ sane_debian_system_timezone }}"
@@ -31,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/defaults/main.yml b/roles/sshd/defaults/main.yml
new file mode 100644
index 0000000..20c9563
--- /dev/null
+++ b/roles/sshd/defaults/main.yml
@@ -0,0 +1,9 @@
+# The user of the role MUST define the version they want to use. If
+# it's not what the version of unix_users being used actually
+# provides, the role will fail.
+sshd_version: null
+
+
+# Allow SSH server to use `authorized_keys` files?
+sshd_allow_authorized_keys: yes
+
diff --git a/roles/sshd/tasks/main.yml b/roles/sshd/tasks/main.yml
index e601969..ff77c40 100644
--- a/roles/sshd/tasks/main.yml
+++ b/roles/sshd/tasks/main.yml
@@ -3,6 +3,20 @@
[ "{{ sshd_version }}" = "1" ] || \
(echo "Unexpected version {{ sshd_version }}" 1>&2; exit 1)
+- name: "sshd role configuration sanity check"
+ when: not sshd_allow_authorized_keys and sshd_user_ca_pub is not defined
+ shell: |
+ echo "You MUST define sshd_allow_authorized_keys OR sshd_user_ca_pub"
+ exit 1
+
+- name: "Configure SSH server to read config files in sshd_config.d"
+ lineinfile:
+ path: /etc/ssh/sshd_config
+ 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
copy:
@@ -32,6 +46,30 @@
dest: /etc/ssh/sshd_config.d/host_id.conf
notify: sshd_restart
+- name: "Remove old host key settings from /etc/ssh/sshd_config"
+ when: sshd_host_key is defined and sshd_host_cert is defined
+ lineinfile:
+ path: /etc/ssh/sshd_config
+ state: absent
+ regex: "(?i)hostkey"
+ notify: sshd_restart
+
+- name: "Remove old host cert settings from /etc/ssh/sshd_config"
+ when: sshd_host_key is defined and sshd_host_cert is defined
+ lineinfile:
+ path: /etc/ssh/sshd_config
+ state: absent
+ regex: "(?i)hostcertificate"
+ notify: sshd_restart
+
+- name: "Remove old user CA settings from /etc/ssh/sshd_config"
+ when: sshd_host_key is defined and sshd_host_cert is defined
+ lineinfile:
+ path: /etc/ssh/sshd_config
+ state: absent
+ regex: "(?i)trustedusercakeys"
+ notify: sshd_restart
+
- name: "Remove obsolete SSH host keys and certificates"
when: sshd_host_key is defined and sshd_host_cert is defined
shell: |
@@ -69,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.md b/subplot.md
index 952ba95..a56e15b 100644
--- a/subplot.md
+++ b/subplot.md
@@ -1,15 +1,3 @@
----
-title: "debian-ansible&mdash;Ansible roles for Debian systems"
-author: Lars Wirzenius
-bindings:
-- subplot.yaml
-impls:
- python:
- - subplot.py
- - lib/runcmd.py
-...
-
-
# Introduction
`debian-ansible` is a collection of Ansible roles for managing Debian
diff --git a/subplot.subplot b/subplot.subplot
new file mode 100644
index 0000000..5d8083f
--- /dev/null
+++ b/subplot.subplot
@@ -0,0 +1,11 @@
+title: "debian-ansible&mdash;Ansible roles for Debian systems"
+authors:
+ - Lars Wirzenius
+markdowns:
+ - subplot.md
+bindings:
+- subplot.yaml
+impls:
+ python:
+ - subplot.py
+ - lib/runcmd.py