## This playbook deploys a client for LinuxMuster.
#
# Use the following in the installer's preseed file:
#
# d-i preseed/late_command string \
#       mkdir -p /target/home/ansible/.ssh && \
#       echo "ssh-ed25519 A...YOUR.KEY...Z" >> /target/home/ansible/.ssh/authorized_keys ; \
#       in-target chown -R ansible:ansible /home/ansible/.ssh/ ; \
#       in-target chmod -R og= /home/ansible/.ssh/ ; \
#       if [ -n "$playbook" ] ; then \
#         mkdir -v /target/dev/shm ; \
#         in-target mount -v -t tmpfs tmpfs /dev/shm ; \
#         echo "$vaultpw" > /target/dev/shm/vaultpw ; \
#         in-target ansible-pull --verbose --purge --extra-vars="run_in_installer=true" \
#            --vault-password-file /dev/shm/vaultpw \
#            -i localhost, --url=git://ansible.example.org/.git -C YOUR_BRANCH $playbook ; \
#       fi
#
---
- name: Apply common configuration to the machines
  hosts: all # desktop:laptop
  remote_user: ansible
  become: yes
  pre_tasks:
    - pause:
        prompt: "Enter global-admin AD password. Leave empty to skip domain join"
        echo: false
      register: adpw
      no_log: true
      when: "ansible_cmdline.adpw is not defined"
    - name: Preseed apparmor
      debconf:
        name: apparmor
        question: apparmor/homedirs
        value: >-
          /srv/samba/schools/default-school/teachers/
          /srv/samba/schools/default-school/students/*/
          /srv/samba/schools/default-school/examusers/
        vtype: string
    - name: Preseed unattended-upgrades
      debconf:
        name: unattended-upgrades
        question: unattended-upgrades/enable_auto_updates
        value: true
        vtype: boolean

  vars_files: lmn-vault
  vars:
    domain: "{{ ansible_domain }}"
    kerberize_uris: "{{ vault_kerberize_uris }}"  ##  example.org
    apt_conf: "{{ vault_apt_conf }}"  ## Acquire::http::Proxy "http://aptcache.example.org:3142/";
    ntp_serv: "{{ vault_ntp_serv }}"  ## ntp.example.org
    proxy: "{{ vault_proxy }}"        ## http://firewall.example.org:3128
    no_proxy: "{{ vault_no_proxy }}"  ## firewall.example.org,server.example.org,idam.example.org,dw.example.org
    printservers: "{{ vault_printservers }}" ## ['10.0.0.1', '10.0.0.15']

    ## PAM mount nextcloud, remove or leave empty to skip:
    web_dav: "{{ vault_web_dav }}"    ## https://nc.example.org/remote.php/dav/files/%(USER)

    ## Local mirror for mscorefonts. Remove or leave empty to use no mirror:
    mirror_msfonts: "{{ vault_mirror_msfonts }}" ## http://livebox.example.org/mscorefonts/

    ## Local mirror for libdvdcss. Remove or leave empty to use no mirror:
    mirror_dvdcss: "{{ vault_mirror_dvdcss }}"   ## http://livebox.example.org/libdvdcss/

    uploadseed_pwd: "{{ vault_uploadseed_pwd }}"
    rsyncsecret: "{{ vault_rsyncsecret }}"
    keys2deploy: "{{ vault_keys2deploy }}" ## ['ssh-ed25519 AAAAC…uYlnS0', 'ssh-ed25519 AAAA…KTM']
    localuser: "{{ vault_localuser }}"  ##  needed here for the (universal) pam-mount configuration

    ## Use grub-mkpasswd-pbkdf2 to calculate the password hash:
    grub_pwd: "{{ vault_grub_pwd }}"
    nfs4: false
    extra_pkgs:
      - vim
      - mc
      - tmux
      - krb5-user
      - unattended-upgrades
      - debconf-utils
    extra_pkgs_bpo: [] # [ linux-image-amd64 ]

    # Wireguad config
    wg_endpoint: "{{ vault_wg_endpoint }}"
    wg_allowed_ips: "{{ vault_wg_allowed_ips }}"
    wg_ip_cdr: "{{ vault_wg_ip_cdr }}"
    wg_dns: "{{ vault_wg_dns }}"
    wg_dns_search: "{{ vault_wg_dns_search }}"

  roles:
    - lmn_network
    - role: up2date_debian
      tags: upgrade
    - lmn_sssd
    - lmn_mount
    - lmn_kde
    - lmn_fvs ## school specific customization
    - lmn_vm
    - lmn_printer
    - kerberize
    - lmn_security
    - role: lmn_localhome
      when: groups.localhome is defined and inventory_hostname in groups.localhome
    - role: lmn_teacherlaptop
      when: groups.teacherlaptop is defined and inventory_hostname in groups.teacherlaptop

  tasks:
    ## Temporary fixes and quirks:
    - name: Remove disturbing NetworkManager connection
      file:
        path: "/etc/NetworkManager/system-connections/Wired connection 1"
        state: absent
      when: ansible_interfaces | select('search', '^en[pso].+') | length > 1

    - name: Fix 8086:4909 external graphics card
      replace:
        dest: "/etc/default/grub"
        regexp: 'GRUB_CMDLINE_LINUX=""$'
        replace: 'GRUB_CMDLINE_LINUX="i915.force_probe=4909"'
      notify: Run update-grub
      when: ansible_board_vendor == "LENOVO" and ansible_board_name == "32CB"

    - name: Fix sound on 312A
      replace:
        dest: "/etc/default/grub"
        regexp: 'GRUB_CMDLINE_LINUX="snd-intel-dspcfg.dsp_driver=1"$'
        replace: 'GRUB_CMDLINE_LINUX=""'
      notify: Run update-grub
      when: ansible_board_vendor == "LENOVO" and ansible_board_name == "312A"

    - name: Fix sound on 312A and 312D
      apt:
        name: firmware-sof-signed
        state: latest
      when: >
        ansible_board_vendor == "LENOVO" and
        (ansible_board_name == "312D" or ansible_board_name == "312A")

    - name: Install customized CodeBlocks packages
      block:
        - name: Check for old CodeBlocks
          command:
            cmd: dpkg -l codeblocks
          register: codeblocks_version
          changed_when: False

        - name: Download codeblocks zip archive
          ansible.builtin.get_url:
            url: "http://livebox.pn.steinbeis.schule/codeblocks/CodeBlocks.zip"
            dest: /tmp/CodeBlocks.zip
            use_proxy: False
          register: new_codeblocks
          when: codeblocks_version.stdout is not search('svn13544')

        - name: Unpack zip archive and install packages manually
          shell:
            cmd: unzip -d /tmp/cb/ CodeBlocks.zip && dpkg -i cb/*.deb
            chdir: /tmp/
          when: new_codeblocks.changed | default(false)
      when: groups.PCroom is defined and inventory_hostname in groups.PCroom

## Clean up stuff from obsolete/faulty tasks:
    - name: Remove sddm login screen patch with deprecated marker (homeondisk)
      blockinfile:
        path: /usr/share/sddm/themes/debian-breeze/Main.qml
        marker: // {mark} ANSIBLE MANAGED BLOCK homeondisk
        state: absent

    - name: Remove packages we do not need anymore
      ansible.builtin.apt:
        name:
          - cachefilesd
          - mosquitto
        state: absent
        purge: True

    - name: Remove virtiofs service
      file:
        path: /etc/systemd/system/virtiofs@.service
        state: absent

    - name: Fix mount point permissions and owner
      file:
        path: "{{ item }}"
        mode: '0755'
        owner: root
        group: root
      loop:
        - /srv/samba
        - /srv/samba/schools

    - name: Remove pam_mount sysvol mount
      blockinfile:
        dest: /etc/security/pam_mount.conf.xml
        marker: "<!-- {mark} ANSIBLE MANAGED BLOCK (SysVol) -->"
        block: |
          <volume
            fstype="cifs"
            server="{{ smb_server }}"
            path="sysvol/"
            mountpoint="/srv/samba/%(USER)/sysvol"
            options="sec=krb5i,cruid=%(USERUID),user=%(USER),gid=1010,file_mode=0770,dir_mode=0770,mfsymlinks"
            ><not><or><user>root</user><user>ansible</user><user>Debian-gdm</user><user>sddm</user><user>{{ localuser }}</user></or></not>
          </volume>
        state: absent

    - name: check if rmlpr.timer is installed
      stat: path=/etc/systemd/system/rmlpr.timer
      register: rmlpr

    - name: disable rmlpr.timer
      systemd:
        name: rmlpr.timer
        enabled: false
      when: rmlpr.stat.exists

    - name: check if vmimage-torrent.service is installed
      stat: path=/etc/systemd/system/vmimage-torrent.service
      register: vmimagetorrent

    - name: disable vmimage-torrent.service
      systemd:
        name: vmimage-torrent.service
        enabled: false
      when: vmimagetorrent.stat.exists

    - name: Remove deprecated files and directories
      file:
        path: "{{ item }}"
        state: absent
      with_items:
        - /etc/linuxmuster-linuxclient7
        - /usr/lib/python3/dist-packages/linuxmusterLinuxclient7
        - /usr/share/linuxmuster-linuxclient7
        - /usr/local/bin/onLogin
        - /etc/sudoers.d/90-lmn-sudotools
        - /etc/systemd/system/rmlpr.service
        - /etc/systemd/system/rmlpr.timer
        - /usr/local/bin/sync-vm.sh
        - /usr/local/bin/run-vm.sh
        - /usr/local/bin/rebase-vm.sh
        - /usr/local/bin/create-vm.sh
        - /usr/local/bin/upload-vm.sh
        - /usr/local/bin/vmimage-torrent
        - /etc/systemd/system/vmimage-torrent.service
        - /usr/local/bin/linbo-torrenthelper.sh
        - /usr/local/bin/link-images.sh
        - /usr/local/bin/start-virtiofsd.sh
        - /etc/sudoers.d/90-lmn-upload-vm
        - /etc/sudoers.d/90-lmn-sync-vm
        - /etc/sudoers.d/90-lmn-startvirtiofsd
        - /etc/sudoers.d/90-lmn-link-images
        - /etc/rsync.secret
        - /etc/systemd/network/30-virbr1.netdev
        - /etc/systemd/network/30-virbr2.netdev
        - /etc/systemd/network/40-ethernet.network
        - /etc/systemd/network/40-ethernet-usb.network
        - /etc/systemd/network/50-virbr1.network
        - /etc/systemd/network/50-virbr2.network
        - /etc/systemd/network/60-wlan0-dhcp.network
        - /etc/NetworkManager/system-connections/macvlan-vm-macvtap.nmconnection

    - name: check if vm_usage_information.txt exists
      stat: path=/lmn/vm/vm_usage_information.txt
      register: vm_usage_information

    - name: pre-fill vm_usage_information.txt
      shell:
        cmd: |
          ls -tr *.qcow2 > vm_usage_information.txt || touchvm_usage_information.txt
          chown lmnsynci:lmnsynci vm_usage_information.txt
        chdir: /lmn/vm/
      when: not vm_usage_information.stat.exists

    - name: Detect if IPP-Everywhere printers exist
      ansible.builtin.shell:
        cmd: grep "IPP Everywhere" /etc/cups/printers.conf
      register: ipp_everywhere
      failed_when: False
      changed_when: False

    - name: Delete old IPP-Everywhere printers
      shell:
        cmd: |
          for p in $(lpstat -p | cut -d" " -f2); do
            lpadmin -x "$p"
          done
      when: not ipp_everywhere.rc

    - name: Remove old VM-printerlists
      shell:
        cmd: rm -f /lmn/media/*/.printerlist.csv

    - name: Remove Listen on VMBridge
      lineinfile:
        dest: /etc/cups/cupsd.conf
        line: 'Listen 192.168.122.1:631'
        state: absent

    - name: Remove NetworkManager Ansible-Block for non-laptops
      blockinfile:
        path: /etc/NetworkManager/NetworkManager.conf
        state: absent
      when: groups.laptop is defined and inventory_hostname not in groups.laptop

