diff --git a/TODO.txt b/TODO.txt
index 04bb802..b1f3875 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -2,5 +2,3 @@
(because of background processes running for labuser). Killing the processes
doesn't really work because things (e.g. XFCE) start failing if we do so.
- LDAP authentication for user login
-- Refactor: Move stuff out of the installer and into Ansible roles (or at least
-playbooks).
diff --git a/ansible/README.md b/ansible/README.md
new file mode 100644
index 0000000..34db4bc
--- /dev/null
+++ b/ansible/README.md
@@ -0,0 +1,29 @@
+# Ansible roles and playbooks for configuration management
+
+This includes various playbooks and roles managing the overall configuration of
+the PCs plus some day-to-day tasks.
+
+**NOTE**: All playbooks / roles expect to run with administrator privileges.
+
+## Quickstart
+
+Taking over from the [installer](../archlive), to apply the base desktop
+configuration:
+
+```sh
+ansible-playbook post-install.yml
+ansible-playbook reboot.yml
+```
+
+Look into the [`extra`](roles/extra) role for course-specific software
+configuration.
+
+## Playbooks
+
+- [`persist.yml`](persist.yml) makes the current configuration permanent (see
+ [reversion mechanism](../reversion_mechanism.md))
+- [`post-install.yml`](post-install.yml) applies the necessary post-installer
+ configuration (desktop, software etc.)
+- [`poweroff.yml`](poweroff.yml) powers off
+- [`reboot.yml`](reboot.yml) reboots
+- [`upgrade.yml`](upgrade.yml) upgrades installe software
diff --git a/ansible/persist.yml b/ansible/persist.yml
new file mode 100644
index 0000000..a26eb13
--- /dev/null
+++ b/ansible/persist.yml
@@ -0,0 +1,40 @@
+---
+- name: Clear pacman cache
+ ansible.builtin.shell: yes | pacman -Scc
+ tags:
+ - cleanup
+
+- name: Make changes permanent
+ block:
+ - name: Persist home
+ block:
+ - name: Ensure no ansible traces left in home
+ ansible.builtin.file:
+ path: /home/labuser/.ansible
+ state: absent
+ - name: Delete old home snapshot
+ ansible.builtin.command: rec-sub-del.sh home-snap /root/btrfs-root
+ - name: Create home snapshot from current
+ ansible.builtin.command: btrfs subvolume snapshot /root/btrfs-root/home /root/btrfs-root/home-snap
+ tags:
+ - home
+ - name: Persist root state
+ ansible.builtin.command: replace-snap.sh
+ tags:
+ - root
+ - name: Generate GRUB configuration
+ # NOTE: This needs to happen after the above
+ block:
+ - name: Ensure /etc/grub.d/30_uefi-firmware is missing
+ # NOTE: This file (part of grub) adds a boot menu option to reboot into
+ # the UEFI firmware settings, which we don't want. The file will be
+ # reinstalled every time GRUB is upgraded, so removing it only once is not
+ # enough. Also, no reason bothering to keep a backup.
+ ansible.builtin.file:
+ path: /etc/grub.d/30_uefi-firmware
+ state: absent
+ - name: Generate grub.cfg
+ ansible.builtin.command: grub-mkconfig -o /boot/grub/grub.cfg
+ tags:
+ - grub
+ tags: persist
diff --git a/ansible/post-install.yml b/ansible/post-install.yml
new file mode 100644
index 0000000..82511c6
--- /dev/null
+++ b/ansible/post-install.yml
@@ -0,0 +1,10 @@
+---
+- name: Configure system post-install
+ hosts: pclab
+ tasks:
+ - name: Apply base desktop configuration
+ import_role:
+ name: common
+ # TODO OPT: Apply extra too?
+ - name: Persist changes
+ import_tasks: persist.yml
diff --git a/ansible/poweroff.yml b/ansible/poweroff.yml
new file mode 100644
index 0000000..90122f6
--- /dev/null
+++ b/ansible/poweroff.yml
@@ -0,0 +1,13 @@
+---
+- name: Power off the system
+ hosts: pclab
+ gather_facts: no
+ vars:
+ delay_minutes: 1
+ tasks:
+ - name: Power off
+ # NOTE: The delay is added to avoid ansible hanging until it times out.
+ ansible.builtin.command: "shutdown +{{ delay_minutes }}"
+ - name: Remind user about the delay
+ ansible.builtin.debug:
+ msg: "System will power off in {{ delay_minutes }} minute(s)"
diff --git a/ansible/reboot.yml b/ansible/reboot.yml
new file mode 100644
index 0000000..8bd7d08
--- /dev/null
+++ b/ansible/reboot.yml
@@ -0,0 +1,13 @@
+---
+- name: Reboot the system
+ hosts: pclab
+ gather_facts: no
+ vars:
+ delay_minutes: 1
+ tasks:
+ - name: Reboot (without waiting for the remotes to come back up)
+ # NOTE: The delay is added to avoid ansible hanging until it times out.
+ ansible.builtin.command: "shutdown -r +{{ delay_minutes }}"
+ - name: Remind user about the delay
+ ansible.builtin.debug:
+ msg: "System will reboot in {{ delay_minutes }} minute(s)"
diff --git a/ansible/roles/common/README.md b/ansible/roles/common/README.md
new file mode 100644
index 0000000..19b9f21
--- /dev/null
+++ b/ansible/roles/common/README.md
@@ -0,0 +1,10 @@
+# Common role
+
+This includes the desktop, complete with all standard apps (not
+course-specific).
+
+- Configures lab user (`labuser`) and its home / environment.
+- COnfigures home reversion mechanism.
+- Configures GRUB (menu default and timeout).
+- Installs and configures X, Xfce, LightDM and necessary desktop applications
+ (utilities, browser, multimedia, office suite).
diff --git a/ansible/roles/common/files/Thunar/uca.xml b/ansible/roles/common/files/Thunar/uca.xml
new file mode 100644
index 0000000..a02b0bc
--- /dev/null
+++ b/ansible/roles/common/files/Thunar/uca.xml
@@ -0,0 +1,20 @@
+
+
+
+ utilities-terminal
+ Open Terminal Here
+ exo-open --working-directory %f --launch TerminalEmulator
+ Example for a custom action
+ *
+
+
+
+
+ org.xfce.catfish
+ Search
+ catfish --path=%f
+
+ *
+
+
+
diff --git a/ansible/roles/common/files/lightdm.conf.d/50-local.conf b/ansible/roles/common/files/lightdm.conf.d/50-local.conf
new file mode 100644
index 0000000..c542075
--- /dev/null
+++ b/ansible/roles/common/files/lightdm.conf.d/50-local.conf
@@ -0,0 +1,4 @@
+[Seat:*]
+allow-user-switching=false
+allow-guest=false
+session-setup-script=/usr/local/sbin/revert-home.sh
diff --git a/ansible/roles/common/files/pkg/hyphen-el-1.1b-2-any.pkg.tar.zst b/ansible/roles/common/files/pkg/hyphen-el-1.1b-2-any.pkg.tar.zst
new file mode 100644
index 0000000..e849756
Binary files /dev/null and b/ansible/roles/common/files/pkg/hyphen-el-1.1b-2-any.pkg.tar.zst differ
diff --git a/ansible/roles/common/files/pkg/libreoffice-extension-orthos-greek-dictionary-0.4.0-1-any.pkg.tar.zst b/ansible/roles/common/files/pkg/libreoffice-extension-orthos-greek-dictionary-0.4.0-1-any.pkg.tar.zst
new file mode 100644
index 0000000..5b825ab
Binary files /dev/null and b/ansible/roles/common/files/pkg/libreoffice-extension-orthos-greek-dictionary-0.4.0-1-any.pkg.tar.zst differ
diff --git a/ansible/roles/common/files/pkg/libreoffice-extension-orthos-greek-thesaurus-0.4.0-1-any.pkg.tar.zst b/ansible/roles/common/files/pkg/libreoffice-extension-orthos-greek-thesaurus-0.4.0-1-any.pkg.tar.zst
new file mode 100644
index 0000000..b060d37
Binary files /dev/null and b/ansible/roles/common/files/pkg/libreoffice-extension-orthos-greek-thesaurus-0.4.0-1-any.pkg.tar.zst differ
diff --git a/ansible/roles/common/files/rules.d/10-admin-override.rules b/ansible/roles/common/files/rules.d/10-admin-override.rules
new file mode 100644
index 0000000..85ae748
--- /dev/null
+++ b/ansible/roles/common/files/rules.d/10-admin-override.rules
@@ -0,0 +1,35 @@
+// Prevent suspend and hibernate for labuser
+polkit.addRule(function(action, subject) {
+ if ((action.id == "org.freedesktop.login1.suspend" ||
+ action.id == "org.freedesktop.login1.suspend-multiple-sessions" ||
+ action.id == "org.freedesktop.login1.hibernate" ||
+ action.id == "org.freedesktop.login1.hibernate-multiple-sessions") &&
+ subject.user == "labuser") {
+
+ return polkit.Result.NO;
+ }
+});
+
+
+// Prevent shut down for labuser
+polkit.addRule(function(action, subject) {
+ if ((action.id == "org.freedesktop.login1.halt" ||
+ action.id == "org.freedesktop.login1.halt-multiple-sessions" ||
+ action.id == "org.freedesktop.login1.power-off" ||
+ action.id == "org.freedesktop.login1.power-off-multiple-sessions") &&
+ subject.user == "labuser") {
+
+ return polkit.Result.NO;
+ }
+});
+
+
+// Prevent running xfsm-shutdown-helper and xfce4-pm-helper for labuser
+polkit.addRule(function(action, subject) {
+ if ((action.id == "org.xfce.session.xfsm-shutdown-helper" ||
+ action.id == "org.xfce.power.xfce4-pm-helper") &&
+ subject.user == "labuser") {
+
+ return polkit.Result.NO;
+ }
+});
diff --git a/ansible/roles/common/files/xfce4/helpers.rc b/ansible/roles/common/files/xfce4/helpers.rc
new file mode 100644
index 0000000..362ffd5
--- /dev/null
+++ b/ansible/roles/common/files/xfce4/helpers.rc
@@ -0,0 +1 @@
+WebBrowser=firefox
diff --git a/ansible/roles/common/files/xfce4/panel/launcher-3/16215916401.desktop b/ansible/roles/common/files/xfce4/panel/launcher-3/16215916401.desktop
new file mode 100644
index 0000000..5daa0c8
--- /dev/null
+++ b/ansible/roles/common/files/xfce4/panel/launcher-3/16215916401.desktop
@@ -0,0 +1,13 @@
+[Desktop Entry]
+Version=1.0
+Type=Application
+Exec=exo-open --launch TerminalEmulator
+Icon=org.xfce.terminalemulator
+StartupNotify=true
+Terminal=false
+Categories=Utility;X-XFCE;X-Xfce-Toplevel;
+OnlyShowIn=XFCE;
+X-AppStream-Ignore=True
+Name=Terminal Emulator
+Comment=Use the command line
+X-XFCE-Source=file:///usr/share/applications/xfce4-terminal-emulator.desktop
diff --git a/ansible/roles/common/files/xfce4/panel/launcher-4/16215916912.desktop b/ansible/roles/common/files/xfce4/panel/launcher-4/16215916912.desktop
new file mode 100644
index 0000000..b6dd1b5
--- /dev/null
+++ b/ansible/roles/common/files/xfce4/panel/launcher-4/16215916912.desktop
@@ -0,0 +1,14 @@
+[Desktop Entry]
+Version=1.0
+Type=Application
+Exec=exo-open --launch FileManager %u
+Icon=org.xfce.filemanager
+StartupNotify=true
+Terminal=false
+Categories=Utility;X-XFCE;X-Xfce-Toplevel;
+OnlyShowIn=XFCE;
+X-XFCE-MimeType=inode/directory;x-scheme-handler/trash;
+X-AppStream-Ignore=True
+Name=File Manager
+Comment=Browse the file system
+X-XFCE-Source=file:///usr/share/applications/xfce4-file-manager.desktop
diff --git a/ansible/roles/common/files/xfce4/panel/launcher-5/16217825961.desktop b/ansible/roles/common/files/xfce4/panel/launcher-5/16217825961.desktop
new file mode 100644
index 0000000..5769fab
--- /dev/null
+++ b/ansible/roles/common/files/xfce4/panel/launcher-5/16217825961.desktop
@@ -0,0 +1,27 @@
+[Desktop Entry]
+Version=1.0
+Name=Firefox
+GenericName=Web Browser
+Comment=Browse the World Wide Web
+Keywords=Internet;WWW;Browser;Web;Explorer
+Exec=/usr/lib/firefox/firefox %u
+Icon=firefox
+Terminal=false
+X-MultipleArgs=false
+Type=Application
+MimeType=text/html;text/xml;application/xhtml+xml;x-scheme-handler/http;x-scheme-handler/https;application/x-xpinstall;application/pdf;application/json;
+StartupNotify=true
+StartupWMClass=firefox
+Categories=Network;WebBrowser;
+Actions=new-window;new-private-window;
+X-XFCE-Source=file:///usr/share/applications/firefox.desktop
+
+[Desktop Action new-window]
+Name=New Window
+Name[en_US]=New Window
+Exec=/usr/lib/firefox/firefox --new-window %u
+
+[Desktop Action new-private-window]
+Name=New Private Window
+Name[en_US]=New Private Window
+Exec=/usr/lib/firefox/firefox --private-window %u
diff --git a/ansible/roles/common/files/xfce4/panel/whiskermenu-1.rc b/ansible/roles/common/files/xfce4/panel/whiskermenu-1.rc
new file mode 100644
index 0000000..c455f91
--- /dev/null
+++ b/ansible/roles/common/files/xfce4/panel/whiskermenu-1.rc
@@ -0,0 +1,4 @@
+button-title=Start
+show-button-title=true
+default-category=2
+show-command-lockscreen=false
diff --git a/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/keyboard-layout.xml b/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/keyboard-layout.xml
new file mode 100644
index 0000000..033a41b
--- /dev/null
+++ b/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/keyboard-layout.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/thunar-volman.xml b/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/thunar-volman.xml
new file mode 100644
index 0000000..ff85738
--- /dev/null
+++ b/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/thunar-volman.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/thunar.xml b/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/thunar.xml
new file mode 100644
index 0000000..7a1a940
--- /dev/null
+++ b/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/thunar.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop.xml b/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop.xml
new file mode 100644
index 0000000..d541371
--- /dev/null
+++ b/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml b/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml
new file mode 100644
index 0000000..f475a1b
--- /dev/null
+++ b/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml b/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml
new file mode 100644
index 0000000..0bfd96b
--- /dev/null
+++ b/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml b/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml
new file mode 100644
index 0000000..689bb1e
--- /dev/null
+++ b/ansible/roles/common/files/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/ansible/roles/common/tasks/main.yml b/ansible/roles/common/tasks/main.yml
new file mode 100644
index 0000000..a8dff41
--- /dev/null
+++ b/ansible/roles/common/tasks/main.yml
@@ -0,0 +1,284 @@
+---
+- name: Setup user
+ # TODO OPT: PAM, LDAP
+ block:
+ - name: Create labuser
+ ansible.builtin.user:
+ name: labuser
+ create_home: yes
+ password: "{{ 'labuser' | password_hash('sha512') }}"
+ state: present
+ - name: Create desktop directories
+ ansible.builtin.file:
+ group: labuser
+ owner: labuser
+ path: "/home/labuser/{{ item }}"
+ state: directory
+ loop:
+ - Desktop
+ - Documents
+ - Downloads
+ - name: Create local bin directories and add them to PATH
+ vars:
+ opt_bin_dir: /home/labuser/opt/bin
+ local_bin_dir: /home/labuser/.local/bin
+ block:
+ - name: Create local bin directories
+ ansible.builtin.file:
+ group: labuser
+ owner: labuser
+ path: "{{ item }}"
+ state: directory
+ loop:
+ - "{{ opt_bin_dir }}"
+ - "{{ local_bin_dir }}"
+ - name: Add local bin directories to labuser's PATH
+ ansible.builtin.lineinfile:
+ group: labuser
+ line: "export PATH={{ item }}:$PATH"
+ owner: labuser
+ path: /home/labuser/.bashrc
+ state: present
+ loop:
+ - "{{ opt_bin_dir }}"
+ - "{{ local_bin_dir }}"
+ tags:
+ - user
+
+- name: Configure GRUB
+ block:
+ - name: Enable os-prober
+ ansible.builtin.lineinfile:
+ line: GRUB_DISABLE_OS_PROBER=false
+ path: /etc/default/grub
+ regexp: ^GRUB_DISABLE_OS_PROBER=
+ state: present
+ - name: Default to Windows
+ ansible.builtin.lineinfile:
+ line: GRUB_DEFAULT=2
+ path: /etc/default/grub
+ regexp: ^GRUB_DEFAULT=
+ state: present
+ - name: Increase timeout
+ ansible.builtin.lineinfile:
+ line: GRUB_TIMEOUT=900
+ path: /etc/default/grub
+ regexp: ^GRUB_TIMEOUT=
+ state: present
+ # TODO OPT: Re-generate grub.cfg here.
+ tags:
+ - grub
+
+- name: Upgrade system
+ community.general.pacman:
+ update_cache: yes
+ upgrade: yes
+ tags:
+ - upgrade
+
+- name: Setup desktop
+ block:
+ - name: Install Xorg
+ # Xorg:
+ # common: mesa xorg-server libva-vdpau-driver libvdpau-va-gl
+ # m1: xf86-video-intel vulkan-intel libva-intel-driver
+ # m2: xf86-video-ati vulkan-radeon amdvlk libva-mesa-driver mesa-vdpau
+ # m3: xf86-video-intel vulkan-intel intel-media-driver
+ community.general.pacman:
+ name:
+ - mesa
+ - xorg-server
+ - libva-vdpau-driver
+ - libvdpau-va-gl
+ - xf86-video-intel
+ - vulkan-intel
+ - libva-intel-driver
+ - xf86-video-ati
+ - vulkan-radeon
+ - amdvlk
+ - libva-mesa-driver
+ - mesa-vdpau
+ - intel-media-driver
+ state: present
+ tags:
+ - xorg
+ - name: Setup Xfce
+ block:
+ - name: Install Xfce
+ community.general.pacman:
+ name:
+ - xfce4
+ - xfce4-notifyd
+ - xfce4-screenshooter
+ - xfce4-taskmanager
+ - htop
+ - xfce4-whiskermenu-plugin
+ - xfce4-xkb-plugin
+ - ttf-dejavu
+ - sshfs # NOTE: Would be --asdeps if thunar listed it as such
+ - catfish
+ - xfce4-pulseaudio-plugin
+ state: present
+ - name: Install optional Xfce dependencies
+ community.general.pacman:
+ extra_args: "--asdeps"
+ name:
+ - thunar-archive-plugin
+ - file-roller
+ - gvfs
+ - gvfs-smb
+ - gvfs-nfs
+ - gvfs-mtp
+ - mlocate
+ - pavucontrol
+ - pulseaudio
+ state: present
+ - name: Configure Xfce
+ # TODO OPT: Use community.general.xfconf instead?
+ ansible.builtin.copy:
+ dest: /home/labuser/.config/
+ group: labuser
+ owner: labuser
+ src: "{{ item }}"
+ loop:
+ - xfce4
+ - Thunar
+ - name: Configure Samba (https://wiki.archlinux.org/title/Samba#Client)
+ block:
+ - name: Ensure /etc/samba exists
+ ansible.builtin.file:
+ path: /etc/samba
+ state: directory
+ - name: Ensure /etc/samba/smb.conf exists
+ ansible.builtin.file:
+ path: /etc/samba/smb.conf
+ state: touch
+ tags:
+ - xfce
+ - name: Setup LightDM
+ block:
+ - name: Install LightDM
+ community.general.pacman:
+ name:
+ - lightdm
+ state: present
+ - name: Install optional LightDM dependencies
+ community.general.pacman:
+ extra_args: "--asdeps"
+ name:
+ - lightdm-gtk-greeter
+ - accountsservice
+ state: present
+ - name: Configure LightDM
+ # TODO OPT: Use community.general.ini_file instead?
+ ansible.builtin.copy: # NOTE: Merges the two directories
+ dest: /etc/lightdm/lightdm.conf.d/
+ src: lightdm.conf.d/
+ - name: Configure LightDM GTK greeter
+ community.general.ini_file:
+ no_extra_spaces: yes
+ option: indicators
+ path: /etc/lightdm/lightdm-gtk-greeter.conf
+ section: greeter
+ state: present
+ value: "~spacer;~clock;~host;~spacer;~language;~a11y"
+ - name: Enable LightDM
+ ansible.builtin.systemd:
+ enabled: yes
+ name: lightdm.service
+ tags:
+ - lightdm
+ - name: Configure polkit
+ ansible.builtin.copy:
+ dest: /etc/polkit-1/rules.d/
+ src: rules.d/
+ tags: polkit
+ tags:
+ - desktop
+
+# TODO OPT: Xfce kiosk mode if we need to prevent labuser changing xfce settings.
+
+- name: Setup extra software
+ block:
+ - name: Setup utilities
+ block:
+ - name: Install utility packages
+ community.general.pacman:
+ name:
+ - python-pip
+ - man-db
+ - man-pages
+ - texinfo
+ - moreutils
+ - tree
+ - inetutils
+ - gnome-calculator
+ - nano
+ - mousepad
+ - gvim
+ - emacs
+ - code
+ - meld
+ - geany
+ - git
+ - chromium
+ - firefox
+ state: present
+ - name: Install optional utility dependencies
+ community.general.pacman:
+ extra_args: "--asdeps"
+ name:
+ - bash-completion
+ state: present
+ tags:
+ - utilities
+ - name: Setup multimedia
+ block:
+ - name: Install multimedia packages
+ community.general.pacman:
+ name:
+ - ristretto
+ - vlc
+ state: present
+ - name: Install optional multimedia dependencies
+ community.general.pacman:
+ name:
+ - librsvg
+ - gst-plugins-base-libs
+ state: present
+ tags:
+ - multimedia
+ - name: Setup office
+ vars:
+ remote_pkg_dir: /root/pkg/
+ block:
+ - name: Copy pre-built AUR packages
+ ansible.builtin.copy:
+ dest: "{{ remote_pkg_dir }}"
+ src: pkg/
+ - name: Install office packages
+ community.general.pacman:
+ name:
+ - evince
+ - libreoffice-fresh
+ - hunspell-en_US
+ - "{{ remote_pkg_dir }}/libreoffice-extension-orthos-greek-dictionary-0.4.0-1-any.pkg.tar.zst"
+ - hyphen-en
+ - "{{ remote_pkg_dir }}/hyphen-el-1.1b-2-any.pkg.tar.zst"
+ - mythes-en
+ - "{{ remote_pkg_dir }}/libreoffice-extension-orthos-greek-thesaurus-0.4.0-1-any.pkg.tar.zst"
+ - name: Install optional office dependencies
+ community.general.pacman:
+ extra_args: "--asdeps"
+ name:
+ - jre-openjdk
+ - libmythes
+ state: present
+ - name: Remove pre-built AUR package files
+ ansible.builtin.file:
+ path: "{{ remote_pkg_dir }}"
+ state: absent
+ tags:
+ - office
+ tags:
+ - extra
diff --git a/ansible/roles/extra/README.md b/ansible/roles/extra/README.md
new file mode 100644
index 0000000..8355b7d
--- /dev/null
+++ b/ansible/roles/extra/README.md
@@ -0,0 +1,9 @@
+# Extra role
+
+This includes all the not-so-standard parts: mainly course-specific
+applications, extra and more volatile software.
+
+- SDKs: C/C++, Java, Node
+- VirtualBox
+- Octave
+- Data science: Jupyter, R, python packages (numpy, pandas etc.)
diff --git a/ansible/roles/extra/tasks/main.yml b/ansible/roles/extra/tasks/main.yml
new file mode 100644
index 0000000..a9b3805
--- /dev/null
+++ b/ansible/roles/extra/tasks/main.yml
@@ -0,0 +1,133 @@
+---
+- name: Setup SDKs
+ community.general.pacman:
+ name:
+ - gdb
+ - valgrind
+ - clang
+ - ltrace
+ - strace
+ - jdk-openjdk
+ - maven
+ - nodejs
+ - npm
+ state: present
+ tags:
+ - sdk
+
+- name: Setup VirtualBox
+ block:
+ - name: Gather facts if necessary
+ ansible.builtin.setup: {}
+ when: ansible_facts is falsy
+ - name: Install VirtualBox dependencies
+ # NOTE: virtualbox-host-modules-arch is not an optional dependency, so
+ # needs to be installed before virtualbox itself (so as to not pull
+ # virtualbox-host-dkms which is the default).
+ community.general.pacman:
+ extra_args: "--asdeps"
+ name:
+ - virtualbox-host-modules-arch
+ - virtualbox-guest-iso
+ state: present
+ - name: Install VirtualBox
+ community.general.pacman:
+ name:
+ - virtualbox
+ - name: Add labuser to vboxusers
+ ansible.builtin.user:
+ append: yes
+ groups:
+ - vboxusers
+ name: labuser
+ # NOTE: Since version 6.1 VirtualBox only supports hardware-assisted
+ # virtualization.
+ when: "'kvm' in ansible_facts['virtualization_tech_host']"
+ tags:
+ - virtualbox
+
+- name: Setup Octave
+ block:
+ - name: Install openblas as blas provider
+ # NOTE: Needs to be installed before octave, which would pull blas by
+ # default, which conflicts with openblas.
+ community.general.pacman:
+ extra_args: "--asdeps"
+ name:
+ - openblas
+ state: present
+ - name: Install Octave
+ community.general.pacman:
+ name:
+ - octave
+ state: present
+ tags:
+ - octave
+
+- name: Setup data science software
+ block:
+ - name: Install Jupyter
+ community.general.pacman:
+ name:
+ - jupyterlab
+ # - jupyter-notebook
+ state: present
+ tags:
+ - jupyter
+ - name: Setup R
+ block:
+ - name: Install R
+ community.general.pacman:
+ name:
+ - r
+ state: present
+ - name: Install optional R dependencies
+ community.general.pacman:
+ extra_args: "--asdeps"
+ name:
+ - gcc-fortran
+ - openblas
+ state: present
+ tags:
+ - r
+ - name: Install pip packages
+ vars:
+ tmpdir: /home/labuser/tmp
+ block:
+ - name: Create temp directory for pip to use
+ ansible.builtin.file:
+ group: labuser
+ owner: labuser
+ path: "{{ tmpdir }}"
+ state: directory
+ - name: Install / update packages with pip
+ become: yes
+ become_user: labuser
+ ansible.builtin.pip:
+ extra_args: "--user"
+ name:
+ - numpy
+ - scipy
+ - matplotlib
+ - pandas
+ - scikit-learn
+ - torch
+ - seaborn
+ - tqdm
+ - networkx
+ state: latest
+ environment:
+ TMPDIR: "{{ tmpdir }}"
+ - name: Delete temp directory for pip
+ ansible.builtin.file:
+ path: "{{ tmpdir }}"
+ state: absent
+ tags:
+ - python
+ - pip
+ tags:
+ - data-science
+
+# TODO OPT: tomcat mariadb java-connector phpmyadmin
+
+# TODO OPT: wireshark tcpdump traceroute
diff --git a/ansible/upgrade.yml b/ansible/upgrade.yml
new file mode 100644
index 0000000..6dddf54
--- /dev/null
+++ b/ansible/upgrade.yml
@@ -0,0 +1,28 @@
+---
+- name: Upgrade system
+ hosts: pclab
+ tasks:
+ - name: Upgrade system
+ # NOTE: The upgrade is performed in parts, to avoid problems when upgrading
+ # after a long time.
+ block:
+ - name: Upgrade archlinux-keyring
+ community.general.pacman:
+ name: archlinux-keyring
+ state: latest
+ update_cache: yes
+ - name: Upgrade pacman
+ community.general.pacman:
+ name: pacman
+ state: latest
+ update_cache: yes
+ - name: Upgrade everything
+ community.general.pacman:
+ update_cache: yes
+ upgrade: yes
+ # TODO OPT: Check for and report any .pacnew and .pacsave
+ # TODO OPT: Update pip packages (if there's a generic way)?
+ tags:
+ - upgrade
+ - name: Persist changes
+ import_tasks: persist.yml