Monthly Archives: January 2023

Installing Amarok on Arch Linux

I have always liked Amarok, the (initially) default KDE media player. It’s very feature-rich, nothing compared to Elisa. Moreover, it has two crucial features that I haven’t found in any other players:

  • it saves statistics (play count and stars) directly into the music file
  • it synchronizes statistics with iPod

Unfortunately, while still maintained, you won’t find pre-built packages in mainstream distributions (e.g., Ubuntu). Thus, you must install that from sources, which is problematic. However, for Arch Linux, there’s an AUR package, which takes care of the compilation and, most of all, its dependencies.

In this blog post, I’ll summarize the steps for installing Amarok to access iPods (I still have an iPod classic).

First, you need to install the Phonon backend required by Amarok:

If you want to use Amarok with an iPod, you must first install

IMPORTANT: the iPod library (this must be present when Amarok is compiled from sources; if you forget about that, you’ll need to recompile Amarok, e.g., by specifying “–rebuild” as a command line argument to the AUR helper):

Then, we’re ready to install (i.e., compile from sources) Amarok from the AUR repository (I’m using the “yay” AUR helper here, but if you use another one, use your preferred one):

Now be patient: it will take several minutes for the compilation to finish (about 20 minutes on a decent machine)!

If you’re on KDE, you can now enjoy Amarok.

If you’re on GNOME, there’s still something to fix. In particular, you’ll see Amarok lacks lots of icons:

You need to install Breeze icons:

And now you can also enjoy icons:

Concerning the iPod: first, you have to mount it, and then you start Amarok so that Amarok can see the mounted iPod.

Enjoy your music! πŸ™‚

Docker on macOS M1

Although I’m a Linux user, I also recently bought a Mac Air M1, and I wanted to use Docker (a big part of my TDD book) to ensure that my projects based on Docker work on m1 as well.

I then went to the Docker website for macOSΒ and downloaded the version for the Apple m1 chip:

Then, I continued with the installation:

Let’s start it. Although m1 is fast, starting Docker Desktop takes some time.

Although I’m already familiar with Docker (on Linux), I decided to follow the “getting started” tutorial, which is well done:

At least, I’m sure that Docker is working on this machine.

The desktop app is well done, with a few sections to inspect Images, Containers, etc.

And, of course, there’s the “Preferences” section. For the moment, I stick with the defaults.

From the terminal, I ran the usual “hello-world” image:

I also tried to run a Ubuntu container.Β Inside the container, I verified that it’s running an “aarch64” version instead of the x86 one (“amd64”).

I also installed “file” to verify that it’s using aarch64 binaries (“arm64”):

From the Desktop application, you can quickly enter a container with a terminal:

Now, it’s time to verify that my Java projects based on Docker work as expected.

Java & Maven

This is a simple Maven example (a pom.xml file) that uses the https://github.com/fabric8io/docker-maven-plugin to start and stop a MySql container:

Run “mvn docker:start” to start a MySql container with a random mapped port. The command will wait for the container to be ready (it looks for a “ready” string within 20 seconds). After the command succeeds, the container will be running in the background.Β Run “mvn docker:stop” to stop the started container.

To avoid errors in this shape:

You need a recent version of the https://github.com/fabric8io/docker-maven-plugin. For example, 0.38.1. It also works with the current latest version, 0.40.2.

Actually, the first time I tried this project, it did not work (not because of the above error), but after a recent update, it started to work, maybe because of this added link:

Note that not all the images are available for this architecture “aarch64”. For example, if you try to use this older version of “mysql”, you get this error:

However, you can force the intel architecture for an image, as documented here https://docs.docker.com/engine/reference/commandline/run/, e.g., with this environment variable correctly set:

For example, for the above Maven project:

If you now enter the container, you can verify that you’re running an x86_64 image:

However, such images will run slower because they are emulated:

Testcontainers

I also use Testcontainers to start Docker containers from the JUnit tests in my projects.

For example, I’m using this example from my TDD book,Β https://github.com/LorenzoBettini/it-docker-mongo-example, and itΒ works out of the box.

Eclipse Docker Tooling

Currently, the Eclipse plugin for Docker, Docker Tooling, does not work: it cannot connect to Docker. This has been reported (https://github.com/eclipse-linuxtools/org.eclipse.linuxtools/issues/61), and a patch is available to make it work: follow the instructions detailed here https://github.com/eclipse-linuxtools/org.eclipse.linuxtools/issues/61#issuecomment-1326838270. I tested it, and it works:

To summarize, using Docker on macOS m1 seems to work fine! πŸ™‚

Installing Arch Linux the (not so) hard way

After using EndeavourOS, an Arch-based distro, for some time with much pleasure and appreciating Arch mechanisms (packages and AUR), I decided it was time to try the “real thing” and install Arch the “hard way” πŸ™‚ Spoiler: it’s not that hard!

I thought it was hard. For sure, it’s more complicated than other distro installation procedures, but, to be honest, after using Linux for more than 20 years, I thought there was not much to be scared of πŸ˜‰

I now use Arch (besides other distros) on my machines greatly. Of course, I did many experiments with virtual machines before installing Arch on bare metal. I know there are many guides and tutorials, but I’d like to summarize my steps for installing Arch (with a SWAP partition, an EXT4 partition for data to be shared among distros, and a BTRFS primary partition). In particular, in this blog post, I’ll describe my steps for installing Arch on a virtual machine, which, as I’ve just said, it’s the best way to get confident with Arch and not be scared of installing Arch on a real computer. Moreover, on many guides, I noticed a few missing points, which, instead, are essential.

Of course, the best reference is the excellent official guide, and I’ll use the official guide as a reference while following along, https://wiki.archlinux.org/title/installation_guide. Note that there are still a few parts in the guide that refer to other parts of the excellent Arch wiki, and I had a few minor problems the first time I tried the Arch installation.

Here we go!

Create and configure the virtual machine with enough disk space (dynamically allocated so you won’t waste space on your disk), let’s say 100Gb. Make sure you enable EFI in the virtual machine configuration. Of course, insert the Arch Linux ISO as a live CD in the virtual machine. I’m going to use archlinux-2022.09.03-x86_64.iso.

As described in a previous post, I’d suggest performing the installation by connecting via SSH to the virtual machine. This way, you’re using a local terminal: copy and paste will work (since you’re on a local terminal). In particular, since the Arch installer is textual, being able to copy and paste commands from a local terminal makes everything easier. Moreover, the keyboard layout will be the host system’s keyboard layout. Thus, the keyboard layout will be already configured correctly. While in the virtual machine, you’d have to configure the keyboard layout.

(On a side note, even when installing Arch on a real computer, I prefer doing that via SSH, of course, from another computer.)

Before starting the virtual machine, we must map the SSH port of the virtual machine to a local port to connect from our computer. This requires knowing the name you gave to your virtual machine. In this example, I called the virtual machine “Arch Gnome” (because I’ll then install Gnome on the Arch installation). We must run these instructions from the host computer:

Port 2522 is the one we’ll have to use later for connecting to the virtual machine via localhost. Of course, feel free to use another free port number as long as you’ll use it consistently from now on.

Start the virtual machine:

Inside the live environment, the SSH server is already up and running. However, since we’ll connect with the root account (the only one present), we must give the root account a password. By default, it’s empty, and SSH will not allow you to log in with a blank password. Choose a password. This password is temporary, and if you’re in a trusted local network, you can choose an easy one.

Now, we can connect via SSH to the virtual machine through localhost. if you have already connected via SSH to localhost, you might get an error of the shape:

All you have to do is edit the known_hosts file by removing the offending lines and try again. You will have to remove all the lines that start with “[127.0.0.1]:2522”.

Note that we’re using port 2522 because we previously used that for creating the port mapping. Let’s connect to the virtual machine and type the password we have previously specified for the root account inside the virtual machine (Accept the fingerprint when asked.):

In your local terminal, you see that you get the colors of the virtual machine (now, you’re inside the virtual machine):

Let’s set the console keyboard layout (the default layout is US; if that’s fine with you, skip the next step). This step is not strictly required for our local terminal: even if we’re inside the virtual machine, we’re using our local terminal, so we already use the correct layout. However, let’s do that anyway since we want to simulate an actual installation. Moreover, having the proper layout is good if we want to run commands directly from the VirtualBox window.

I already know the layout I want for my Italian keyboard, so I run:

If you don’t know the exact layout, you can list the available ones with

You can verify in the VirtualBox window that the layout is applied correctly.

Since we are in a virtual machine, the machine should already be able to access the Internet if your host is correctly connected (and that’s required to install Arch Linux). However, if you want to simulate what you would do with an actual installation on bare metal, you can ping a remote host and verify that everything’s OK:

Before going on, as suggested in the official guide, it’s better to make sure the system clock is accurate by enabling network synchronization NTP:

Partitioning the disk

How to partition the disk is your choice. In this example, I will partition the disk according to my needs. However, you need at least two partitions: one for booting in UEFI mode and one for the root filesystem.

In this example, I’ll create four partitions:

  • the one for booting in UEFI mode, formatted as FAT32, 300Mb (it should be enough for UEFI, but if unsure, go on with 512Mb)
  • a swap partition, 20Gb (I have 16Gb, and if I want to enable hibernation, i.e., suspend to disk, that should be enough)
  • a partition meant to host common data that I want to share among several Linux installations on the same machine (maybe I’ll blog about that in the future), formatted as EXT4, 30Gb
  • the root partition, formatted as BTRFS, the rest of the disk

To do that, I’m using cfdisk, a textual partition manager, which I find easy to use.

Now, it is time to get to know the device name of our disk using the command lsblk:

As you might guess, sda is the disk we are installing Arch Linux upon. In a virtual machine, that’s probably always like that. On a real machine, it might be different (for example, if you have an NVME SSD, it will be something like nvme0n1). It’s needless to say that using the correct device name is crucial, especially on a real machine, or you might end up wiping away essential data. The nice thing about a virtual machine is that you’re in a “sandbox,” so, at worst, you’ll break your virtual machine.

So I run

If it is a new virtual machine, you’ll be asked a partition table: choose gpt.

Start creating your partitions. Just use the menus of cfdisk; it’s easy (on the bottom, you will find some help). Once you create a partition, set the “Type” correctly. By default, the type is “Linux filesystem”. For UEFI, you have to specify the type “EFI System,” and for the swap partition, “Linux swap”.

That’s my final result:

Let’s “Write” the partition table to disk and “Quit”. We can also verify with lsblk that the result is as expected:

Of course, you must know which partition is meant for what. In my example, sda1 is for UEFI, sda2 for swap, sda3 for my shared data, and sda4 for root.

Format the partitions

According to my intended layout shown above, I’ll format the four partitions with the following commands:

Mount the partitions

This is also delicate, so you must use the correct device names. What follows is, of course, correct according to my layout.

First of all, let’s deal with the swap partition:

The presence of the BTRFS file system for the root partition makes things a bit more interesting (or a bit more complicated, as you prefer πŸ˜‰

First, we must mount the BTRFS filesystem on /mnt. Note that we are mounting the BTRFS on /mnt only temporarily and to create the subvolumes (in a minute, we will mount the subvolumes in their final shape on /mnt, together with the other partitions):

This will allow us to create the subvolumes. Again, what follows is the BTRFS subvolume layout I prefer. You might want to choose a different one. To use Timeshift, you must have at least @ for / and @home for /home. This is how I create the subvolumes I want:

As I said, this mount was temporary, just for creating subvolumes. In fact, we now unmount /mnt:

And we mount every single subvolume in its final “position” inside /mnt by also specifying a few additional options like the general “noatime” and the BTRFS-specific “compress” to enable the ztsd compression:

The “-m” option makes mount create the target directory if it does not exist.

Finally, we can mount the remaining partitions. The UEFI one should be mounted to “/boot/efi” inside “/mnt”. I like to mount the “common” partition in “/media/bettini/common” inside “/mnt” because that’s where I’ll use it (relying on the fact that I’ll create a user “bettini” for myself). Again, choose something else for yourself. These are the commands:

This is the final layout of /mnt, which, remember, is where our system will be installed:

Select the mirrors

This part, documented in the official installation guide, is usually skipped in several blog posts I found online. Instead, this step is essential.

The mirrors are specified in the file /etc/pacman.d/mirrorlist.

The guide says:

On the live system, after connecting to the internet, reflector updates the mirror list by choosing 20 most recently synchronized HTTPS mirrors and sorting them by download rate.

The higher a mirror is placed in the list, the more priority it is given when downloading a package. You may want to inspect the file to see if it is satisfactory. If it is not, edit the file accordingly, and move the geographically closest mirrors to the top of the list, although other criteria should be taken into account

You can verify that by inspecting the file /etc/pacman.d/mirrorlist. In my case, the Italian mirror is the last one, so it will be given the lowest priority. This sounds wrong to me. In particular, the documentation also points out:

This file will later be copied to the new system by pacstrap, so it is worth getting right.

Thus, I prefer to run the program reflector myself (see the reflector documentation for the single arguments; of course, I’m using “Italy” as the country because that’s where I leave; I could also specify several values separated by a comma, e.g., “Italy,Germany”):

The following step does not seem to be required in the installation guide. However, to make sure we have an updated PGP keyring (for checking signatures of packages), at this point, I also run:

Running pacstrap

Now, it’s time to install the base packages, Linux kernel, and firmware for standard hardware using the pacstrap script. You specify the target directory, which, as you might guess, it’s /mnt, and the packages.

This is the command I run (I prefer to use the LTS kernel; if you want the latest kernel, use “linux” package instead of “linux-lts”; you can also install them both and then select one from the grub menu):

This command will download about 500Mb, which might take time depending on your Internet speed.

Configuring the system

Since we have already manually mounted all our partitions (on /mnt), the Arch ISO can generate for us the file fstab automatically through the command genfstab:

The “-U” option tells genfstab to use UUID to refer to partitions (alternatively, “-L” can be used to use labels instead).

You can have a look at the result (of course, UUID will be different in your case):

Note that although we used the option “compress=zstd” when mounting our BTRFS subvolumes, genfstab turned that into “compress=zstd:3” because “3” is the default compression value for zstd in BTRFS. If we wanted to make the compression value explicit, e.g., “1”, we should have done that when mounting the subvolumes. Of course, you can always tweak the generate fstab as you see fit.

Now, we can “enter” our installation with “chroot” or, better, with the enhanced arch-chroot, which automatically binds other things like /dev and /proc:

The root directory is what’s inside /mnt, so / refers to what’s inside /mnt. Also, the prompt has changed to reflect this:

We now set the timezone of the installed system. You must use Region/City according to your location. Timezones are available in the directory /usr/share/zoneinfo/. In my case (Italy), I run:

Then, we use hwclock to set the Hardware Clock from the System Clock:

Then, we edit /etc/locale.gen and uncomment the locales we need; in my case, en_US.UTF-8 UTF-8 and it_IT.UTF-8. Since I already know the two locales, instead of editing the file (where all locales are commented out), I append the two locales to the end of that file:

And we generate the locales:

We must also create the /etc/locale.conf file, and set the LANG variable accordingly. This can be done as follows:

We also make permanent the initial changes to the console layout (remember, I used “it”; in your case, you need to use the code you previously specified):

We’ll deal with the network configuration (of the installed system) in a minute. But we can already create the files /etc/hostname and /etc/hosts. You have to choose your preferred hostname. In this example, I’m going to use “arch-vm-gnome”. So I generate the two files with the following two commands:

The boot loader

Since we use BTRFS, we might want to tweak the file /etc/mkinitcpio.conf with these two modules:

And regenerate the initramfs images:

Let’s now install the bootloader. I prefer GRUB. So let’s install a few packages:

During the installation, you might want to take note of the recommendation for installing and configuring grub and the optional dependencies:

Now we install grub in the UEFI partition. Note that, unlike standard GUI Linux installations, you can specify the “–bootloader-id”, which will be the identifier of this grub installation in UEFI. This is useful if you have several bootloaders on your machine. In this example, I’m using ArchGnome:

Hopefully, the installation should succeed, and we can generate the grub menu:

Here’s the output of these two commands:

User accounts

Don’t forget to set the following passwords, or you will not be able to log in to the installed system once you reboot later.

We can now set the root password. This is the effective password for root in the installed system. This should be chosen carefully:

I prefer to use “sudo”, so I first install that

This is also the moment to create your own user account; in my case, it is “bettini”.

I add the user to a few essential groups, in particular, “wheel” which makes my user a superuser account. Just relying on the group “wheel” is not enough: we must allow members of the group wheel to execute any command. This is done by uncommenting this line in the /etc/sudoers: “%wheel ALL=(ALL:ALL) ALL”. A sed command will accomplish that:

That would be enough to reboot and try our installation. However, we would have no networking (actually, since this is a virtual machine, networking should work out of the box since you don’t need to configure any WiFi network, for example) and no desktop environment. So let’s go on with some further installations and configurations:

Install Gnome

In this example, I’m going to install the GNOME desktop environment. Besides GNOME, I’m installing other necessary packages like the “NetworkManager” (for easily configuring networking in GNOME), “firewall”, “firefox”, the package for choosing a power profile (useful for laptops), and other base packages, including the kernel headers (here I’m using “linux-lts-headers” because I installed the LTS kernel; otherwise, use “linux-headers”):

About 700Mb will be downloaded.

Once done, we have to enable the services at boot (in particular, GDM, the login manager, and the NetworkManager):

Time to reboot!

Now, it’s time to leave the environment and unmount all the partitions:

And reboot into our new Arch Linux installation.

If everything goes fine, we should see the login manager, and we can enter Gnome:

So, in the end, it’s not so hard to install Arch πŸ˜‰

Maybe it’s a long procedure, but… most of that can be scripted! That’s will be the subject of another blog post, so stay tuned! πŸ™‚