Showing posts with label linux. Show all posts
Showing posts with label linux. Show all posts

Wednesday, 12 July 2023

My journey through BLFS - part 2

Continuing from where I left in part 1 with a functional X Windows System, it's time to aim for something closer to a usable system.

16 May 2022 - GTK+ 2

I cloned the VM to have a checkpoint to restart from in case anything went horribly wrong. At this point there are many possible paths but I decided to go for LXDE due to its small memory footprint and dependencies compared to other more mainstream desktop environments.

Building GTK+ 2

GTK+ is the centerpiece for all graphics used in LXDE. I started with version 2. As explained in the guide, some libraries will need to be rebuilt with extra support previously disabled. On that note I had to rebuild cairo, pango, harfbuzz due to the later addition of gobject-introspection.

GTK+ 2 up and running from the demo app.

Quick gotcha: ISO Codes source code was not available from the proposed location, instead I got it from http://ftp.debian.org/debian/pool/main/i/iso-codes/iso-codes_4.9.0.orig.tar.xz not a big issue but it required a bit of googling around.

I wanted to see if it was possible to build LXDE with GTK+ version 3, so I built GTK+ 3, here is how it looks from the demo app.

17 May 2022

LSB Tools link is broken it gives 404, instead of releases, I got it from Github repositor tags page https://github.com/djlucas/LSB-Tools/archive/refs/tags/v0.9.tar.gz

Building apps with GTK+ 3 support.

Building LXSession

./configure \
  --prefix=/usr \
  --enable-gtk3 \
  --enable-buildin-clipboard \
  --enable-buildin-polkit

Building PCManFM

./configure \
  --prefix=/usr \
  --sysconfdir=/etc \
  --with-gtk=3

Building libindicator-12.10.1

It has a bug which is allegedly fixed, however, I could find the issue in the source code I downloaded from https://launchpad.net/libindicator/+download as per this comment. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=806470.

CFLAGS=-Wno-error ./configure \
  --prefix=/usr \
  --with-gtk=3 \
  --enable-deprecations=yes

18 May 2022

I tried many different ways to get LXPanel built with GTK+ 3 to work. Long story short, I couldn’t.

Building LXPanel (not possible to install with GTK 3)

./configure \
  --prefix=/usr \
  --with-plugins=-netstat

It required wireless-tools-devel.

Building libwnck, download source from: https://download.gnome.org/sources/libwnck/3.24/libwnck-3.24.1.tar.xz

./configure \
  --prefix=/usr \
  --disable-static

Building keybinder, download source from: https://github.com/kupferlauncher/keybinder/releases/download/keybinder-3.0-v0.3.2/keybinder-3.0-0.3.2.tar.gz

./configure --prefix=/usr

End of LXPanel, at this point all dependencies were met and LXPanel is installed.

Building LXAppearance

./configure \
  --prefix=/usr \
  --sysconfdir=/etc \
  --enable-dbus \
  --enable-gtk3

9 June 2022

I gave up on LXPanel with GTK+ 3, the main reason being that even if it installed correctly in the system, it constantly crashed randomly and this seems to be a known bug. I built libfm-gtk as well so LXPanel has a GTK+ 2 dependency built before and ./configure is happy.

Unfortunately (or fortunately) I was very busy during the following months and I couldn't spend time on this. Finally I got some spare time and I went back to it.

3rd March 2023

Installed Lightdm and lightdm-gtk-greeter.

At this point, a new problem appeared, the VM integration didn't work until I log in which is when SPICE agent runs. I added a note for future research.

I need to find out how to run spice-vdagent with lightdm or the greeter. Potentially exploring more here: https://wiki.ubuntu.com/LightDM.

Copying the desktop entry to the relevant location works to autostart the SPICE agent when you log in to the session.

sudo cp \
  /sources/spice-vdagent-0.21.0/data/spice-vdagent.desktop \
  /etc/xdg/autostart/

I installed Mousepad without any trouble.

Important note: compiling Firefox requires a lot a lot of RAM, no less than 8GB!

It also requires send-notify program to complete installation

Gtkmm - it wouldn’t compile unless disabling building documentation in all subprojects:

meson --prefix=/usr --buildtype=release .. \
  -Dmm-common:use-network=true \
  -Dbuild-documentation=false \
  -Datkmm-1.6:build-documentation=false \
  -Dcairomm-1.0:build-documentation=false \
  -Dglibmm-2.4:build-documentation=false \
  -Dlibsigcplusplus-2.0:build-documentation=false \
  -Dpangomm-1.4:build-documentation=false 

