GNOME (GNU Network Object Model Environment) is probably the most used graphical environment in the Linux ecosystem, if only because all major Linux distributions such as Fedora, RHEL, Debian and Ubuntu ship with it as the default desktop. GNOME strives for simplicity and ease of use, and for this reason, not without some criticisms by a part of the Linux community, tends to be less customizable than other desktop environments such as KDE Plasma or XFCE. Instead of using plaintext configuration files, GNOME stores its settings in the dconf database, which can be manipulated using the “dconf-editor” GUI, or from the command line using the “dconf” utility.
In this tutorial we learn how to automate the configuration of GNOME using Ansible and specifically the community.general.dconf module, which allow us to read and write entries in the dconf database.
In this tutorial you will learn:
- How to install the community-general Ansible collection
- How to write a playbook to configure GNOME using Ansible
|Category||Requirements, Conventions or Software Version Used|
|Software||GNOME, Ansible, the python3 psutil library|
|Other||Administrative privileges to install packages globally, being familiar with Ansible basic concepts|
|Conventions||# – requires given linux-commands to be executed with root privileges either directly as a root user or by use of
$ – requires given linux-commands to be executed as a regular non-privileged user
We talked about Ansible in the past, and we saw how it is one of the most used and easy to learn provisioning systems on Linux: if something can be done from the command line there is probably an existing module which let us integrate it in the Ansible workflow, with all the advantages it provides.
To programmatically configure GNOME and easily replicate our setup everywhere GNOME is used, we can use the
community.general.dconfAnsible module, which is part of the
community-generalcollection. This module let us manage entries in the dconf database used by GNOME as a backend to store user preferences.
To use the
community.general.dconf module, we must install Ansible itself and the “community-general collection”, plus, we need to ensure the
psutil python3 library is installed on the target machine. Since the Ansible module works as a wrapper around the “dconf” utility, it goes by itself that the latter should also be available on the system we intend to configure; however, since it is usually part of any GNOME installation, we won’t explicitly install it here.
We can install the aforementioned requirements either by using our favorite distribution package manager, or, since Ansible itself is written in Python, by using
pip, the Python package manager. The former method provides the best possible integration of packages into the system; by using the latter, instead, we can control what version of a package is installed, being it the latest, or a specific one which perhaps we need for compatibility reasons. By using “pip” we can also install packages only for our unprivileged user, without the need of using “sudo” or other methods to escalate privileges.
Ansible can be generally installed using the “ansible-core” or the “ansible” packages. The former provides a barebone installation of just the provisioning system core and the “default” collection; the latter includes also some other useful community-maintained collections: “community-general” is among them. To install the packages on Fedora we can use use
$ sudo dnf install ansible python3-psutil
Ansible can also be installed on Archlinux, using
$ sudo pacman -S ansible python-psutil
On Debian and derivatives such as Ubuntu, we can use the following command to install Ansible together with the “psutil” Python library:
$ sudo apt-get update && sudo apt-get install ansible python3-psutil
Universal installation using pip
As we previously said, if we decide to use
pip to install the packages, we don’t need to use privilege escalation. To perform the installation only for our user (and eventually in a Python virtual environment), we can run:
$ pip install ansible psutil
Using the community.general.dconf module
The module which allow us to manage entries in the dconf database is
community.general.dconf, which is basically a wrapper around the dconf utility. Here comes some examples of how we can use it to change some settings. In the following playbook I consider the machine where the GNOME instance we want to configure is installed to be also the Ansible control node:
- name: Configure GNOME hosts: localhost tasks: - name: Enable touchpad tap-to-click community.general.dconf: key: /org/gnome/desktop/peripherals/touchpad/tap-to-click value: 'true' - name: Disable event sounds community.general.dconf: key: /org/gnome/desktop/sound/event-sounds value: 'false' - name: Setup text editor community.general.dconf: key: /org/gnome/TextEditor/indent-style value: "'space'"
In the example above we created three tasks: the first is used to enable the touchpad tap-to-click; with the second we disable the (quite annoying) GNOME event sounds, and with the the third we specify we want to use spaces instead of tabs for indentation in the GNOME text editor.
The “community.general.dconf” module basically accepts three parameters:
The key parameter is the path of the a key in the dconf database. At this point you may ask: “how can I know the path of the key corresponding to the option I want to change?” The most practical way to discover it, is by taking a look at the content of the dconf database by using the
dconf utility directly (perhaps piping the output to grep, in order to filter some keywords), which can be obtained by running:
$ dconf dump /
The value parameter represents the value we want to assign to the dconf key. A very important thing to remember is that the value must be specified in the “GVariant” format. A strategy which can be adopted here is to first change the desired setting manually, than take a look at the value that is written in the dconf database and report it in the task. Normally if a value is reported between single quotes in the database, the quotes themselves must be considered part of it, therefore must be enclosed in double-quotes in the ansible playbook (for instance, in the example above ‘space’ is reported as “‘space'”, and true as ‘true’).
The last parameter accepted by the module is “state”, which can be set to one among “present”, “absent” or “read”. By default it is set to “present”, therefore this parameter can be omitted if we want to write an entry. We can set it to “absent” if we want to ensure an entry doesn’t exist in the database, or to “read” in order to retrieve the value of a key.
Assuming we saved the playbook as “gnome.yml” in our current working directory, we can “execute” them by running:
$ ansible-playbook gnome.yml
In this tutorial we saw how to use Ansible to easily automate the configuration of the GNOME desktop environment on Linux, by writing keys and values corresponding to the settings we want to change into the dconf database.