Nowadays, I mostly use Arch-based distributions (especially with EndeavourOS). So I haven’t been using Ubuntu for a while and decided to try it again now that the brand new release, 23.10 “Mantic Minotaur”, is available.
Let’s start the installation. This new version of Ubuntu features a new installer, which looks nice. I still feel comfortable with this new installer having already installed Ubuntu many times.
The initial steps are the language, keyboard, and network connection:
In the next step, the installer detected a new version available to download. I said yes. Then, you have to restart the installer, starting from scratch.
By default, Ubuntu proposes a minimal installation when choosing the installation type. However, I prefer to have most of the things installed during this stage, so I chose the “Full Installation”:
Then, we get to the partitioning. As usual, I prefer manual partitioning since I have several Linux distributions installed on my computer. I chose EXT4 as the file system. On Arch, I use BTRFS. However, Ubuntu does not come with good defaults for BTRFS. I dealt with such problems in the past, but now I prefer to stick with EXT4 in Ubuntu and give up on BTRFS snapshots.
Then, we get to the timezone selection (the installer automatically detected my location) and user details. This is as usual.
Interestingly, you can select during the installation the theme and the color accent (that’s nothing special, but it is a nice surprise):
The installation starts; by clicking on the small icon on the bottom right, you can also enable logging on the terminal:
The installation only took a few minutes on this laptop.
Time to restart. Of course, at the first login, you get some updates to install:
The touchpad is already configured with tap-to-click, but it defaults to “natural scrolling” (which I don’t like). That gave me the chance to see the new nice-looking Gnome setting for the touchpad:
I installed Dropbox, and with the Ubuntu extension for “app indicator”, the Dropbox icon appears in the tray bar. It works (mostly: sometimes it always shows as if it is synchronizing, though everything is up-to-date).
Remember that the current icon theme does not show the “Dropbox” folder in Nautilus with overlay.
Connecting an external HDMI monitor works perfectly (so Wayland is not a problem); I prefer to mirror the contents:
Also, GNOME extensions work fine. Despite the new GNOME Version (45), known to have broken all extensions due to an API breakage, the ones I use seem to have been ported and work correctly.
I don’t like the fact that, despite a SWAP partition already present on my disk, the installer did not pick it up: the result is the usage of a small SWAP file, which I don’t like.
1
.rw-------4.3Groot4Nov18:06swap.img
I removed this line from the “/etc/fstab”:
1
/swap.img none swap sw00
I added the line to refer to my existing SWAP partition.
I also enabled ZRAM, which will automatically have precedence over the SWAP partition:
1
2
sudo apt install systemd-zram-generator
sudo systemctl daemon-reload
1
2
3
4
❯swapon
NAME TYPE SIZE USED PRIO
/dev/nvme0n1p4 partition21G2M-2
/dev/zram0 partition4G0B100
I don’t like the wallpapers shipped with this version (in the screenshot, you can easily tell the GNOME wallpapers from the Ubuntu ones):
However, I typically use Variety for wallpapers, so it’s not a big problem.
IMPORTANT: as I have already blogged, you need additional fonts for “Oh-My-Zsh” with the “p10k” prompt.
All in all, Ubuntu 23.10 seems pretty stable and smooth. I’m using it (not as my daily driver), and for the moment, I’m enjoying it.
Here’s another post on how to get started with Hyprland.
This time, we’ll see how to configure notifications with mako, a lightweight notification daemon for Wayland, which also works with Hyprland. (you might also want to consider and experiment with an alternative: dunst).
If you followed my previous tutorials, you have no notification daemon installed. You can verify that by running the following command (to issue a notification manually) and by looking at the resulting errors:
1
2
$ notify-send "hello"
GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name org.freedesktop.Notifications was not provided by any .service files
Let’s install “mako”:
1
sudo pacman-Smako
The nice thing about mako is that you don’t need to start it as a service manually: the first time a notification is emitted, mako will run automatically.
Let’s try to run the above notification command above, and this time, we see the pop-up, by default, on the right top corner of the screen:
You have to click the pop-up to make it disappear.
Each time a program emits a notification, mako will show it. For example, Thunderbird, Firefox, and Chrome will emit notifications that mako will display.
Let’s do some further experiments by manually emitting notifications:
1
notify-send"hello world\!""This is a message"
will lead to
You can see that the first argument is the title and formatted in boldface.
You can have a look at mako’s manual (5) about its configuration file and where it is searched for:
1
2
3
4
5
6
7
8
9
10
11
12
man 5 mako
NAME
mako - configuration file
DESCRIPTION
The config file is located at <strong>~/.config/mako/config</strong> or at $XDG_CON‐
FIG_HOME/mako/config. Option lines can be specified to configure mako like so:
key=value
Empty lines and lines that begin with # are ignored.
Each time you modify the configuration, you must reload mako by using one of the following commands:
1
killall mako
or
1
makoctl reload
With that example configuration, we can emit a few notifications with different “urgencies”, and see the different colors and positions of the boxes:
1
2
3
4
5
6
7
notify-send-ulow"hello world\!""This is a low urgency message"
notify-send-unormal"hello world\!""This is a normal message"
notify-send-ucritical\
"This is a critical message\!"\
"OK, that was just a demo ;)"
If you use EndeavourOS, you will get notifications about new updates and when a reboot is required after a system update (the latter is a “critical” notification):
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 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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
├── 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”:
YAML
1
2
3
4
5
6
7
---
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.
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:
YAML
1
2
3
4
---
# 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”):
YAML
1
2
3
4
5
6
7
8
9
10
11
12
13
---
- 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.
YAML
1
2
3
4
5
6
7
8
9
10
11
- 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:
YAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 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
- 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 "Failedtoconnecttobus: 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):
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):
YAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 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 "user-theme@gnome-shell-extensions.gcampax.github.com"
- id: 615 # AppIndicator and KStatusNotifierItem Support
# 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
YAML
1
2
3
4
5
6
- 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.
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)
YAML
1
2
3
4
5
6
7
8
9
10
11
---
# 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:
YAML
1
2
3
4
5
6
7
8
9
---
- 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:
YAML
1
2
3
4
5
6
7
8
9
10
11
12
13
---
# 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 🙂
We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “Accept All”, you consent to the use of ALL the cookies. However, you may visit "Cookie Settings" to provide a controlled consent.
This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary cookies are absolutely essential for the website to function properly. These cookies ensure basic functionalities and security features of the website, anonymously.
Cookie
Duration
Description
cookielawinfo-checkbox-analytics
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Analytics".
cookielawinfo-checkbox-functional
11 months
The cookie is set by GDPR cookie consent to record the user consent for the cookies in the category "Functional".
cookielawinfo-checkbox-necessary
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookies is used to store the user consent for the cookies in the category "Necessary".
cookielawinfo-checkbox-others
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Other.
cookielawinfo-checkbox-performance
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Performance".
viewed_cookie_policy
11 months
The cookie is set by the GDPR Cookie Consent plugin and is used to store whether or not user has consented to the use of cookies. It does not store any personal data.
Functional cookies help to perform certain functionalities like sharing the content of the website on social media platforms, collect feedbacks, and other third-party features.
Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.
Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics the number of visitors, bounce rate, traffic source, etc.
Advertisement cookies are used to provide visitors with relevant ads and marketing campaigns. These cookies track visitors across websites and collect information to provide customized ads.