Compare commits

...
Sign in to create a new pull request.

20 commits
fvs ... main

Author SHA1 Message Date
Raphael Dannecker
efd48de6c7 The virt-viewer package must be explicitly selected for trixie 2025-06-05 13:02:12 +02:00
Raphael Dannecker
db6197d0a0 Prevents the --options option in vm-run from interfering with other options 2025-06-05 12:48:10 +02:00
Raphael Dannecker
563ac18483 Add host to inventory 2025-06-04 11:20:58 +02:00
Raphael Dannecker
76c7cc042a Configure display resolution / audio out for specific clients 2025-06-04 10:49:47 +02:00
Raphael Dannecker
84865291e0 Allow multiple macvtap-VMs to use the same MAC address 2025-06-04 10:26:56 +02:00
Raphael Dannecker
6e119e0129 Omit backports, because Trixie does not have backports yet 2025-06-04 10:21:18 +02:00
Andreas B. Mundt
6063e65089 Fixes for trixie 2025-05-14 12:33:39 +02:00
Andreas B. Mundt
0e0950d184 Fix conditionals for ansible version in trixie 2025-05-14 12:33:39 +02:00
Raphael Dannecker
ce31924a3c Remove unnecessary systemd-resolved 2025-05-08 07:16:12 +02:00
Raphael Dannecker
f0fd1d5aa0 Skip delegate_to tasks when running in installer 2025-05-07 14:38:01 +02:00
Raphael Dannecker
e060ba9161 Prevent playbook abort if iwd was not installed 2025-05-07 13:35:32 +02:00
Raphael Dannecker
dfb9cf5ee7 Fix playbook check if delegate_to host is accessible 2025-05-07 13:32:17 +02:00
Raphael Dannecker
233e8e4ecf Improve documentation 2025-04-09 16:08:46 +02:00
Raphael Dannecker
3580a9141b Avoid the need to use ssh keys for ansible connections to localhost 2025-04-09 14:18:17 +02:00
Raphael Dannecker
39d2491e36 Use defaults for kde_desktop_pkg in inventory-sample 2025-04-09 08:38:18 +02:00
Raphael Dannecker
9f5ecfc4f1 Improve documentation about installation via pxe 2025-04-08 18:35:47 +02:00
Raphael Dannecker
0406669109 Add vaultpw to debian installer preseeding 2025-04-08 11:19:19 +02:00
Raphael Dannecker
4f69dc0dfe Merge fvs branch into main 2025-04-08 08:06:36 +02:00
Andreas B. Mundt
92bacc4dd3 Merge branch 'fvs' 2024-03-12 19:45:10 +01:00
andi
24fcf70e1d Initial commit 2024-03-12 17:53:49 +00:00
19 changed files with 800 additions and 696 deletions

View file

@ -1,6 +1,12 @@
# Installation on existing client # Installation on existing client
An easy method to test the lmn-client is to run the playbook manual on a fresh installed client. A straightforward way to test the lmn-client is to manually run the playbook on a freshly installed client.
This can be done in the following ways:
On the client using ansible-pull
On the client by checking out the lmn-client repository and running the playbook locally
On a target device by checking out the lmn-client repository locally and executing the playbook against the target device
## Direct call via ansible-pull ## Direct call via ansible-pull
@ -9,10 +15,10 @@ With two simple commands you can install the lmn-client with default configurati
Steps: Steps:
* Install debian on client (via USB or PXE) * Install debian on client (via USB or PXE)
* Install additional packages: ansible * Install additional packages: ansible
`sudo apt install ansible` `sudo apt install ansible`
* Run Playbook * Run Playbook
`ansible-pull -i inventory.yml -l localhost, --url=https://codeberg.org/DigitalSouveraeneSchule/lmn-client.git -C main lmn-client.yml` `sudo ansible-pull --verbose -i inventory-sample.yml -l localhost --url=https://codeberg.org/DigitalSouveraeneSchule/lmn-client.git -C main lmn-client.yml`
## Checkout git and run ansible locally ## Checkout git and run ansible locally
@ -24,10 +30,12 @@ Steps:
* Install debian on client (via USB or PXE) * Install debian on client (via USB or PXE)
* Install additional packages: ansible, git * Install additional packages: ansible, git
`sudo apt install ansible git` `sudo apt install ansible git`
* Checkout Repository * Checkout Repository
`git clone https://codeberg.org/DigitalSouveraeneSchule/lmn-client.git` `git clone https://codeberg.org/DigitalSouveraeneSchule/lmn-client.git`
* Change into repository directory
`cd lmn-client`
* Create inventory * Create inventory
`cp inventory.yml inventory-myschool.yml` `cp inventory-sample.yml inventory-myschool.yml`
* Edit inventory-myschool.yml * Edit inventory-myschool.yml
e.g.: `nano inventory-myschool.yml` e.g.: `nano inventory-myschool.yml`
* Run Playbook * Run Playbook

