commit 01b88d4c07a08a96b899d61003b253bd5699b6c4 Author: Matt Date: Sun Sep 28 18:02:09 2025 -0700 init commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..3c3bdfc --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +This role will install KDE and set up a chromium kiosk site or several + +The kiosk(s) are generated based on the variables. This is based on the kiosk I built for the road trip carputer pipeline, and here is an example of how to load two sites with this playbook. The reason for the presence of the user_data_dir variable is the need to create this folder. I now have ansible check if there are multiple objects in the variable and create the folder, but I still need the second variable for the task to create the folder because I don't want to parse the bigger variable. + +For some reason there is a problem with multiple windows and Wayland, it seems to ignore the placement. When the playbooks is ran with X11 enabled, the placement of the windows is correct. When the playbook is configured with Wayland, all chrome windows are centered. There is a variable to force X11 that can be manually set. I also set this to just use Chromium; it was origninally a troubleshooting step, but since this is a Kiosk, Chromium is lovely. It could always be put back to Chrome with just a few tasks. + +This role has two modes, and it matters which is used. It can be called from the Jenkins pipeline that uses a dynamic kiosk service file and just creates a chrome kiosk. It can be also called as another step in a bigger playbook using ansible variables. If I can figure out how to pass this ansible variable through jenkins another way I would, but since the variable contains newlines I'm not sure how to pass it through the shell command. Most of the time it will be used by another playbook, and the variables can be set in the role. + +Example kiosk.yaml file: + +``` +kiosk_service_templates: + + - chrome_website: "http://localhost:8081" + service_name: user_stream_control + service_description: "VCR Capture User Stream Control" + extra_service_configs: "" + user_data_dir: "/opt/chrome/one" + extra_chrome_configs: | + --window-size="560,1080" \ + --user-data-dir=/opt/chrome/one \ + - chrome_website: "http://localhost:8888/stream" + service_name: stream_preview + service_description: "VCR Capture Preview Stream" + extra_service_configs: "" + user_data_dir: "/opt/chrome/two" + extra_chrome_configs: | + --window-size="1350,1080" \ + --user-data-dir=/opt/chrome/two \ + --window-position="570,0" \ + +``` \ No newline at end of file diff --git a/defaults/main.yaml b/defaults/main.yaml new file mode 100644 index 0000000..0ecc770 --- /dev/null +++ b/defaults/main.yaml @@ -0,0 +1,44 @@ +--- + +# make sure to indent properly; use the | for the extra_ vars +# see the readme for fancier examples +kiosk_service_templates: + - chrome_website: "https://theregion.beer" + service_name: chrome_default + service_description: "Default Chrome Kiosk Service" + user_data_dir: "" + extra_service_configs: "" + extra_chrome_configs: "" + +# set to true when there are multiple pages +create_data_dir: false + +# this should probably not be changed +local_user: "cosmos" + +kiosk_packages: + - sddm + - kde-plasma-desktop + +kiosk_package_remove: + - plasma-welcome + - partitionmanager + - kwalletmanager + - kdeconnect + - kdeconnect-libs + - zutty + - firefox-esr + +sddm_method: "plasma" + +refresh_special: true + +browser_binary: "/usr/bin/google-chrome" + +force_x11: false + +kiosk_yaml: files/kiosk.yaml + +jenkins_kiosk: false + +... \ No newline at end of file diff --git a/files/kiosk.yaml b/files/kiosk.yaml new file mode 100644 index 0000000..21db9bc --- /dev/null +++ b/files/kiosk.yaml @@ -0,0 +1,22 @@ +``` +kiosk_service_templates: + + - chrome_website: "http://localhost:8081" + service_name: user_stream_control + service_description: "VCR Capture User Stream Control" + extra_service_configs: "" + user_data_dir: "/opt/chrome/one" + extra_chrome_configs: | + --window-size="560,1080" \ + --user-data-dir=/opt/chrome/one \ + - chrome_website: "http://localhost:8888/stream" + service_name: stream_preview + service_description: "VCR Capture Preview Stream" + extra_service_configs: "" + user_data_dir: "/opt/chrome/two" + extra_chrome_configs: | + --window-size="1350,1080" \ + --user-data-dir=/opt/chrome/two \ + --window-position="570,0" \ + +``` \ No newline at end of file diff --git a/tasks/autologin.yaml b/tasks/autologin.yaml new file mode 100644 index 0000000..f05d9a7 --- /dev/null +++ b/tasks/autologin.yaml @@ -0,0 +1,93 @@ +--- + +############################################### +# Install packages and set up autologin + +# Stop SDDM if running +- name: autologin - stop sddm + ignore_errors: yes + systemd: + name: sddm + state: stopped + +- name: autologin - purge user account + ignore_errors: yes + shell: "rm -R /home/{{ local_user }}" + +- name: Autologin - run once section + when: not refresh_special | bool + block: + + # Install Packages + - name: autologin - Install Packages + apt: + name: "{{ kiosk_package_items }}" + state: present + loop: "{{ kiosk_packages }}" + loop_control: + loop_var: kiosk_package_items + + # Remove Packages + - name: autologin - Remove Packages + apt: + name: "{{ kiosk_package_remove_items }}" + state: absent + loop: "{{ kiosk_package_remove }}" + loop_control: + loop_var: kiosk_package_remove_items + + # Set sddm as def + - name: autologin - enable sddm in xdm + debconf: + name: sddm + question: shared/default-x-display-manager + value: sddm + vtype: select + +# sddm_method, should always run +- name: Display cpu_architecture + debug: + msg: "cpu_architecture: {{ cpu_architecture }}" + +- name: check OS name + shell: cat /etc/os-release | grep VERSION_CODENAME | cut -d '=' -f 2 + register: debian_codename + +- name: Set sddm_method if needed + when: "'amd' in cpu_architecture and 'bookworm' in debian_codename.stdout" + set_fact: + sddm_method: "plasmawayland.desktop" + +- name: Set sddm_method for x11 + when: force_x11 | bool + set_fact: + sddm_method: "plasmax11" + +# Configure Autologin +- name: autologin - configure autologin et. al. + template: + src: sddm.conf + dest: /etc/sddm.conf + mode: 0644 + +- name: autologin - check sddm config + shell: cat /etc/sddm.conf + register: sddm_check +- debug: + msg: "{{ sddm_check.stdout_lines }}" + +############################################### +# Apply Profile in separate file to keep things tidy +# Create account and configure other settings like power and stuff + +- name: autologin - apply user profile settings + include_tasks: user_profile.yaml + +# Restart sddm to initialize user profile +- name: autologin - restart sddm + systemd: + enabled: yes + name: sddm + state: started + +... \ No newline at end of file diff --git a/tasks/chrome.yaml b/tasks/chrome.yaml new file mode 100644 index 0000000..e6a9c1c --- /dev/null +++ b/tasks/chrome.yaml @@ -0,0 +1,30 @@ +--- + +############################################### +# Install Chromium + +- name: chrome - Install Chromium + when: not refresh_special | bool + apt: + name: chromium + state: present + +- name: Chrome - fine chromium binary + shell: "find /usr/bin/chromium*" + register: find_chromium + +- name: Chrome - change var if chromium +# when: armcpu_check | bool + set_fact: + browser_binary: "{{ find_chromium.stdout_lines[0] }}" + +############################################### +# Configure Kiosks + +- name: Set up Chrome Kiosk Services + include_tasks: kiosk.yaml + loop: "{{ kiosk_service_templates }}" + loop_control: + loop_var: kiosk_service_items + +... \ No newline at end of file diff --git a/tasks/kiosk.yaml b/tasks/kiosk.yaml new file mode 100644 index 0000000..0b749c4 --- /dev/null +++ b/tasks/kiosk.yaml @@ -0,0 +1,50 @@ +--- +############################################### +# Chrome Kiosk Config +# intended to be called in a loop +############################################### + +- name: Chrome Kiosk - display kiosk_service_items + debug: + msg: "{{ kiosk_service_items }}" +# - "Chrome Kiosk Configuring: {{ kiosk_service_items.service_description }}" +# - "Kiosk Service Name: {{ kiosk_service_items.service_name }}" +# - "Kiosk Service Options:" +# - "{{ kiosk_service_items.extra_service_configs }}" +# - "Chrome Website: {{ kiosk_service_items.chrome_website }}" +# - "Chrome App Extra Configs:" +# - "{{ kiosk_service_items.extra_chrome_configs }}" + +# Create user data dir Folder +- name: Chrome Kiosk - create working folder + when: create_data_dir | bool + file: + path: "{{ kiosk_service_items.user_data_dir }}" + state: directory + mode: '0777' + owner: "{{ local_user }}" + group: "{{ local_user }}" + +- name: Chrome Kiosk - user stop service if running + command: "systemctl --user -M {{ local_user }}@ stop {{ kiosk_service_items.service_name }}.service" + ignore_errors: true + +- name: Chrome Kiosk - Copy chrome service file + template: + src: chrome-app.service + dest: "/home/{{ local_user }}/.config/systemd/user/{{ kiosk_service_items.service_name }}.service" + owner: "{{ local_user }}" + group: "{{ local_user }}" + mode: 0600 + +- name: Chrome Kiosk - user daemon reload + command: "systemctl --user -M {{ local_user }}@ daemon-reload" + register: user_daemon_reload + +- name: Chrome Kiosk - user enable service + command: "systemctl --user -M {{ local_user }}@ enable {{ kiosk_service_items.service_name }}.service" + +- name: Chrome Kiosk - user start service + command: "systemctl --user -M {{ local_user }}@ start {{ kiosk_service_items.service_name }}.service" + +... \ No newline at end of file diff --git a/tasks/main.yaml b/tasks/main.yaml new file mode 100644 index 0000000..98113c5 --- /dev/null +++ b/tasks/main.yaml @@ -0,0 +1,47 @@ +--- + +- name: check arch if needed + when: refresh_special | bool + block: + + - name: Video Capture - Check CPU Arch + shell: "dpkg --print-architecture" + register: cpu_architecture_output + + - name: Set cpu_architecture variable + set_fact: + cpu_architecture: "{{ cpu_architecture_output.stdout_lines[0] }}" + +- name: kiosk variable handler + block: + # when coming from jenkins overwrite the variable + - name: include jenkins vars + when: jenkins_kiosk | bool + block: + + - name: import jenkins var file + include_vars: + file: "{{ kiosk_yaml }}" + name: kiosk_vars + - debug: + msg: "{{ kiosk_vars.kiosk_service_templates }}" + + - name: overwrite kiosk_service_templates + set_fact: + kiosk_service_templates: "{{ kiosk_vars.kiosk_service_templates }}" + + - name: check if multiple and set create_data_dir, force_x11 accordingly + when: kiosk_service_templates | length > 1 + set_fact: + create_data_dir: true + force_x11: true + - debug: + msg: "{{ 'Multiple Services Requested, data directories will be created and X11 will be forced.' if kiosk_service_templates | length > 1 else 'Single page requested; no data directory and wayland may be used.' }}" + +- name: Autologin Setup + include_tasks: autologin.yaml + +- name: Install KDE + Kiosk Services + include_tasks: chrome.yaml + +... \ No newline at end of file diff --git a/tasks/user_profile.yaml b/tasks/user_profile.yaml new file mode 100644 index 0000000..f024acc --- /dev/null +++ b/tasks/user_profile.yaml @@ -0,0 +1,63 @@ +--- + +######################################## +# Apply KDE settings to user profile +######################################## + +#- name: autologin - create local user profile folder +# file: +# path: "/home/{{ local_user }}" +# owner: "{{ local_user }}" +# group: "{{ local_user }}" +# state: directory +# mode: '0700' + +- name: autologin - Create User Service Folder and parents + file: + path: "/home/{{ local_user }}/.config/systemd/user" + state: directory + owner: "{{ local_user }}" + group: "{{ local_user }}" + mode: '0700' + +- name: autologin - Disable kwallet + copy: + dest: "/home/{{ local_user }}/.config/kwalletrc" + content: | + [Wallet] + Enabled=false + owner: "{{ local_user }}" + group: "{{ local_user }}" + mode: '0700' + +- name: autologin - configure power options + copy: + dest: "/home/{{ local_user }}/.config/powerdevilrc" + content: | + [AC][Display] + DimDisplayIdleTimeoutSec=-1 + DimDisplayWhenIdle=false + TurnOffDisplayIdleTimeoutSec=-1 + TurnOffDisplayWhenIdle=false + + [AC][SuspendAndShutdown] + AutoSuspendAction=0 + LidAction=0 + PowerButtonAction=0 + owner: "{{ local_user }}" + group: "{{ local_user }}" + mode: '0700' + +- name: autologin - configure screen locking + copy: + dest: "/home/{{ local_user }}/.config/kscreenlockerrc" + content: | + [Daemon] + Autolock=false + LockOnResume=false + Timeout=0 + owner: "{{ local_user }}" + group: "{{ local_user }}" + mode: '0700' + +... \ No newline at end of file diff --git a/templates/chrome-app.service b/templates/chrome-app.service new file mode 100755 index 0000000..8c7b08d --- /dev/null +++ b/templates/chrome-app.service @@ -0,0 +1,25 @@ +[Unit] +Description={{ kiosk_service_items.service_description }} +After=sddm.service + + +[Service] +Restart=always +RestartSec=1s +ExecStartPre=/bin/sleep 5 +ExecStart={{ browser_binary }} \ +--disable-pinch \ +--disable-translate \ +--no-first-run \ +--ignore-ssl-errors \ +--disable-usb-keyboard-detect \ +--window-name {{ kiosk_service_items.service_description }} \ +--app="{{ kiosk_service_items.chrome_website }}" \ +{{ kiosk_service_items.extra_chrome_configs}} + + +{{ kiosk_service_items.extra_service_configs }} + +[Install] +WantedBy=graphical-session.target + diff --git a/templates/sddm.conf b/templates/sddm.conf new file mode 100644 index 0000000..b215f88 --- /dev/null +++ b/templates/sddm.conf @@ -0,0 +1,12 @@ +[Autologin] +User={{ local_user }} +Session={{ sddm_method }} + +[Theme] +Current=breeze-dark + +[Wayland] +EnableHiDPI=false + +[General] +GreeterEnvironment=QT_SCREEN_SCALE_FACTORS=2,QT_FONT_DPI=96 \ No newline at end of file