15

My Ansible Role for GNOME

 1 year ago
source link: https://www.lorenzobettini.it/2023/11/my-ansible-role-for-gnome/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

My Ansible Role for GNOME

I have already started blogging about Ansible; in particular, I have shown how to develop and test an Ansible role with Molecule and Docker, also on Gitpod.

This blog post will describe my Ansible role for installing the GNOME desktop environment with several programs and configurations. As for the other roles I’ve blogged about, this one is tested with Molecule and Docker and can be developed with Gitpod (see the linked posts above). In particular, it is tested in Arch, Ubuntu, and Fedora.

This role is for my personal installation and configuration and is not meant to be reusable.

The role can be found here: https://github.com/LorenzoBettini/my_gnome_role.

The role assumes that at least the basic GNOME DE is already installed in the Linux distribution. The role then installs several programs I’m using on a daily basis and performs a few configurations (it also installs a few extensions I use).

At the time of writing, the role has the following directory structure, which is standard for Ansible roles tested with Molecule.

├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── LICENSE
├── meta
│   └── main.yml
├── molecule
│   ├── default
│   │   ├── molecule.yml
│   │   └── prepare.yml
│   ├── fedora
│   │   └── molecule.yml
│   ├── no-flatpak
│   │   ├── converge.yml
│   │   ├── molecule.yml
│   │   └── verify.yml
│   ├── shared
│   │   ├── converge.yml
│   │   └── verify.yml
│   └── ubuntu
│       ├── molecule.yml
│       └── prepare.yml
├── pip
│   └── requirements.txt
├── README.md
├── requirements.yml
├── tasks
│   ├── flatpak.yml
│   ├── gnome-arch.yml
│   ├── gnome-configurations.yml
│   ├── gnome-extension-manager.yml
│   ├── gnome-extensions.yml
│   ├── gnome-templates.yml
│   ├── gnome-tracker.yml
│   ├── guake.yml
│   └── main.yml
├── templates
├── tests
│   ├── inventory
│   └── test.yml
└── vars
    └── main.yml

The role has a few requirements, listed in “requirements.yml”:

roles:
  - name: petermosmans.customize-gnome
    version: 0.2.10
collections:
  - name: community.general

These requirements must also be present in playbooks using this role; my playbooks (which I’ll write about in future articles) have such dependencies in the requirements.

The main file “tasks/main.yml” is as follows:

# tasks file for my_gnome_role
- name: System details
  ansible.builtin.debug:
    msg: "{{ item }}"
  with_items:
  - "ansible_os_family: {{ ansible_os_family }}"
  - "ansible_distribution: {{ ansible_distribution }}"
  - "ansible_distribution_release: {{ ansible_distribution_release }}"
  - "ansible_distribution_version: {{ ansible_distribution_version }}"
  - "ansible_distribution_major_version: {{ ansible_distribution_major_version }}"
- name: Install Gnome Packages
  become: true
  ansible.builtin.package:
    state: present
    name:
    - gnome-shell
    - gnome-tweaks
    - dconf-editor
    - xdg-utils # required for xdg-mime below
    - gnome-screenshot # the original screenshot application
    - baobab
    - deja-dup
    - evince
    - evolution
    - file-roller
    - gnome-backgrounds
    - gnome-calculator
    - gnome-calendar
    - gnome-contacts
    - gnome-logs
    - gnome-photos
    - gnome-remote-desktop
    - gnome-system-monitor
    - gnome-text-editor
    - gnome-weather
    - simple-scan
    - gvfs
- name: Override python-psutil package name for Arch.
  ansible.builtin.set_fact:
    python_psutil: python-psutil
  when: ansible_os_family == 'Archlinux'
- name: Install Python psutil
  become: true
  ansible.builtin.package:
    state: present
    name: "{{ python_psutil }}"
- name: Tasks for Guake Drop-down Terminal
  ansible.builtin.include_tasks: guake.yml
- name: Tasks for ArchLinux
  ansible.builtin.include_tasks: gnome-arch.yml
  when: ansible_os_family == 'Archlinux'
- name: Tasks for Template files
  ansible.builtin.include_tasks: gnome-templates.yml
- name: Tasks for Gnome Tracker
  ansible.builtin.include_tasks: gnome-tracker.yml
- name: Tasks for Gnome configuration
  ansible.builtin.include_tasks: gnome-configurations.yml
- name: Tasks for Gnome extensions
  ansible.builtin.include_tasks: gnome-extensions.yml
- name: Tasks for Flatpak
  ansible.builtin.include_tasks: flatpak.yml
  when: with_flatpak
- name: Tasks for Gnome Extension Manager
  ansible.builtin.include_tasks: gnome-extension-manager.yml
  when: with_flatpak

This shows a few debug information about the current Linux distribution. Indeed, the whole role has conditional tasks and variables depending on the current Linux distribution.

The file installs a few programs, mainly Gnome programs, but also other programs I’m using in GNOME.

The “vars/main.yml” only defines a few default variables used above:

# vars file for my_gnome_role
python_psutil: python3-psutil
with_flatpak: true

As seen above, the package for “python psutils” has a different name in Arch, and it is overridden.