View file

@ -2,15 +2,28 @@
* **Using DigitalSouveraeneSchule repository and LinuxMuster.Net tftp** * **Using DigitalSouveraeneSchule repository and LinuxMuster.Net tftp**
Simplest solution. Playbook and default inventory from DigitalSouveraeneSchule codeberg repository. Simplest solution. Playbook and default inventory from DigitalSouveraeneSchule codeberg repository.
Linux kernel and initial Ramdisk from debian repository. Linux kernel and initial Ramdisk from debian repository.
Client must have access to the internet (noproxy group).
* **Using your own repository and LinuxMuster.Net tftp** * **Using your own repository and LinuxMuster.Net tftp**
Here you can use your own inventory and make many custom settings. Here you can use your own inventory and make many custom settings.
Linux kernel and initial Ramdisk from debian repository. Linux kernel and initial Ramdisk from debian repository.
Client must have access to the internet (noproxy group).
* **Using your own repository and livebox tftp** * **Using your own repository and livebox tftp**
Additional kernel and Ramdisk from your own infrastrukture. Additional kernel and Ramdisk from your own infrastrukture.
Client does not need direct internet access.
## Using codeberg repository and LinuxMuster.Net tftp ## Using codeberg repository and LinuxMuster.Net tftp
### Requirements / firewall settings
The computer on which the linuxclient is to be installed must have access to the Internet (add host to noproxy group)
The following resources are downloaded from the internet:
* The repository is provided by codeberg.org
* the Linux kernel, the initial ramdisk and the installation files are loaded from debian.org.
* mscorefonts from Microsoft
### Modification LinuxMuster.Net server ### Modification LinuxMuster.Net server
Create grub config for device group `lmnclient` on your schools server: Create grub config for device group `lmnclient` on your schools server:
@ -25,9 +38,12 @@ set default=1
menuentry 'Installer Debian bookworm (amd64) + preseed + ansible inventory' { menuentry 'Installer Debian bookworm (amd64) + preseed + ansible inventory' {
echo -n "Enter domain join password: " echo -n "Enter domain join password: "
read adpw read adpw
set vaultpw="dummy"
# echo -n "Enter vault password"
# read vaultpw
linux (http,ftp.debian.org)/debian/dists/stable/main/installer-amd64/current/images/netboot/debian-installer/amd64/linux auto=true priority=high \ linux (http,ftp.debian.org)/debian/dists/stable/main/installer-amd64/current/images/netboot/debian-installer/amd64/linux auto=true priority=high \
url=https://codeberg.org/DigitalSouveraeneSchule/lmn-client/raw/branch/fvs/misc/preseed.cfg interface=auto \ url=https://codeberg.org/DigitalSouveraeneSchule/lmn-client/raw/branch/main/misc/preseed.cfg interface=auto \
playbook=lmn-client.yml adpw="${adpw}" --- playbook=lmn-client.yml adpw="${adpw}" vaultpw="${vaultpw}" ---
initrd (http,ftp.debian.org)/debian/dists/stable/main/installer-amd64/current/images/netboot/debian-installer/amd64/initrd.gz initrd (http,ftp.debian.org)/debian/dists/stable/main/installer-amd64/current/images/netboot/debian-installer/amd64/initrd.gz
} }
``` ```
@ -47,4 +63,52 @@ classroom;mypc01;lmnclient;F2:81:6B:C9:E3:EF;10.0.5.51;;;;classroom-studentcompu
* confirm `hostname` and `domain` (you will be asked in network setup) * confirm `hostname` and `domain` (you will be asked in network setup)
* ... Get a cup of coffee ... wait until reboot ... login (Logging in may take a few minutes after installation) * ... Get a cup of coffee ... wait until reboot ... login (Logging in may take a few minutes after installation)
## Using your own livebox server
## Using your own repository and LinuxMuster.Net tftp
If you fork the lmn-client repository, you can customize the preseeding and inventory to your needs.
Use the instructions in the previous section and customize the repository in `/srv/linbo/boot/grub/lmnclient.cfg`.
It makes sense to encrypt your inventory via `ansible-vault`.
When using encrypted inventories you have to provide the vault password by commenting in the two lines in the `/srv/linbo/boot/grub/lmnclient.cfg`.
## Using your own repository and livebox tftp
The next improvement will be to use your own livebox with following functionalities:
* Providing linux kernel and initial ramdisk for installer
* Can be used as cache for debian packages (aptcacher)
* Can provide mscorefonts and libdvdcss (multimedia codecs)
* Can be used to boot live systems (netboot) via pxe
### Installing the livebox server
* Install debian VM and configure network
* Install additional packages: ansible
`sudo apt install ansible`
* Run livebox playbook
`ansible-pull -i localhost, --url=https://salsa.debian.org/andi/debian-lan-ansible.git -C master livebox.yml`
* Set DNS entry for your new livebox server
### Modification LinuxMuster.Net server
The file `/srv/linbo/boot/grub/lmnclient.cfg` might look like this:
```
# ### NOT managed by linuxmuster.net ###
# edit to your needs
set default=1
menuentry 'Installer Debian bookworm (amd64) + preseed + ansible inventory' {
echo -n "Enter domain join password: "
read adpw
set vaultpw="dummy"
# echo -n "Enter vault password"
# read vaultpw
linux (http,livebox.example.com)/d-i/n-pkg/images/12/amd64/text/debian-installer/amd64/linux auto=true priority=high \
url=https://codeberg.org/MySchool/lmn-client/raw/branch/main/misc/preseed-myschool.cfg interface=auto \
playbook=lmn-client.yml adpw="${adpw}" vaultpw="${vaultpw}" ---
initrd (http,livebox.example.com)/d-i/n-pkg/images/12/amd64/text/debian-installer/amd64/initrd.gz
}
```