Sunday, 8 May 2022

My journey through BLFS - part 1

Having successfully finished LFS, I felt inspired to continue the journey, since all I had was a very minimal system. As I used version LFS 11.0-systemd, it only made sense to continue with the same version BLFS 11.0-systemd

15 Feb 2022 - SSH & curl

The top priority for me was to be able to connect remotely, primarily motivated by the fact that I was typing all commands from the guide since I left the chroot. OpenSSH to the rescue.

Another priority was the ability to download packages to continue building the system with new packages as I followed along, but there was no curl or wget. I could have used some bash magic or python minimal script, however, the main issue was the lack of support to download files via HTTPS. This is where make-ca, pk11-kit, GnuTLS and a few others came handy.

During all that time, I was making use of virtio 9p to share a folder with my host, this would simulate copying files manually before being able to use the network to download the rest.

6 April 2022 - LLVM compiled - required a lot of RAM

At some point I went down the rabbit hole, probably my mistake being too ambitious, building packages that I didn’t need so early in the process, but hey, that’s the learning process. A particular package that took me too deep in the dependency hell was texlive-20210325 as I was also building the documentation along with the binaries, to such extent that I decided to leave it and use the binary option (install-tl-unx) which is also huge in size.

One issue I encountered while building some of those dependencies of dependencies, I was building LLVM when all of the sudden the compiling process was killed, not enough memory. I set up 4GB swap space and tried again, to my surprise, it got killed again, so I ended up creating a swap file of 8 GB to complete the compilation process.

Other interesting milestones were:

Linux PAM - it allowed a more streamlined integration with many programs. In my particular use case, I wanted to control how I was using the “su” command without having to type root password every time and without using sudo. It also made me rebuild the whole systemd again to include PAM support.

Polkit - a somehow ubiquitous dependency for GUI apps and because it has quite a few dependencies that take some time to build like js engine, some of the next packages benefited from not having to build them as dependencies.

Having built all this, it was time to start preparing one of the most daunting parts of the whole BLFS, the X Window System !

25 April 2022 - X Window System up and running

This part is another one, where you can see yourself building and installing tons of packages and not seeing anything encouraging. It’s not until that very last moment of truth when you run startx that you see the result of all that hard work.

To my surprise, it worked the first time ! Well, not without some issues, but I have to say, the default values for xorg configuration are pretty good. Without proper graphic card drivers and barely any configuration in place, it managed to launch the X server with twm and some insanely big terminal emulators.

It took me some time to get my head around this poor man’s window manager, especially because for some reason the mouse movement was a bit awkward when the VM’s window had a different aspect ratio from the guest resolution.

Some issues I noted to fix immediately after this successful milestone:

  • Mouse cursor trapped in VM’s window
  • Clipboard integration host-guest
  • Mouse movement impacted by VM’s window size

26 April 2022 - Qemu agent integration

All the issues above mentioned are related to the same root cause, not having the "guest drivers" running in the VM. In this case, I needed both the qemu-agent and spice-vdagent running as well as the actual kernel drivers.

In order to get spice channel working, I had to add virtio vsockets in the kernel, so that the devices /dev/virtio-ports/com.redhat.spice.0 and /dev/virtio-ports/org.qemu.guest_agent.0 were available after setting them up in VM’s hardware configuration. Together with some udev rules provided by the agent, it was all I needed to get the daemons running.

Something I found out, which is not covered in the guide (again, because it was specific to my VM scenario) when building spice-vdagent, I had to add a few extra parameters to make it work:

CFLAGS=-Wno-error ./configure \
  --prefix=/usr \
  --with-init-script=systemd \
  --with-session-info=systemd

For some reason it wasn’t recognising that it’s being compiled in a running systemd environment, so I provided the flags to force using it, also the warning being treated as errors.

The second part of the integration, as per documentation is a per X-session process spice-vdagent, which I had to somehow manually invoke, and when I did, magic happened ! The mouse cursor was free as a bird to move all over my screen. Next, figure out how to adjust the resolution and bundle everything together to run automatically when all X starts up.

This is the tweaked version of my ".xinitrc" which worked well enough to get by without having any desktop environment to handle all these tasks.

