lmn-client/roles/lmn_vm/tasks/main.yml
Raphael Dannecker 23a9b6ff97 Enable firewall activation for exam-mode
For working exam-mode we need to block direct internet access by firewall.
Users have to use squid-proxy on firewall, which can be disabled for exam-users.
To allow VM-traffic (anonymous user), we use a local squid server with users
kerberos-ticket to authenticate on the parent squid.

When using VMs on teacherdevices offsite, the local squid has to use direct internet access.
So we need two squid configs. When switching between offsite and onsite,
the squid has to be restartet with corresponding config.
2024-12-11 13:09:30 +01:00

315 lines
8.2 KiB
YAML

---
# FIXME #691138, better: prepare interfaces ready to use, c.f. down below, macvtap.
# This task needs to be run before the last apt run to provide a ready-to-use installation.
- name: Allow users to attach to bridge
ansible.builtin.copy:
dest: /etc/apt/apt.conf.d/94qemu-bridge-suid
content: |
## Modify permissions after installation/upgrade
## to run qemu-bridge as root
DPkg::Post-Invoke {"/usr/bin/chmod 4755 /usr/lib/qemu/qemu-bridge-helper || true"; };
- name: install libvirt packages
apt:
name:
- aria2
- mktorrent
- libvirt-daemon-system
- virt-manager
- dialog # for vm-netboot menu
state: latest
autoremove: true
#- name: allow all users to use VMs
# lineinfile:
# dest: /etc/libvirt/libvirtd.conf
# line: 'auth_unix_rw = "none"'
# insertafter: '#auth_unix_rw = "polkit"'
# notify: reload libvirtd
- name: Configure pam_mount for VM bind mounts
blockinfile:
dest: /etc/security/pam_mount.conf.xml
marker: "<!-- {mark} ANSIBLE MANAGED BLOCK (bind mounts for VMs) -->"
block: |
<!-- bind mounts for the VMs, setting gid here does not work -->
<volume
path="~"
mountpoint="/lmn/media/%(USER)/home"
options="bind"
><not><or><user>root</user><user>ansible</user><user>Debian-gdm</user><user>sddm</user><user>{{ localuser }}</user></or></not>
</volume>
<volume
path="/srv/samba/schools/default-school/share"
mountpoint="/lmn/media/%(USER)/share"
options="bind"
><not><or><user>root</user><user>ansible</user><user>Debian-gdm</user><user>sddm</user><user>{{ localuser }}</user></or></not>
</volume>
insertafter: "<!-- END ANSIBLE MANAGED BLOCK .* -->"
- name: Configure pam_mount for VM bind mounts
blockinfile:
dest: /etc/security/pam_mount.conf.xml
marker: "<!-- {mark} ANSIBLE MANAGED BLOCK (bind mount school for VMs) -->"
block: |
<volume
path="/srv/samba/schools/default-school"
mountpoint="/lmn/media/%(USER)/school"
options="bind"
><not><or><user>root</user><user>ansible</user><user>Debian-gdm</user><user>sddm</user><user>{{ localuser }}</user></or></not>
</volume>
insertafter: "<!-- END ANSIBLE MANAGED BLOCK .* -->"
when: "'localhome' in group_names"
- name: Use umount script for proper cleanup
blockinfile:
dest: /etc/security/pam_mount.conf.xml
marker: "<!-- {mark} ANSIBLE MANAGED BLOCK (umount script needed for bind mounts ordering) -->"
block: |
<!-- Provide special umount script here to handle bind mounts and proper ordering -->
<umount>/usr/local/sbin/pam-umount.sh %(USER) %(USERUID) %(MNTPT)</umount>
insertafter: '^<mntoptions.*'
- name: Prepare umount script
ansible.builtin.copy:
src: pam-umount.sh
dest: /usr/local/sbin/pam-umount.sh
mode: "0755"
- name: Insert domain in default-network
lineinfile:
path: /etc/libvirt/qemu/networks/default.xml
line: ' <domain name="{{ ansible_domain }}" localOnly="no"/>'
insertafter: '</ip>'
- name: Autostart default network for VMs
file:
src: /etc/libvirt/qemu/networks/default.xml
dest: /etc/libvirt/qemu/networks/autostart/default.xml
state: link
- name: Create system-user syncing VM-files and others
ansible.builtin.user:
name: lmnsynci
comment: lmn sync user
system: true
create_home: false
- name: Create /etc/lmn directory
file:
path: /etc/lmn
state: directory
- name: Create /lmn directory
file:
path: /lmn
state: directory
- name: Create /lmn/media directory
file:
path: /lmn/media
state: directory
mode: '1777'
- name: Create /var/vm directory
file:
path: /var/vm
state: directory
mode: '1777'
- name: Create vm directory
file:
path: /lmn/vm
state: directory
owner: lmnsynci
group: lmnsynci
mode: 0755
- name: Create cleanup-exam.conf
ansible.builtin.copy:
dest: /etc/tmpfiles.d/clean-exam.conf
content: |
R! /lmn/media/*-exam
- name: Install squid
apt:
name:
- squid
state: latest
autoremove: true
- name: Disable squid
systemd:
name: squid
enabled: false
state: stopped
- name: Deploy squid user mode configuration
template:
src: "{{ item }}.j2"
dest: "/etc/squid/{{ item }}"
mode: '0644'
loop:
- squid-usermode.conf
- squid-usermode-external.conf
- name: Deploy startusersquid script
template:
src: startusersquid.sh.j2
dest: /usr/local/bin/startusersquid.sh
mode: '0755'
notify: daemon reload
- name: Provide usersquid service
copy:
src: usersquid.service
dest: /etc/systemd/user/usersquid.service
mode: 0644
- name: Deploy sudo configurations
copy:
src: "{{ item }}"
dest: "/etc/sudoers.d/90-{{ item }}"
owner: root
group: root
mode: '0700'
loop:
- lmn-mounthome
- lmn-vm
- name: Deploy vmimages scripts
copy:
src: "{{ item }}"
dest: /usr/local/bin/
owner: root
group: root
mode: '0755'
loop:
- mounthome.sh
- vm-create
- vm-rebase
- vm-run
- vm-upload
- vm-sync
- vm-link-images
- vm-virtiofsd
- virtiofsd
- vm-aria2
- uploadseed
- desktop-sync
- name: Deploy vm configuration file vm.conf
ansible.builtin.copy:
src: vm.conf
dest: /etc/lmn/vm.conf
owner: root
group: root
- name: Deploy aria2 RPC password file
ansible.builtin.copy:
dest: /etc/lmn/uploadseed.conf
owner: root
group: lmnsynci
mode: '0640'
content: |
{{ uploadseed_pwd }}
- name: Prepare directory for aria2 dht.dat
ansible.builtin.file:
path: /var/cache/aria2/
state: directory
owner: lmnsynci
group: lmnsynci
- name: Prepare directory for qemu bridge config
ansible.builtin.file:
path: /etc/qemu/
state: directory
- name: Deploy bridge.conf needed for qemu session mode
ansible.builtin.copy:
dest: /etc/qemu/bridge.conf
content: |
allow virbr0
allow virbr1
allow virbr2
- name: Configure macvtap interface
ansible.builtin.copy:
dest: "/etc/NetworkManager/system-connections/macvlan-vm-macvtap-{{ item }}.nmconnection"
mode: '0600'
content: |
[connection]
id=macvlan-macvtap-{{ item[3:9] }}
type=macvlan
interface-name=macvtap-{{ item[3:9] }}
[macvlan]
mode=2
parent={{ item }}
tap=true
[ipv4]
method=disabled
[ipv6]
method=disabled
[proxy]
loop: "{{ ansible_interfaces | select('search', '^en[pso].+') }}"
- name: Adjust interface permissions for user mode VMs
ansible.builtin.copy:
dest: /etc/udev/rules.d/80-macvlan.rules
content: |
{% for interface in (ansible_interfaces | select('search', '^en[pso].+')) %}
SUBSYSTEMS=="net", KERNELS=="macvtap-{{ interface[3:9] }}", MODE="0666"
{% endfor %}
- name: Create directory for local .desktop-Files
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- /usr/local/share/applications
- /usr/local/share/desktop-directories
notify: Run update-desktop-database
- name: Copy fvs.directory
ansible.builtin.copy:
src: fvs.directory
dest: /usr/local/share/desktop-directories/
notify: Run update-desktop-database
- name: Copy fvs.menu
ansible.builtin.copy:
src: fvs.menu
dest: /etc/xdg/menus/applications-merged/
notify: Run update-desktop-database
- name: check if sync.desktop is installed
stat: path=/usr/local/share/applications/sync.desktop
register: syncdesktop
- name: remove deprecated desktop-files
ansible.builtin.shell: rm -f /usr/local/share/applications/*.desktop
when: not syncdesktop.stat.exists
notify: Run update-desktop-database
- name: Copy initial sync starter
ansible.builtin.copy:
src: sync.desktop
dest: /usr/local/share/applications/
notify: Run update-desktop-database
- name: Start virt-manager in session mode by default
ansible.builtin.copy:
dest: /usr/local/bin/virt-manager
content: |
#!/usr/bin/sh
exec /usr/bin/virt-manager --connect qemu:///session $@
mode: '0755'
- name: Copy vm-netboot script
ansible.builtin.copy:
src: vm-netboot
dest: /usr/local/bin/
mode: '0755'