For Arch, we have to install a few additional packages, which are not required in the other distributions (file “gnome-arch.yml”):

- name: Install Gnome Packages (Arch Linux)
  become: true
  ansible.builtin.package:
    state: present
    name:
    - gvfs-afc
    - gvfs-goa
    - gvfs-google
    - gvfs-gphoto2
    - gvfs-mtp
    - gvfs-nfs
    - gvfs-smb

For the Guake dropdown terminal, we install it (see the corresponding YAML file).

The file “gnome-templates.yml” creates the template for “New File”, which, otherwise, would not be available in recent versions of GNOME, at least in the distributions I’m using.

- name: Create Templates directory
  ansible.builtin.file:
    path: '~/Templates'
    state: directory
    mode: 0755
- name: Create Templates
  ansible.builtin.copy:
    content: ""
    dest: '~/Templates/New File'
    mode: 0644

For the search engine GNOME Tracker, I performed a few configurations concerning the exclusion mechanisms. This is done by using the Community “dconf” module:

# the default was ['.trackerignore', '.git', '.hg', '.nomedia']
# but that way the contents of a git working directory are not indexed
- name: Customize Tracker Ignored directories with content
  community.general.dconf:
    key: "/org/freedesktop/tracker/miner/files/ignored-directories-with-content"
    value: "['.trackerignore', '.hg', '.nomedia']"
    state: present
- name: Customize Tracker Ignored directories
  community.general.dconf:
    key: "/org/freedesktop/tracker/miner/files/ignored-directories"
    value: "['po', 'CVS', 'core-dumps', 'lost+found', 'bin', 'test-bin', 'bin-test', 'target', 'xtend-gen', 'src-gen', 'cache', 'node_modules', 'node_packages', 'thunderbird']"
    state: present
- name: Make sure Tracker 3 is installed (Arch)
  become: true
  ansible.builtin.package:
    state: present
    name:
    - tracker3
    - tracker3-miners
  when: ansible_os_family == 'Archlinux'
- name: Make sure Tracker 2 is NOT installed (Arch)
  become: true
  ansible.builtin.package:
    state: absent
    name:
    - tracker
    - tracker-miners
  when: ansible_os_family == 'Archlinux'
# In previous versions of ubuntu the service file was
# tracker-extract.service
# In more recent versions is
# tracker-extract-3.service
- name: Disable Tracker Extract at system level
  ansible.builtin.systemd:
    name: tracker-extract-3
    scope: global
    masked: yes
# Better to mask it at the global level
# so that it can be run also in a chroot environment
# otherwise we get "Failed to connect to bus: No such file or directory"

This also ensures that possibly previous versions of Tracker are not installed. Moreover, while I use Tracker to quickly look for files (e.g., with the GNOME Activities search bar), I don’t want to use “Tracker extract”, which also indexes file contents. For indexing file contents, I prefer “Recoll”, which is installed and configured in my dedicated playbooks for specific Linux distributions (I’ll blog about them in the future).

Then, the file “gnome-configurations.yml” configures a few aspects (the comments should be self-documented), including some custom keyboard shortcuts (including the one for Guake, which, in Wayland, must be set explicitly as a GNOME shortcut):

- name: Enable minimize and maximize
  community.general.dconf:
    key: "/org/gnome/desktop/wm/preferences/button-layout"
    value: "'appmenu:minimize,maximize,close'"
- name: Terminal transparency
  community.general.dconf:
    key: "/org/gnome/terminal/legacy/profiles:/:b1dcc9dd-5262-4d8d-a863-c897e6d979b9/use-transparent-background"
    value: "true"
- name: Terminal transparency percentage
  community.general.dconf:
    key: "/org/gnome/terminal/legacy/profiles:/:b1dcc9dd-5262-4d8d-a863-c897e6d979b9/background-transparency-percent"
    value: "5"
- name: Ctrl+Alt+Up reserved for Eclipse
  community.general.dconf:
    key: "/org/gnome/desktop/wm/keybindings/switch-to-workspace-up"
    value: "['<Super>Page_Up']"
- name: Ctrl+Alt+Down reserved for Eclipse
  community.general.dconf:
    key: "/org/gnome/desktop/wm/keybindings/switch-to-workspace-down"
    value: "['<Super>Page_Down']"
- name: Super+d Show Desktop
  community.general.dconf:
    key: "/org/gnome/desktop/wm/keybindings/show-desktop"
    value: "['<Super>d']"
# Custom shortcuts:
#   For each shortcut, define a name, a command, and a binding.
- name: Maximized terminal shortcut <Super>t"
  community.general.dconf:
    key: "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/name"
    value: "'terminal'"
- name: Terminal shortcut command
  community.general.dconf:
    key: "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/command"
    value: "'gnome-terminal --maximize'"
- name: Terminal shortcut binding
  community.general.dconf:
    key: "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/binding"
    value: "'<Super>t'"
- name: Terminal shortcut Ctrl+Alt+t"
  community.general.dconf:
    key: "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/name"
    value: "'terminal'"
- name: Terminal shortcut command
  community.general.dconf:
    key: "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/command"
    value: "'gnome-terminal'"