xrandr --output Virtual-0 --mode 1366x768
spice-vdagent
xrdb -load $HOME/.Xresources
xsetroot -solid gray &
xclock -g 50x50-0+0 -bw 0 &
xload -g 50x50-50+0 -bw 0 &
xterm -g 80x24+0+0 &
xterm -g 80x24+700+320 &
twm

To wrap this part up, it’s been an incredible learning experience, this time focusing on building packages that are closer to what it’s being used on a daily basis in any Linux system. This is the base to add a desktop environment which will be my next task, at this point I’m leaning towards LXDE, but I’ll keep a backup copy at this stage in case I’d like to go for a different one later on.

The journey continues.

Wednesday, 4 May 2022

My journey through LFS

Building a whole Linux system completely from the ground up is something I wanted to do for some time and finally I had all I needed to take the plunge. In this post I’m sharing the highlights of this journey. Also, this is something I’m doing in my spare time, hence the time gaps between milestones.

1st Jan 2022 - Started reading the guide

I decided to go for the LFS-11.0-systemd released in September 2021, the latest stable at the time and I'm comfortable enough with systemd.

Before even starting with LFS I needed a host system, I gave it a try to the latest Arch iso at the time, which was archlinux-2022.01.01-x86_64.iso. Also, as my first attempt in such a venture, I went for a virtual machine using KVM/QEMU with its own challenges which are not fully covered in the guide.

25 Jan 2022 - Created VM with vanilla Arch as host system

Some initial decisions about my target system:

  • Virtual machine KVM/QEMU
  • 4 CPU (compiling can be CPU intensive)
  • 2 GB RAM (aim for a small system)
  • 60 GB Disk storage (that was too optimistic)
  • UEFI boot (mimic modern systems)
  • Network - bridged (ease of connection via SSH)
  • 1 partition for everything (simplicity)
  • No swap partition, swap file when needed

I learned that a plain vanilla Arch Linux base system is good enough for building a full LFS with no extra packages. Every requirement was met out of the box, that’s a good start !

Once I had my VM up and running with all the base configuration, including my SSH key in place so I can connect to it via SSH so it makes my life easier by enabling me to copy and paste, I made a clone of it just in case I had to go back and start again.

The first few days required a lot of patience and will power, since you’re only compiling and compiling and not seeing much in use. I had the impression sometimes that some of the commands to follow were somehow hacking my way to just get it compiled despite the environment conditions.

It’s only once you enter the chroot that it starts to feel like you’re getting somewhere.

10 Feb 2022 - chroot getting ready

Working inside the chroot can give you some frustration since it’s such a minimal system, the LFS developers made good effort to provide enough tooling to get the job done, but anything outside that, you’ll be faced with the dreaded "-bash: xxxx: command not found"

This was the first time I installed neofetch in the pseudo new system, mostly since I was intrigued by which logo it would display and how it’d find system information when there is barely any system at all.

Because I used UEFI in my target system, I had to jump ahead to BLFS for boot loader installation and configuration, that break in the flow can be a little disrupting and confusing, but nothing major.

14 Feb 2022 - First successful boot

There is always a moment that makes or breaks the installation, in this case is when configuring the Linux kernel. As almost expected after such a long build up preparing and configuring all the packages, I was greeted by a big kernel panic when I booted the system for the first time outside of the chroot.

It couldn’t find /dev/vda3 from the kernel command line argument root=/dev/vda3 which happens to be the root partition in the virtual hard drive. Some symbols were not selected (or indicated in the guide, since it’s specific to my setup using a VM) such as CONFIG_VIRTIO_BLK, more information on that can be found at linux-kvm website.

After adding the missing symbols and rebuilding the kernel a couple of times, following the classical trial and error method, I could see a normal boot screen all the way to the login prompt, which I have to say was lightning fast !

At this point, the system had been built but this was not the end of the journey, there was some extra networking configuration required, again, due to use of a VM which required virtio network as well as 9p so I had a mechanism to share files between the host and the guest LFS.

One more thing before calling it a milestone complete, I got counted and this is my information:

You have successfully registered!
ID: 29352
Name: Abel Perez Martinez
First LFS Version: 11.0-systemd

Date: 14 Feb 2022

My key takeaways from this process:

  • Arch Linux is minimal but powerful
  • Be patient, compiling takes time
  • Compiling software takes a lot of disk space
  • Use -j4 whenever possible
  • Make a backup of your VM after a significant milestone
  • This is only the beginning, it’s a minimal system