View file

@ -2,10 +2,9 @@
all: all:
vars: vars:
domain: "{{ ansible_domain }}" domain: "{{ ansible_domain }}"
security_defaultuser_login_disable: false
kde_desktop_pkg:
- akonadi-backend-sqlite
# Comment out on productive systems when ssh key is provided
security_defaultuser_login_disable: false
## Proxy configuration (see: doc/localproxy.md) ## Proxy configuration (see: doc/localproxy.md)
# localproxy: true # localproxy: true
@ -59,7 +58,6 @@ all:
# - vim # - vim
# - mc # - mc
# - tmux # - tmux
# - debconf-utils
## WLAN configuration (see: doc/vpn.md): ## WLAN configuration (see: doc/vpn.md):
## ##
@ -105,6 +103,7 @@ all:
hosts: hosts:
localhost: localhost:
ansible_connection: local
laptops: laptops:
children: children:

File diff suppressed because it is too large Load diff

View file

@ -50,13 +50,11 @@ d-i apt-setup/contrib boolean true
d-i mirror/country string manual d-i mirror/country string manual
d-i mirror/http/hostname string deb.debian.org d-i mirror/http/hostname string deb.debian.org
d-i mirror/http/directory string /debian d-i mirror/http/directory string /debian
#d-i mirror/http/proxy string http://10.167.0.253:3142/ #d-i mirror/http/proxy string http://aptcache.pn.steinbeis.schule:3142/
#d-i mirror/http/proxy string http://192.168.1.17:3142/ d-i mirror/http/proxy string
#d-i mirror/http/proxy string http://aptcache.steinbeisschule-reutlingen.de:3142/
d-i mirror/http/proxy string http://aptcache.pn.steinbeis.schule:3142/
# NTP server to use: # NTP server to use:
d-i clock-setup/ntp-server string server.pn.steinbeis.schule #d-i clock-setup/ntp-server string server.pn.steinbeis.schule
### Backports: ### Backports:
#apt-setup-udeb apt-setup/services-select multiselect security, updates, backports #apt-setup-udeb apt-setup/services-select multiselect security, updates, backports
@ -129,10 +127,9 @@ d-i preseed/late_command string \
in-target mount -v -t tmpfs tmpfs /dev/shm ; \ in-target mount -v -t tmpfs tmpfs /dev/shm ; \
echo "$vaultpw" > /target/dev/shm/vaultpw ; \ echo "$vaultpw" > /target/dev/shm/vaultpw ; \
in-target ansible-pull --verbose --purge --extra-vars="run_in_installer=true" \ in-target ansible-pull --verbose --purge --extra-vars="run_in_installer=true" \
-l localhost \ --vault-password-file /dev/shm/vaultpw -l localhost \
-i inventory-sample.yml --url=https://codeberg.org/DigitalSouveraeneSchule/lmn-client.git -C fvs $playbook ; \ -i inventory-sample.yml --url=https://codeberg.org/DigitalSouveraeneSchule/lmn-client.git -C main $playbook ; \
fi fi
## --vault-password-file /dev/shm/vaultpw -l localhost \
# #
## When installing in combination with ansible-pull, ## When installing in combination with ansible-pull,
## export your ansible playbook like: ## export your ansible playbook like:

View file

@ -220,7 +220,7 @@
ansible.builtin.blockinfile: ansible.builtin.blockinfile:
path: /usr/share/sddm/themes/debian-breeze/Main.qml path: /usr/share/sddm/themes/debian-breeze/Main.qml
marker: // {mark} ANSIBLE MANAGED BLOCK marker: // {mark} ANSIBLE MANAGED BLOCK
insertbefore: '\s+//Footer' insertbefore: '^}$'
block: | block: |
Text { Text {
id: hostname id: hostname

View file

@ -14,7 +14,7 @@
main non-free-firmware main non-free-firmware
state: present state: present
update_cache: true update_cache: true
# when: extra_pkgs_bpo|length when: extra_pkgs_bpo | length > 0 or extra_pkgs_bpo1 | length > 0 or extra_pkgs_bpo2 | length > 0
- name: Install extra packages from backports - name: Install extra packages from backports
ansible.builtin.apt: ansible.builtin.apt:
@ -25,6 +25,7 @@
- "{{ extra_pkgs_bpo }}" - "{{ extra_pkgs_bpo }}"
- "{{ extra_pkgs_bpo1 }}" - "{{ extra_pkgs_bpo1 }}"
- "{{ extra_pkgs_bpo2 }}" - "{{ extra_pkgs_bpo2 }}"
when: extra_pkgs_bpo | length > 0 or extra_pkgs_bpo1 | length > 0 or extra_pkgs_bpo2 | length > 0
- name: Timestamp successfull run and send up-to-date report - name: Timestamp successfull run and send up-to-date report
ansible.builtin.shell: ansible.builtin.shell:

View file

@ -6,6 +6,7 @@ kde_desktop_pkg:
- calligra - calligra
- codeblocks - codeblocks
- dia - dia
- filius
- flameshot - flameshot
- freecad - freecad
- fritzing - fritzing
@ -14,8 +15,9 @@ kde_desktop_pkg:
- inkscape - inkscape
- kde-full - kde-full
- keepassxc - keepassxc
- kicad
- kicad-doc-de
- librecad - librecad
- mu-editor
- openboard - openboard
- qtcreator - qtcreator
- spyder - spyder
@ -34,3 +36,5 @@ kde_desktop_pkg:
- xdg-desktop-portal-kde - xdg-desktop-portal-kde
- xdg-desktop-portal-wlr # share screen in browser - xdg-desktop-portal-wlr # share screen in browser
- xournalpp - xournalpp
kde_desktop_pkg_bpo: [ ]

View file

@ -8,19 +8,14 @@
repo: deb http://deb.debian.org/debian/ {{ ansible_distribution_release }}-backports main non-free-firmware repo: deb http://deb.debian.org/debian/ {{ ansible_distribution_release }}-backports main non-free-firmware
state: present state: present
update_cache: true update_cache: true
when: kde_desktop_pkg_bpo | length > 0
- name: Install extra packages from backports - name: Install extra packages from backports
ansible.builtin.apt: ansible.builtin.apt:
name: name: "{{ kde_desktop_pkg_bpo }}"
- filius
- kicad
- kicad-doc-de
- libreoffice
- libreoffice-l10n-de
- libreoffice-qt5
state: latest # noqa package-latest
autoremove: true autoremove: true
default_release: "{{ ansible_distribution_release }}-backports" default_release: "{{ ansible_distribution_release }}-backports"
when: kde_desktop_pkg_bpo | length > 0
- name: Create akonadi config dir - name: Create akonadi config dir

View file

@ -9,7 +9,7 @@
ansible.builtin.blockinfile: ansible.builtin.blockinfile:
path: /usr/share/sddm/themes/debian-breeze/Main.qml path: /usr/share/sddm/themes/debian-breeze/Main.qml
marker: // {mark} ANSIBLE MANAGED BLOCK localhome marker: // {mark} ANSIBLE MANAGED BLOCK localhome
insertbefore: '\s+//Footer' insertbefore: '^}$'
block: | block: |
Text { Text {
id: localhome id: localhome

View file

@ -98,7 +98,7 @@
export superusers export superusers
password_pbkdf2 root {{ grub_pwd }} password_pbkdf2 root {{ grub_pwd }}
notify: Run update-grub notify: Run update-grub
when: grub_pwd|default(false) when: grub_pwd | bool | default(false)
- name: Allow booting grub menu entries - name: Allow booting grub menu entries
ansible.builtin.lineinfile: ansible.builtin.lineinfile:

View file

@ -5,14 +5,14 @@
mode: '0644' mode: '0644'
content: > content: >
{{ apt_conf }} {{ apt_conf }}
when: apt_conf|default(false) when: apt_conf | bool | default(false)
- name: Set NTP server - name: Set NTP server
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: /etc/systemd/timesyncd.conf path: /etc/systemd/timesyncd.conf
insertafter: '^#NTP=' insertafter: '^#NTP='
line: NTP={{ ntp_serv }} line: NTP={{ ntp_serv }}
when: ntp_serv|default(false) when: ntp_serv | bool | default(false)
- name: Add proposed-updates repository - name: Add proposed-updates repository
ansible.builtin.apt_repository: ansible.builtin.apt_repository:

View file

@ -37,7 +37,7 @@
line: "SystemGroup root lpadmin {{ printer_admin_group }}" line: "SystemGroup root lpadmin {{ printer_admin_group }}"
regexp: '^SystemGroup' regexp: '^SystemGroup'
state: present state: present
when: printer_admin_group | length when: printer_admin_group | length > 0
- name: Disable cups-browsed - name: Disable cups-browsed
ansible.builtin.systemd: ansible.builtin.systemd:

View file

@ -216,7 +216,7 @@ while true; do
shift shift
;; ;;
-o | --options ) -o | --options )
LIBVIRTOPTS=$2 LIBVIRTOPTS="${LIBVIRTOPTS} $2"
shift 2 shift 2
;; ;;
--no-viewer ) --no-viewer )
@ -267,6 +267,7 @@ while true; do
type="ethernet,mac=${mac},target.dev=${interface},xpath1.set=./target/@managed=no,model.type=virtio" type="ethernet,mac=${mac},target.dev=${interface},xpath1.set=./target/@managed=no,model.type=virtio"
LIBVIRTOPTS="${LIBVIRTOPTS} --network type=$type" LIBVIRTOPTS="${LIBVIRTOPTS} --network type=$type"
done done
LIBVIRTOPTS="${LIBVIRTOPTS} --check mac_in_use=off"
shift shift
;; ;;
--os ) --os )

