Year: 2024

  • How audiobooks rekindled my love for reading

    How audiobooks rekindled my love for reading

    After listening to a lot of grandma stories when I was very young, I started reading story books, in English and Tamil, during my school days. I always looked forward to long train journeys because I could request my father to buy me some books and Tinkle comics from Higginbothams to read during the travel. In a few years, I moved on to reading books from authors like J. K. Rowling, Dan Brown, Stieg Larsson etc. and enjoyed that a lot. This continued through my college days and then somehow after I got my first job, I lost that habit. ☹️

    Perhaps, my love for computers, gadgets, and gaming distracted me, or I spent all my spare time wooing the love of my life, I do not know. While I have read a book or two once in a while, mostly non-fiction ones that interested me, I couldn’t get back into my habit of reading books regularly.

    A few years ago, I had read good reviews about Brandon Sanderson’s Mistborn saga and started reading the first book a couple of times but lost interest very quickly. This wasn’t because of the book’s content, but more due to getting distracted by other, “more interesting” things.

    Around 2015, I started listening to podcasts during my long commute to and from work and loved that experience so much that I have continued to do so till now even though I don’t have any daily commutes anymore. So I decided to channel that into listening to audiobooks to see if that sticks as a habit.

    I started listening to the Mistborn saga audiobooks and surprisingly, it stuck! I kept coming back to it regularly enough to be able to finish listening to the trilogy in 2 months or so. Listening to podcasts during dinner time was often replaced with long audiobook sessions during the same time. Even when there were some gaps, I came back to it within the next day or two. On a few days, I even ended up listening for long hours because I was interested in seeing the stories progress. I have to thank Michael Kramer, who narrated all the books, for keeping things lively throughout.

    Cover images of the Mistborn trilogy books
    Cover images of the Mistborn trilogy books

    As for the Mistborn trilogy itself, it had a decent plot and the execution was decent, considering that these were some of Brandon Sanderson’s earliest books. While there were enough plot points that kept the listener hooked through parts of the books, I couldn’t help noticing how most of what happened in each book barely mattered at the book’s/trilogy’s ending.

    Even though I noticed and realized that audiobooks are a very inefficient way to consume content at a glacial pace (relative to reading), it was still better than not reading books at all.

    Here’s to reading and listening to more books in the coming years! 🤞

    Fediverse Reactions
  • A roundup of my 2024

    2024 has been a good year for me and my family, and I wanted to share some highlights from it.

    Personal life

    Keirthana and I had our tenth wedding anniversary ❤️ at the beginning of this year (we have known each other for more than 32 years now!) and celebrated it with a trip to Murudeshwara (a long train journey that we enjoyed) where our daughter had her first beach experience.

    Statue of Lord Shiva, Murudeshwara
    Statue of Lord Shiva, Murudeshwara

    Our daughter also had her first flight, and her first international trip (to Singapore) along with my cousin who had his firsts too. A day trip to the Universal Studios at Sentosa was a highlight of this trip.

    Shrek Castle at Universal Studios, Sentosa, Singapore
    Shrek Castle at Universal Studios, Sentosa, Singapore

    We also had a memorable trip to Jaipur with family while presenting at the UbuCon Asia 2024 event held there. More details about that later.

    A beloved family member passed away in the middle of this year, causing a mix of sorrow and relief to the bereaved.

    Towards the end of the year, we managed to achieve some longstanding financial goals, which should stand us in good stead for the future.

    While there were some challenges throughout the year, we are grateful to have been in a position to deal with them well. 🙏

    Work

    I continue to work in the awesome Launchpad team at Canonical, and we have been doing a great job so far in coping with the departures of legendary colleagues (Colin and William), and the team growth has helped with it. This has given me a valuable opportunity to grow and provide leadership in specific areas (infrastructure, overall system design etc.) within the team, and I am grateful for that.

    At the beginning of this year, Keirthana and I had a stressful time when we had to assess our options and decide not to travel to the Canonical engineering sprint at Madrid in May. As a Real Madrid, I was really looking forward to going to Madrid, visit the iconic Santiago Bernabéu stadium, and possibly attend a Real Madrid game. 💔 But this tough decision had to be made due to a lack of reasonable childcare options for our daughter during our work trip. We were able to travel to The Hague for the second engineering sprint in October and also attend the Ubuntu Summit 2024.

    A photograph taken at the Den Haag Centraal Bus Stop, featuring the sky with numerous white clouds
    A snap taken at the Den Haag Centraal Bus Stop
    The Ubuntu Summit 2024 logo featuring a white stork with an eel in its beak
    Ubuntu Summit 2024 logo

    During the summit, I had the chance to meet and thank some inspirational people from the Linux ecosystem (Mathieu Comandon from the Lutris project, GloriousEggroll of Proton GE, Nobara fame, Neal Gompa, a prolific contributor to Linux distributions and a fixture in many of my favorite Linux podcasts), ex-colleagues, and friends (Soumyadeep Ghosh). I loved the Matrix 2.0 talk by Mathew Hodgson and the lightning talk by Nirav Patel from Framework where he successfully switched the Mainboard of a Framework laptop from x86 to RISC-V during the talk was mind-blowing!

    Keirthana and I presented talks at the UbuCon Asia 2024 at Jaipur in September. My talk was about ‘6 little-known features: How to make the most out of Launchpad’ and it was well-received by an audience containing a mix of many students very new to Linux and some seasoned, veteran community members.

    A photograph taken during my talk at UbuCon Asia 2024
    A snap from my talk

    During this event, I met Soumyadeep Ghosh, a still-in-college prodigy doing great work in the Ubuntu, Snap, KDE, and the open source software communities, and gained a new friend!

    I started learning Golang this year and have used it to build some toy personal projects so far. Python has spoiled me so much that I find it very difficult to pick up a new programming language. After relying on the ‘batteries included’ approach of Python and its standard library, I find the ‘So what if it is not there in Golang? We can easily implement it ourselves’ attitude of developers using Golang, very hard to accept. But this ‘learn, unlearn, and relearn’ process is very important for me to master, and so I will continue learning Golang in 2025.

    Hobbies

    Self-hosting

    I built my first homeserver (code-named, tesseract, because of the cubic shape of the Fractal Design Node 804 case that I used for the build) at the beginning of this year and moved all the local self-hosted services from the 2 Raspberry Pi 4s to it. I run Ubuntu 24.04 on this server with multiple ZFS pools having plenty of storage. Even though I have known about ZFS for a very long time (right from my college days as a Sun Microsystems Campus Ambassador in 2008), I am grateful to the 2.5 Admins podcast (Jim Salter and Allan Jude, in particular) for evangelizing ZFS and nudging me to use it! I plan to convert all my computers to use ZFS, with tesseract acting as a zfs send backup target, soon.

    Gaming

    I continued to wade through my ever-growing backlog of video games this year, and managed to finish many more games this year than the averages from the previous years. You can see my posts about these games in this Mastodon thread. Here is a list of the games that I played and completed this year.

    • Venba (Xbox Series X)
    • Lovers in a dangerous spacetime (Steam)
    • Spiderman 2 (PlayStation 5)
    • Trine 3 (Steam)
    • Cyberpunk 2077 Phantom Liberty (Steam)
    • Super Mario Odyssey (Nintendo Switch)
    • My Friend Peppa Pig (Xbox Series X) — I played this for/with my daughter, who is a big Peppa Pig fan
    • Journey (PlayStation 5)
    • Operation Tango (PlayStation 5 + Steam)
    • Trine 4 (Steam)
    • Astro Bot (PlayStation 5)
    • Plucky Squire (PlayStation 5)
    • Trine 5 (Steam)
    • We Were Here (Steam)
    • We Were Here Too (Steam)
    • Marvel’s Midnight Suns (PlayStation 5)
    • It takes two (Steam, 2nd playthrough, this time as May)
    • SteamWorld Dig 2 (Steam)

    As you can see, most of the above games have cooperative gameplay of some sort and that is what I have enjoyed the most this year, playing with my cousins during weekend nights. Astro Bot (I preordered it) was my best game of this year and I enjoyed every moment of it and got the Platinum trophy at the end.

    Astro Bot game cover image
    Astro Bot game cover image

    I attempted emulating my Nintendo Switch games using Yuzu (RIP!) before Nintendo took it down and then came back to stop all development on Ryujinx too. I swore off Nintendo due to this, but I suspect I will buy their games and consoles in the future because they do make excellent games! ☹️

    I had an on and off relationship with my Steam Deck and played some games on it, without completing anything meaningful. SteamWorld Dig 2, Dave the diver, Cult of the Lamb, Borderlands 2, Yakuza 0, and Psychonauts 2 are some honorable mentions. You can find more details about it in my Steam Replay 2024 showcase.

    I bought game discs/cartridges for Marvel’s Midnight Suns, Metaphor: Refantazio (I loved playing Persona 5 Royal), and The Legend of Zelda: Echoes of Wisdom during my international trips, and I am yet to play the last two.

    Gadgets

    I bought myself an Aorus FO32U2P 32-inch 4K 240 Hz QD-OLED monitor to add to my existing BenQ EW3270U 32-inch 4K monitor, and it has been great to use so far. Since there isn’t a GPU that can run most of my favorite games at 4K 240 Hz, I will have to wait for a future GPU upgrade to be able to use the full power of this monitor. I chose this over the cheaper Alienware AW3225QF monitor because this doesn’t have a curved display and has more productivity features than AW3225QF. I still need to iron out some issues/limitations with my current setup to make the best use of it.

    Aorus FO32U2P 32-inch 4K 240 Hz QD-OLED monitor
    Aorus FO32U2P monitor

    Ever since Apple released the M-series MacBooks a few years ago, with trailblazing compute power and battery life, I have been interested in buying one and running Asahi Linux. So this June, I bit the bullet and bought myself an M3 MacBook Pro laptop with the M3 Pro chip, 18 GB RAM, and 512 GB storage. While the Asahi Linux project doesn’t support it yet, I am happy to wait and use macOS till then. I have been using it as an “on-the-bed laptop for personal projects and entertainment” device so far, and have written this post on it.

    Furthermore, I bought 3 more TP-Link Deco XE75 mesh routers during my Netherlands trip to allow extending my home Wi-Fi network’s coverage and/or replace any existing devices if they fail. This was important to me because the Wi-Fi 6E/7 mesh routers are no longer sold in India due to some uncertainty around the licensing and usage of the corresponding radio bands for Wi-Fi or telecom mobile networks. I hope this should suffice for the next 5 years or so.

    Podcasts

    After listening to and supporting Jupiter Broadcasting network’s podcasts for nearly a decade, I stopped listening to their shows this year because of the excessive bitcoin shilling (I hate cryptocurrencies) that took the focus away from the great content in those shows. It looks like they have been doubling down on the bitcoin stuff since I stopped listening, so there might be no way back for me. ☹️

    The Late Night Linux family of podcasts have been as great as ever and provide a lot of excellent content. 2.5 Admins is my favorite podcast and I can’t wait to hear its every new episode.

    I am currently evaluating ‘The Untitled Linux Show’ and so far it has been enjoyable.

    FOSS contributions

    This year, I have continued my recurring donation to the KDE project and started a new monthly donation to the Matrix project. If you haven’t done so, I strongly recommend donating/contributing to the FOSS projects of your choice.

    Gratitude

    2024 was a memorable and an eventful year, that ebbed and flowed every day. We are thankful for all the good and grateful for the privileges that allowed us to deal with the not-so-good well. Looking forward to a great 2025 ahead! Wish all of you a happy, prosperous, and fulfilling 2025! 🎉🙏

    Fediverse Reactions
  • Seamlessly access local services on LAN and Tailnet

    As I am passionate about self-hosting, I have been setting up various services in my homelab, in addition to those on my cloud servers. I have also been using Tailscale to access my devices and services while not at home. So I have wanted to have a seamless way to access the services, irrespective of whether I am on my home local area network (LAN) or connected to it via Tailscale. Below are my requirements for such a setup.

    • All the devices/services should be accessible using a fully-qualified domain name (FQDN), under a domain that I own and control. This rules out the auto-generated Tailscale subdomains.
    • I have a LinuxServer.io SWAG reverse proxy in front of all the services in my homelab, and it provides TLS termination. So I would like to access the existing services using TLS at all times.
    • While I could set up a Tailscale subnet router that allows access to my LAN, I do not want to allow the devices on my Tailnet full access to my LAN. And I do not want to redo my home LAN setup to isolate things to be able to do this.
    • The FQDNs of the exposed services should resolve to a LAN IP address when I am in my home LAN and to a Tailnet-specific address when I am not at home and connected to my Tailnet.
    • It should be possible to expose more services using this setup in the future, even if they are not behind the SWAG reverse proxy.
    • The base domain that I want to use for this should not have any publicly accessible DNS records pointing to private IP addresses for this setup to work.
    • The resulting setup should integrate into my existing docker-compose configuration.

    The Tailscale docker documentation illustrates a way to expose LAN services on a Tailnet, but the example on that page causes the service(s) to be accessibly only over the Tailnet. So it doesn’t work for me.

    To start, I added a Tailscale docker container to my compose.yaml file using a configuration like

      tailscale:
        image: tailscale/tailscale
        container_name: tailscale
        hostname: <tailnet device name>
        environment:
          - TS_ACCEPT_DNS=true
          - TS_AUTHKEY=<authkey or OAuth2 client secret>
          - TS_EXTRA_ARGS=--advertise-tags=tag:docker
          - TS_ROUTES=172.21.0.0/24
        volumes:
          - ./config/tailscale/state:/var/lib/tailscale
          - /dev/net/tun:/dev/net/tun
        cap_add:
          - net_admin
          - sys_module
        networks:
          tailnet-subnet:
            ipv4_address: 172.21.0.11
        restart: unless-stopped
    networks:
      tailnet-subnet:
        ipam:
          config:
            - subnet: 172.21.0.0/24
    

    For this to work, I had to define a tag named docker and add it to my Tailscale ACLs. I also added an ACL to auto-approve the routes advertised by this container.

    {
        // other configuration
    	"tagOwners": {
    		"tag:docker": ["autogroup:admin"],
    	},
        "autoApprovers": {
    		"routes": {
    			"172.21.0.0/24": ["tag:docker"],
    		},
    	},
        // other configuration
    }
    

    With this, all the containers that get added to the tailnet-subnet network and have an IP address in the 172.21.0.0/24 subnet will be accessible over my Tailnet. So I updated the configuration of the swag container to add it to the tailnet-subnet network.

      swag:
        image: lscr.io/linuxserver/swag
        container_name: swag
        cap_add:
          - NET_ADMIN
        environment:
          - var1=value1
          - var2=value2
        volumes:
          - ./config/swag:/config
        ports:
          - 443:443
          - 80:80
        networks:
          tailnet-subnet:
            ipv4_address: 172.21.0.12
          default:
        restart: unless-stopped
    

    In the above snippet, I added the tailnet-subnet network to the networks key and assigned it a static IP address in its subnet, 172.21.0.12. Since the default network was implicitly included before and adding a different network will remove the implicit inclusion, I have also explicitly added the default network.

    With these configuration changes, the swag container was accessible at the 172.21.0.12 IP address over my Tailnet. But I still needed to set up DNS to access the services by domain name.

    Tailscale provides a way to add a restricted nameserver for a specific domain using split DNS. So I needed a DNS server that resolved the domains of the services hosted on the swag container to its Tailnet subnet IP address, 172.21.0.12.

    For this, I took inspiration from jpillora/dnsmasq and created a custom Dockerfile that set up a dnsmasq resolver.

    FROM alpine:latest
    LABEL maintainer="email@domain.tld"
    RUN apk update \
        &amp;&amp; apk --no-cache add dnsmasq
    RUN mkdir -p /etc/default \
        &amp;&amp; echo -e "ENABLED=1\nIGNORE_RESOLVCONF=yes" > /etc/default/dnsmasq
    COPY dnsmasq.conf /etc/dnsmasq.conf
    EXPOSE 53/udp
    ENTRYPOINT ["dnsmasq", "--no-daemon"]
    

    Then I created a dnsmasq.conf configuration file that looks like the following snippet.

    log-queries
    no-resolv
    address=/domain1.fqdn/172.21.0.12
    address=/domain2.fqdn/172.21.0.12
    

    Then I added the following snippet to my compose.yaml file to add the dnsmasq container.

      dnsmasq:
        build: "./build/dnsmasq"
        container_name: dnsmasq
        restart: unless-stopped
        volumes:
          - ./config/dnsmasq/dnsmasq.conf:/etc/dnsmasq.conf
        networks:
          tailnet-subnet:
            ipv4_address: 172.21.0.3
    

    Then I ran docker compose build to build the container, and docker compose up -d dnsmasq to start it. With that, I had a DNS resolver to resolve my domain names in the Tailnet.

    You might notice error messages in the dnsmasq container’s logs that look like dnsmasq: config error is REFUSED (EDE: not ready). This happens because we have not defined any upstream servers that dnsmasq can use. But since we want this dnsmasq instance to resolve only our domain names, this is okay and the error can be ignored.

    Then on my Tailscale admin dashboard, I added a custom nameserver for my domain name and configured 172.21.0.3, the IP address of the dnsmasq container, as the address of the server to use. Now, all the devices on my Tailnet could access the services on my swag container by domain name.

    I have an existing DNS setup on my home LAN that resolves the same domain names to the LAN IP addresses. So now, with this setup for Tailscale, my devices can seamlessly access the private services on my LAN and Tailnet.

    If I want to add a new service to this setup, it is as easy as adding the tailscale-subnet network to it, and adding the DNS records to dnsmasq docker container’s configuration file and the resolver in my home LAN.

    Fediverse Reactions