Sunday, 17 February 2019

How to Install docker on raspbian stretch

As part of one of my recent experiments I wanted to install docker on my raspberry pi. The procedure nowadays seems significantly better than a couple of years ago when I first tried. However, there are always some little details that can be a bit frustrating when following steps.

Although the process to install docker is well described in their website, it's focused on Debian distribution. We all know that Raspbian is based on Debian and therefore most of the instructions for will apply without much trouble.

That said, I will detail the exact steps I followed to get docker installed on my raspberry pi, this procedure was tested on 3B, Zero and Zero W.

First, update the package list, if you haven't done yet after setting up your raspberry pi.

$ sudo apt-get update

Install packages to allow apt to use a repository over HTTPS.

$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg2 \
software-properties-common

Add Docker’s official GPG key. Note that here the url points to raspbian directory and not to debian as per the original instructions.

curl -fsSL https://download.docker.com/linux/raspbian/gpg | sudo apt-key add -

The next step recommended didn't work for me.

sudo add-apt-repository \
   "deb [arch=armhf] https://download.docker.com/linux/raspbian \
   $(lsb_release -cs) \
   stable"

It failed with an error similar to this:

Traceback (most recent call last):
File "/usr/bin/add-apt-repository", line 95, in 
  sp = SoftwareProperties(options=options)
File "/usr/lib/python3/dist-packages/softwareproperties/SoftwareProperties.py"
, line 109, in __init__
  self.reload_sourceslist()
File "/usr/lib/python3/dist-packages/softwareproperties/SoftwareProperties.py"
, line 599, in reload_sourceslist
  self.distro.get_sources(self.sourceslist)
File "/usr/lib/python3/dist-packages/aptsources/distro.py", line 89, 
in get_sources (self.id, self.codename))
aptsources.distro.NoDistroTemplateException: Error: could not find a 
distribution template for Raspbian/stretch

Instead, I tried this other way, more explicitly setting up the repository into a new docker.list sources file.

$echo "deb [arch=armhf] https://download.docker.com/linux/raspbian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list

With the new source repository in the list, update the package list again.

$ sudo apt-get update

Now we are in a position to install docker-ce from the repository, in this particular case, I ran into an issue with the latest version, documented in github basically they suggest to go back to 18.06.1 which we can get from the command below as per official docker instructions on how to get a specific version.

$ apt-cache madison docker-ce
docker-ce | 5:18.09.0~3-0~raspbian-stretch | https://download.docker.com/linux/raspbian stretch/stable armhf Packages
docker-ce | 18.06.2~ce~3-0~raspbian | https://download.docker.com/linux/raspbian stretch/stable armhf Packages
docker-ce | 18.06.1~ce~3-0~raspbian | https://download.docker.com/linux/raspbian stretch/stable armhf Packages
docker-ce | 18.06.0~ce~3-0~raspbian | https://download.docker.com/linux/raspbian stretch/stable armhf Packages

As of this writing, the version I tried is 18.06.2~ce~3-0~raspbian, which can be installed using the apt-get command.

$ sudo apt-get install docker-ce=18.06.2~ce~3-0~raspbian containerd.io

Also notice that by using this vesion, there's no need to install docker-ce-cli.

Testing everything is running as expected.

$ sudo docker info
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 1
Server Version: 18.06.2-ce
 --- more data --- 

Run the hello world. Usually we get the command sudo docker run hello-world but that only works on "normal" architectures, in this case, we're using ARMv6/7, but to make it more compatible with all of them, I ran the image from arm32v5/hello-world.

$ sudo docker run arm32v5/hello-world
Unable to find image 'arm32v5/hello-world:latest' locally
latest: Pulling from arm32v5/hello-world
590e13f69e4a: Pull complete 
Digest: sha256:8a6a26a494c03e91381161abe924a39a2ff72de13189edcc2ed1695e6be12a5f
Status: Downloaded newer image for arm32v5/hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (arm32v5)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

And that's all, docker installed up and running on a raspberry pi.

UPDATE:

If you'd like to get rid of the sudo command every time you use docker, then you can run the following command found in the official guide as a post-installation step. You don't need to create the group as it's already created by docker installation. It adds your user to the docker group.

$ sudo usermod -aG docker $USER

You need to log out and back in for this change to take effect. After that you'll be able to run all docker commands as a regular user.