View file

@ -18,6 +18,7 @@
- mktorrent - mktorrent
- libvirt-daemon-system - libvirt-daemon-system
- virt-manager - virt-manager
- virt-viewer
- dialog # for vm-netboot menu - dialog # for vm-netboot menu
# - name: allow all users to use VMs # - name: allow all users to use VMs

View file

@ -5,7 +5,7 @@
- wireguard - wireguard
- name: Check if wg_server is reachable - name: Check if wg_server is reachable
ansible.builtin.command: echo "Test if wg_server is reachable" ansible.builtin.command: echo "reachable"
delegate_to: wireguard_server delegate_to: wireguard_server
register: result register: result
changed_when: false changed_when: false
@ -17,10 +17,12 @@
* server not reachable * server not reachable
* no matching ssh-key * no matching ssh-key
changed_when: true changed_when: true
when: result.unreachable is defined and result.unreachable when: result.stdout is not defined or result.stdout!="reachable"
- name: Configure WG Server - name: Configure WG Server
when: result.unreachable is not defined or not result.unreachable when:
- result.stdout is defined and result.stdout=="reachable"
- not run_in_installer|default(false)|bool
block: block:
- name: Set facts wg_clientname - name: Set facts wg_clientname
ansible.builtin.set_fact: ansible.builtin.set_fact:

