diff --git a/roles/serterm/defaults/main.yml b/roles/serterm/defaults/main.yml new file mode 100644 index 0000000..8480f31 --- /dev/null +++ b/roles/serterm/defaults/main.yml @@ -0,0 +1,2 @@ +serterm_static_windows: [] +serterm_authorized_keys: [] diff --git a/roles/serterm/files/add-window.sh b/roles/serterm/files/add-window.sh new file mode 100644 index 0000000..f43f14a --- /dev/null +++ b/roles/serterm/files/add-window.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# vim: set sw=4 ts=4 sts=4 et : + +port="$1" + +exec tmux new-window -a -t 'serial:{end}' -n "${port##*/}" /usr/local/libexec/serterm/connect-serial /dev/"${port}" diff --git a/roles/serterm/files/connect-serial.sh b/roles/serterm/files/connect-serial.sh new file mode 100644 index 0000000..1200ec0 --- /dev/null +++ b/roles/serterm/files/connect-serial.sh @@ -0,0 +1,8 @@ +#!/bin/sh +# vim: set sw=4 ts=4 sts=4 et : + +: "${LOG_DIR:=/var/log/serial}" + +port="$1" + +exec picocom -b 115200 -g "${LOG_DIR%/}"/"${port##*/}".log "${port}" diff --git a/roles/serterm/files/remove-window.sh b/roles/serterm/files/remove-window.sh new file mode 100644 index 0000000..f053cc3 --- /dev/null +++ b/roles/serterm/files/remove-window.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# vim: set sw=4 ts=4 sts=4 et : + +port="$1" + +exec tmux kill-window -t "${port##*/}" diff --git a/roles/serterm/files/serial-terminal-server-window@.service b/roles/serterm/files/serial-terminal-server-window@.service new file mode 100644 index 0000000..c4a8ed5 --- /dev/null +++ b/roles/serterm/files/serial-terminal-server-window@.service @@ -0,0 +1,16 @@ +# vim: set ft=systemd : +[Unit] +Description=Add serial terminal window for %I +Requires=serial-terminal-server.service +After=serial-terminal-server.service + +[Service] +Type=oneshot +ExecStart=/usr/local/libexec/serterm/add-window %I +ExecStop=/usr/local/libexec/serterm/remove-window %I +RemainAfterExit=yes +User=serterm +Group=serterm + +[Install] +WantedBy=serial-terminal-server.service diff --git a/roles/serterm/files/serial-terminal-server.service b/roles/serterm/files/serial-terminal-server.service new file mode 100644 index 0000000..91530a1 --- /dev/null +++ b/roles/serterm/files/serial-terminal-server.service @@ -0,0 +1,14 @@ +# vim: set ft=systemd : +[Unit] +Description=Serial Terminal + +[Service] +Type=forking +ExecStart=/usr/local/libexec/serterm/start-server +User=serterm +Group=serterm +Restart=always +RestartSec=1s + +[Install] +WantedBy=multi-user.target diff --git a/roles/serterm/files/start-server.sh b/roles/serterm/files/start-server.sh new file mode 100644 index 0000000..19eba0d --- /dev/null +++ b/roles/serterm/files/start-server.sh @@ -0,0 +1,16 @@ +#!/bin/sh +# vim: set sw=4 ts=4 sts=4 et : + +if [ -z "${TMUX}" ]; then + exec tmux new-session -s serial -d "$0" +fi + +tmux \ + set-option -t serial:0 -w remain-on-exit on \; \ + rename-window -t serial:0 info + +cat <<'EOF' +This window must remain open to keep the tmux server/session running. +If all windows are closed, tmux will exit and will not be able to +receive commands to add new windows for hotplugged devices. +EOF diff --git a/roles/serterm/files/start-session.sh b/roles/serterm/files/start-session.sh new file mode 100644 index 0000000..a1d9612 --- /dev/null +++ b/roles/serterm/files/start-session.sh @@ -0,0 +1,18 @@ +#!/bin/sh +# vim: set sw=4 ts=4 sts=4 et : + +if [ -z "${TMUX}" ]; then + exec tmux new-session -s serial -d "$0" +fi + +tmux \ + set-option -t serial:0 -w remain-on-exit on \; \ + rename-window -t serial:0 info + +cat <<'EOF' +This window must remain open to keep the tmux server/session running. +If all windows are closed, tmux will exit and will not be able to +receive commands to add new windows for hotplugged devices. + +Use `respawn-window` to restart all serial terminal windows. +EOF diff --git a/roles/serterm/files/start-terminal-server.sh b/roles/serterm/files/start-terminal-server.sh new file mode 100644 index 0000000..a1d9612 --- /dev/null +++ b/roles/serterm/files/start-terminal-server.sh @@ -0,0 +1,18 @@ +#!/bin/sh +# vim: set sw=4 ts=4 sts=4 et : + +if [ -z "${TMUX}" ]; then + exec tmux new-session -s serial -d "$0" +fi + +tmux \ + set-option -t serial:0 -w remain-on-exit on \; \ + rename-window -t serial:0 info + +cat <<'EOF' +This window must remain open to keep the tmux server/session running. +If all windows are closed, tmux will exit and will not be able to +receive commands to add new windows for hotplugged devices. + +Use `respawn-window` to restart all serial terminal windows. +EOF diff --git a/roles/serterm/handlers/main.yml b/roles/serterm/handlers/main.yml new file mode 100644 index 0000000..36accaf --- /dev/null +++ b/roles/serterm/handlers/main.yml @@ -0,0 +1,9 @@ +- name: restart serial-terminal-server + service: + name: serial-terminal-server + state: restarted + +- name: reload sshd + service: + name: sshd + state: reloaded diff --git a/roles/serterm/meta/main.yml b/roles/serterm/meta/main.yml new file mode 100644 index 0000000..e2827fe --- /dev/null +++ b/roles/serterm/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: +- systemd-base diff --git a/roles/serterm/tasks/main.yml b/roles/serterm/tasks/main.yml new file mode 100644 index 0000000..8dc1fcb --- /dev/null +++ b/roles/serterm/tasks/main.yml @@ -0,0 +1,153 @@ +- name: ensure serial terminal packages are instaled + package: + name: + - picocom + - tmux + state: present + tags: + - install + +- name: ensure serterm group exists + group: + name: serterm + state: present + tags: + - group + - user +- name: ensure serterm user exists + user: + name: serterm + create_home: false + home: / + group: serterm + groups: + - dialout + state: present + tags: + - user + +- name: ensure serial log directory exists + file: + path: /var/log/serial + owner: root + group: serterm + mode: ug=rwx,o= + state: directory + tags: + - logs + +- name: ensure serterm configuration directory exists + file: + path: /etc/serterm + owner: root + group: root + mode: u=rwx,go=rx + state: directory + tags: + - config +- name: ensure serterm is configured + template: + src: tmux.conf.j2 + dest: /etc/serterm/tmux.conf + owner: root + group: root + mode: u=rw,go=r + tags: + - config + +- name: ensure serterm script directory exists + file: + path: /usr/local/libexec/serterm + owner: root + group: root + mode: u=rwx,go=rx + state: directory + tags: + - script +- name: ensure serterm scripts are installed + copy: + src: '{{ item }}.sh' + dest: /usr/local/libexec/serterm/{{ item }} + mode: u=rwx,go=rx + owner: root + group: root + loop: + - add-window + - connect-serial + - remove-window + - start-server + notify: + - restart serial-terminal-server + +- name: ensure serterm systemd units are installed + copy: + src: '{{ item }}' + dest: /etc/systemd/system/ + mode: u=rw,go=r + owner: root + group: root + notify: + - reload systemd + - restart serial-terminal-server + loop: + - serial-terminal-server.service + - serial-terminal-server-window@.service + tags: + - systemd + +- name: ensure serial-terminal-server is enabled + service: + name: serial-terminal-server + enabled: true + tags: + - service +- name: ensure static serial-terminal-server-window units are enabled + service: + name: serial-terminal-server-window@{{ item }} + enabled: true + loop: '{{ serterm_static_windows }}' + tags: + - service + +- name: flush handlers + meta: flush_handlers + tags: + - always + +- name: ensure serial-terminal-server is running + service: + name: serial-terminal-server + state: started + tags: + - service +- name: ensure static serial-terminal-server-window units are started + service: + name: serial-terminal-server-window@{{ item }} + state: started + loop: '{{ serterm_static_windows }}' + tags: + - service + +- name: ensure serterm user ssh keys are authorized + template: + src: authorized_keys.j2 + dest: /etc/serterm/authorized_keys + owner: root + group: root + mode: u=rw,go=r + tags: + - ssh + - authorized_keys + +- name: ensure sshd is configured for serterm + template: + src: sshd_config.j2 + dest: /etc/ssh/sshd_config.d/80-serterm.conf + owner: root + group: root + mode: u=rw,go=r + notify: + - reload sshd + tags: + - ssh + - sshd_config diff --git a/roles/serterm/templates/authorized_keys.j2 b/roles/serterm/templates/authorized_keys.j2 new file mode 100644 index 0000000..65d942d --- /dev/null +++ b/roles/serterm/templates/authorized_keys.j2 @@ -0,0 +1,3 @@ +{% for key in serterm_authorized_keys %} +{{ key }} +{% endfor %} diff --git a/roles/serterm/templates/sshd_config.j2 b/roles/serterm/templates/sshd_config.j2 new file mode 100644 index 0000000..faf19dc --- /dev/null +++ b/roles/serterm/templates/sshd_config.j2 @@ -0,0 +1,3 @@ +Match user serterm + ForceCommand tmux attach + AuthorizedKeysFile /etc/serterm/authorized_keys diff --git a/roles/serterm/templates/tmux.conf.j2 b/roles/serterm/templates/tmux.conf.j2 new file mode 100644 index 0000000..bfd4946 --- /dev/null +++ b/roles/serterm/templates/tmux.conf.j2 @@ -0,0 +1 @@ +set -g remain-on-exit on diff --git a/serterm.yml b/serterm.yml new file mode 100644 index 0000000..0e23fed --- /dev/null +++ b/serterm.yml @@ -0,0 +1,5 @@ +- hosts: serterm + roles: + - role: serterm + tags: + - serterm