## bookworm fixes/hacks:
    - name: Work around sddm hang on shutdown
      ansible.builtin.lineinfile:
        path: /etc/systemd/system.conf
        line: DefaultTimeoutStopSec=5s
        insertafter: '^#DefaultTimeoutStopSec=.*'

    - name: Patch spyder to fix 'file-has-changed' issues on CIFS
      ansible.posix.patch:
        src: spyder.patch
        dest: /usr/lib/python3/dist-packages/spyder/plugins/editor/widgets/editor.py

#################

    - name: Timestamp successfull run and send up-to-date report
      ansible.builtin.shell:
        cmd: date --iso-8601=seconds >> /var/local/ansible-stamps && /usr/local/sbin/reporter
      changed_when: False
      tags: upgrade

    - name: Force ansible-run after install trough emitter by setting timestamp in the past
      ansible.builtin.shell:
        cmd: echo "2020-01-01T00:00:00+01:00" >> /var/local/ansible-stamps && /usr/local/sbin/reporter
      when: run_in_installer|default(false)|bool

#################

- name: Apply additional laptop configuration
  hosts: laptop
  remote_user: ansible
  become: yes
  vars_files: lmn-vault
  vars:
    wifipasswd: "{{ vault_wifipasswd[ssid] }}"
    localuser: "{{ vault_localuser }}"
    localuser_pwd: "{{ vault_localuser_pwd }}"
  roles:
    - role: lmn_wlan_iwd
      when: ansible_interfaces | select('search', 'wl.+') | first is defined
    - role: lmn_localuser
      when: not (groups.teacherlaptop is defined and inventory_hostname in groups.teacherlaptop)
  tasks:
    - name: Remove deprecated files and directories (laptop-class)
      file:
        path: "{{ item }}"
        state: absent
      with_items:
        - /etc/systemd/network/80-wlan-dhcp.network
        - /etc/systemd/network/wlan-dhcp.network
        - /etc/systemd/network/virbr1.netdev
        - /etc/systemd/network/virbr1.network
        - /etc/systemd/network/wlan-dhcp.network