View file

@ -27,7 +27,7 @@
when: cert_client_active.stat.exists when: cert_client_active.stat.exists
- name: Check if radius-server is reachable - name: Check if radius-server is reachable
ansible.builtin.command: echo "Test if radius-server is reachable" ansible.builtin.command: echo "reachable"
delegate_to: radius_server delegate_to: radius_server
register: radius_reachable register: radius_reachable
changed_when: false changed_when: false
@ -40,12 +40,13 @@
- "* server not reachable" - "* server not reachable"
- "* no matching ssh-key" - "* no matching ssh-key"
changed_when: true changed_when: true
when: radius_reachable.unreachable is defined and radius_reachable.unreachable when: radius_reachable.stdout is not defined or radius_reachable.stdout!='reachable'
- name: Issue radius certificate - name: Issue radius certificate
ansible.builtin.include_tasks: eap-tls_issue-certificate.yaml ansible.builtin.include_tasks: eap-tls_issue-certificate.yaml
when: when:
- radius_reachable.unreachable is not defined or not radius_reachable.unreachable - radius_reachable.stdout is defined and radius_reachable.stdout=="reachable"
- not run_in_installer|default(false)|bool
- | - |
( not cert_client_active.stat.exists ) or ( not cert_client_active.stat.exists ) or
(cert_serial.stdout | replace('serial=','') | int(base=16) ) in ( radius_crl.revoked_certificates | map(attribute='serial_number') | list ) or (cert_serial.stdout | replace('serial=','') | int(base=16) ) in ( radius_crl.revoked_certificates | map(attribute='serial_number') | list ) or

View file

@ -105,6 +105,7 @@
ansible.builtin.systemd: ansible.builtin.systemd:
name: iwd.service name: iwd.service
enabled: false enabled: false
failed_when: false
- name: Remove deprecated NetworkManager config - name: Remove deprecated NetworkManager config
ansible.builtin.blockinfile: ansible.builtin.blockinfile:

View file

@ -3,7 +3,6 @@
- name: Install packages related to wifi - name: Install packages related to wifi
ansible.builtin.apt: ansible.builtin.apt:
name: name:
- systemd-resolved
- firmware-realtek # for our wifi sticks - firmware-realtek # for our wifi sticks
- name: Provide service to enable WiFi on boot - name: Provide service to enable WiFi on boot