- name: Terminal shortcut binding
  community.general.dconf:
    key: "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/binding"
    value: "'<Primary><Alt>t'"
- name: Guake shortcut F12 for Wayland"
  community.general.dconf:
    key: "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/guake/name"
    value: "'guake'"
- name: Guake shortcut command
  community.general.dconf:
    key: "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/guake/command"
    value: "'guake-toggle'"
- name: Guake shortcut binding
  community.general.dconf:
    key: "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/guake/binding"
    value: "'F12'"
# All custom shortcuts must also be added to an array.
- name: Enable custom keybindings
  community.general.dconf:
    key: "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings"
    value: "['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/', '/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/', '/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/guake/']"

Then, by using the “petermosmans.customize-gnome” role (see the requirements file above), I install a few GNOME extensions, which are specified by their identifiers (these can be found on the GNOME extensions website). I leave a few of them commented out, since I don’t use them anymore, but I might need them in the future):

# Required for unzipping extension archives
- name: Install Unzip
  become: true
  ansible.builtin.package:
    state: present
    name:
    - unzip
# Downloading extensions is very flaky, so if it succeeds on 'converge'
# we skip it on 'idempotence'
- name: Install Gnome Extensions
  ansible.builtin.include_role:
    name: petermosmans.customize-gnome
  tags: molecule-idempotence-notest
  vars:
    gnome_extensions:
      - id: 19 # User Theme "[email protected]"
      - id: 615 # AppIndicator and KStatusNotifierItem Support
      - id: 3740 # Magic Lamp "[email protected]"
      - id: 307 # dash-to-dock "[email protected]"
      - id: 973 # switcher "[email protected]"
      - id: 779 # clipboard-indicator
      - id: 1112 # screenshot-tool
      - id: 3088 # extension-list
      - id: 7 # removable-drive-menu
      - id: 97 # Coverflow Alt-Tab
      # - id: 16 # Auto Move Windows
      # - id: 10 # windowNavigator
      # - id: 5004 # dash-to-dock-for-cosmic
      # - id: 2890 # Tray Icons: Reloaded, works with Dropbox in Gnome 42!
      # - id: 120 # system-monitor
      # - id: 3843 # just-perfection
      # - id: 4033 # x11-gestures "[email protected]" requires touchegg

Then, we have the files for installing and configuring Flatpak, which I use only to install the GNOME Extension manager:

- name: Install Flatpak
  become: true
  ansible.builtin.package:
    state: present
    name:
    - flatpak
- name: Add the flathub flatpak repository remote
  become: true
  community.general.flatpak_remote:
    name: flathub
    state: present
    flatpakrepo_url: https://dl.flathub.org/repo/flathub.flatpakrepo
#    method: user
# To remove the filters on flathub introduced by Fedora
# see https://ask.fedoraproject.org/t/ansible-flathub-repo-setup/19176
# see https://fedoraproject.org/wiki/Changes/Filtered_Flathub_Applications
- name: Remove filters from flathub
  become: true
  ansible.builtin.command:
    cmd: flatpak remote-modify --no-filter flathub
  changed_when: false
- name: Install Gnome Extension Manager
  become: true
  community.general.flatpak:
    name: com.mattjakeman.ExtensionManager
    state: present
#    method: user

I installed them system-wide (the “user” option is commented out).

Concerning Molecule, I have several scenarios. As I said, I tested this role in Arch, Ubuntu, and Fedora, so I have a scenario for each operating system. The “default” scenario is Arch, which nowadays is my daily driver.

For Ubuntu, we have a “prepare.yml” file:

- name: Prepare
  hosts: all
  gather_facts: false
  tasks:
    - name: Install python in Ubuntu
      ansible.builtin.raw: apt update && apt install -y --no-install-recommends python3 sudo
      changed_when: false

The reason why is explained in my previous posts on Ansible and Molecule.

By default, I test that “flatpak” is installed. (see the default variables above: by default, Flatpak is installed)

# This is an example playbook to execute Ansible tests.
- name: Verify
  hosts: all
  gather_facts: false
  tasks:
  - name: Assert flatpak is installed in this scenario
    ansible.builtin.shell: >
      flatpak --version
    changed_when: false

But I also have a scenario (in Arch) where I run the role without Flatpak:

- name: Converge
  hosts: all
  tasks:
    - name: "Include lorenzobettini.my_gnome_role"
      ansible.builtin.include_role:
        name: "lorenzobettini.my_gnome_role"
      vars:
        with_flatpak: false

For this scenario, the “verify.yml” verifies Flatpak is not installed:

# This is an example playbook to execute Ansible tests.
- name: Verify
  hosts: all
  gather_facts: false
  tasks:
  - name: Assert flatpak is NOT installed in this scenario
    ansible.builtin.shell: >
      flatpak --version
    register: flatpak_cmd
    failed_when: flatpak_cmd.rc == 0
    changed_when: false

Of course, this is tested on GitHub Actions and can be developed directly on the web IDE Gitpod.

I hope you find this post useful for inspiration on how to use Ansible to automatize your Linux installations 🙂

Like this:

Loading...

Related


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK