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:
1
sudo pacman -S phonon-qt5-vlc
If you want to use Amarok with an iPod, you must first install
1
yay -S amarok
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):
1
sudo pacman -S libgpod
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):
1
yay -S amarok
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:
1
sudo pacman -S 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.
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.
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:
1
2
[ERROR] : could not get native definition for type `POINTER`, original error message follows: java.lang.UnsatisfiedLinkError: Unable to execute or load jffi binary stub from `/var/folders/5c/90l1wfls2xl7_xvqxqvnm3jw0000gn/T/`. Set `TMPDIR` or Java property `java.io.tmpdir` to a read/write path that is not mounted "noexec".
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:
1
2
3
docker pull mysql:5.7
5.7: Pulling from library/mysql
no matching manifest for linux/arm64/v8 in the manifest list entries
[WARNING]DOCKER>The requested image'splatform(linux/amd64)does notmatch the detected host platform(linux/arm64/v8)andno specific platform was requested
If you now enter the container, you can verify that you’re running an x86_64 image:
1
2
3
sh-4.2# uname -a
Linux cf9d5b28744a 5.15.49-linuxkit #1 SMP PREEMPT Tue Sep 13 07:51:32 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
sh-4.2#
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.
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:
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256: ...
Please contact your system administrator.
Add correct host key in <YOUR HOME>/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in <YOUR HOME>/.ssh/known_hosts:<A LINE NUMBER>
Host key for [127.0.0.1]:2522 has changed and you have requested strict checking.
Host key verification failed.
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.):
1
ssh-p2522root@127.0.0.1
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:
1
loadkeys it
If you don’t know the exact layout, you can list the available ones with
1
ls/usr/share/kbd/keymaps/**/*.map.gz
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:
1
ping archlinux.org
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:
1
timedatectl set-ntp true
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:
1
2
3
4
5
root@archiso ~ # lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0 7:0 0 683.2M 1 loop /run/archiso/airootfs
sda 8:0 0 100G 0 disk
sr0 11:0 1 794.3M 0 rom /run/archiso/bootmnt
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
1
cfdisk/dev/sda
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:
1
2
3
4
5
6
7
8
9
root@archiso ~ # lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0 7:0 0 683.2M 1 loop /run/archiso/airootfs
sda 8:0 0 100G 0 disk
├─sda1 8:1 0 300M 0 part
├─sda2 8:2 0 20G 0 part
├─sda3 8:3 0 30G 0 part
└─sda4 8:4 0 49.7G 0 part
sr0 11:0 1 794.3M 0 rom /run/archiso/bootmnt
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:
1
2
3
4
mkfs.fat-F32/dev/sda1
mkswap/dev/sda2
mkfs.ext4/dev/sda3
mkfs.btrfs/dev/sda4
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:
1
swapon/dev/sda2
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):
1
mount/dev/sda4/mnt
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:
1
2
3
4
5
6
btrfs su cr/mnt/@
btrfs su cr/mnt/@home
btrfs su cr/mnt/@cache
btrfs su cr/mnt/@log
btrfs su cr/mnt/@machines
btrfs su cr/mnt/@portables
As I said, this mount was temporary, just for creating subvolumes. In fact, we now unmount /mnt:
1
umount/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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/mnt
├── boot
│ └── efi
├── home
├── media
│ └── bettini
│ └── common
│ └── lost+found
└── var
├── cache
├── lib
│ ├── machines
│ └── portables
└── log
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”):
1
2
3
4
5
6
7
8
reflector \
--country Italy \
--age 12 \
--protocol https \
--fastest 5 \
--latest 20 \
--sort rate \
--save /etc/pacman.d/mirrorlist
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:
1
pacman-Sy--noconfirm archlinux-keyring
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):
1
2
3
4
5
pacstrap /mnt base linux-lts linux-firmware \
nano vim \
intel-ucode \
btrfs-progs \
sof-firmware alsa-firmware
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:
1
genfstab -U /mnt >> /mnt/etc/fstab
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:
1
arch-chroot/mnt
The root directory is what’s inside /mnt, so / refers to what’s inside /mnt. Also, the prompt has changed to reflect this:
1
2
root@archiso ~ # arch-chroot /mnt
[root@archiso /]#
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:
1
hwclock--systohc
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:
1
2
echo en_US.UTF-8 UTF-8 >> /etc/locale.gen
echo it_IT.UTF-8 UTF-8 >> /etc/locale.gen
And we generate the locales:
1
locale-gen
We must also create the /etc/locale.conf file, and set the LANG variable accordingly. This can be done as follows:
1
echo LANG=en_US.UTF-8 >> /etc/locale.conf
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):
1
echo KEYMAP=it >> /etc/vconsole.conf
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:
1
2
3
4
5
6
7
echo arch-vm-gnome >> /etc/hostname
cat >> /etc/hosts << EOF
127.0.0.1 localhost
::1 localhost
127.0.1.1 myhostname.localdomain arch-vm-gnome
EOF
The boot loader
Since we use BTRFS, we might want to tweak the file /etc/mkinitcpio.conf with these two modules:
1
MODULES=(crc32c-intel btrfs)
And regenerate the initramfs images:
1
mkinitcpio-P
Let’s now install the bootloader. I prefer GRUB. So let’s install a few packages:
1
pacman -S --noconfirm --needed grub efibootmgr
During the installation, you might want to take note of the recommendation for installing and configuring grub and the optional dependencies:
1
2
3
4
5
6
7
8
9
10
11
12
13
:: Install your bootloader and generate configuration with:
$ grub-install ...
$ grub-mkconfig -o /boot/grub/grub.cfg
Optional dependencies for grub
freetype2: For grub-mkfont usage
fuse2: For grub-mount usage
dosfstools: For grub-mkrescue FAT FS and EFI support
lzop: For grub-mkrescue LZO support
efibootmgr: For grub-install EFI support [pending]
libisoburn: Provides xorriso for generating grub rescue iso using
grub-mkrescue
os-prober: To detect other OSes when generating grub.cfg in BIOS systems
mtools: For grub-mkrescue FAT FS support
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:
Found initrd image: /boot/intel-ucode.img /boot/initramfs-linux-lts.img
Found fallback initrd image(s) in /boot: intel-ucode.img initramfs-linux-lts-fallback.img
Warning: os-prober will not be executed to detect other bootable partitions.
Systems on them will not be added to the GRUB boot configuration.
Check GRUB_DISABLE_OS_PROBER documentation entry.
Adding boot menu entry for UEFI Firmware Settings ...
done
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:
1
passwd
I prefer to use “sudo”, so I first install that
1
pacman-Ssudo
This is also the moment to create your own user account; in my case, it is “bettini”.
1
2
3
useradd-mbettini
usermod-aG wheel,sys,rfkill 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”):
Once done, we have to enable the services at boot (in particular, GDM, the login manager, and the NetworkManager):
1
2
3
4
systemctl enable gdm.service
systemctl enable NetworkManager.service
systemctl enable power-profiles-daemon.service
systemctl enable firewalld.service
Time to reboot!
Now, it’s time to leave the environment and unmount all the partitions:
1
2
exit
umount-R/mnt
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! 🙂
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.