Alien Pastures

My thoughts on Slackware, life and everything

I had to fix the Slackware 15.0 git repository

Recently, and unexpectedly, I noticed a lot of errors in the output of the script which populates the git repository for Slackware. Specifically, when it updated the “15.0” branch which tracks the updates in Slackware 15.0.

I did an evening of troubleshooting and fixing. Somehow, the root user had dumped a copy of Slackware-current in the checked-out directory containing the Slackware 15.0 branch of the git repository. The script errors were caused by the inability of the non-root user running the script, to delete all the root-owned files that were suddenly there.

I was out traveling (to the ISC’26) with my team and did not have the time to fix this earlier.

Now I have fixed https://git.slackware.nl/current/log/?h=15.0 which I mirror as https://forge.slackware.nl/slackware/distrodevelopment/src/branch/15.0 by deleting the faulty commit (which contained all of Slackware-current), replaying the three good commits that came after and then salvaging the actual update from the faulty commit.
It means that the 4 new commits (actually the same commits but with a new hash) look a bit weird compared with all the others. They were manually fixed.

What this also means is: I have re-written the git history. If you cloned this repository from either of the above repository URLs (pure ‘clone’, not ‘clone –mirror’) you need to do a hard reset:

$ git fetch origin
$ git reset --hard origin/15.0
$ git fetch --prune --prune-tags origin

If you cloned this repository in the Slackware Forge, it’s considered an independent copy. It will not update of its own. You will have to sync or reset manually.

If you actually are mirroring the repository https://forge.slackware.nl/slackware/distrodevelopment then your next “git remote update” will most likely just bring your mirror back in sync without a need for further interaction.

I have also double-checked that any script that touches this git repository when doing updates is not clashing with another instance.
Sorry for any inconvenience.

Fixing the cgit configuration of git.slackware.nl

In an earlier article here on the blog, I documented how I have setup cgit to create a browseable web interface to my git repositories, most notably git.liveslak.org and git.slackware.nl.

That configuration has worked just fine for years, and you could clone a branch of a repository using the “https://” git URI and that works.

However…
Cgit is a nice graphical shell around git repositories, but it does not serve the actual git protocol.
I found out when I tried to setup a mirror of the “current” repository on the Slackware Forge. For that, I needed to perform a full clone including all branches and tags. That failed mysteriously with the error:

$ git clone https://git.slackware.nl/current
Cloning into 'current'...
error: Unable to find d8220d28e5d53cd896b28d9dea13e2258923f35a under https://git.slackware.nl/current
Cannot obtain needed object d8220d28e5d53cd896b28d9dea13e2258923f35a
while processing commit 897670f2f2e1795652dfa3da21f9879d04a9b8dc.
error: fetch failed.

At first I thought that the remote repository was damaged or corrupted,but that was ruled out by searching for the hash to see if it would actually return something else than an error. From within the bare git repositorty on the server:

# git cat-file -t d8220d28e5d53cd896b28d9dea13e2258923f35a
commit

The hash does exist and it is a commit. That rules out the corruption.
Examining those errors “unable to find under ” and “cannot obtain needed object … while processing commit …” the conclusion is that the webserver only serves the bare repository as static files over plain HTTP, with no git-http-backend smart protocol behind it.
A working “git clone” over https needs the git-http-backend configured alongside the cgit configuration in Apache. Since that backend runs as the webserver user “apache”, and the git repositories are owned by user “git”,  we need to deal with file permissions/ownership and what git considers “safe directories”. Modern git (2.35.2 and later) refuses to operate on a repository owned by a different user than the one running git, and aborts with:
fatal: detected dubious ownership in repository at '/the/path/to/current'

The final configuration that adds the “git-http-backend” protocol to the Apache webserver and also resolves the “dubious ownership” error comes in two parts.

First:
A global git configuration directive which will only be used by the Apache user so that it won’t trip over the “git” user-owned repository files.
Create the file “/etc/httpd/http-git-config” and add these lines to it:

# ---
[safe]
        directory = *
# ---

Second:
Adding a code block to the VHost definition of the git server. In my previous article I described the git.liveslak.org configuration but actually this is identical to that for git.slackware.nl.
Therefore, to the file “/etc/httpd/extra/git.slackware.nl_content.conf” we add the following right before the “SetEnv CGIT_CONFIG” line:

# ---- smart HTTP for git clients (git-http-backend) ----
# Root directory that contains the bare repositories (current.git, etc.).
SetEnv GIT_PROJECT_ROOT /local/path/to/git/repositories

# Apache trips over the git:git ownership of the repositories, so we
# need to tell git that for Apache, all repositories should be considered
# as having safe ownership:
SetEnv GIT_CONFIG_GLOBAL /etc/httpd/http-git-config

# Route ONLY the git protocol paths to git-http-backend. Everything else
# (the cgit pretty URLs) is left untouched and handled by cgit below.
# The character classes accept both SHA-1 (40 hex) and SHA-256 (64 hex)
# object names, so this keeps working When we ever migrate hash formats.
# This MUST appear before the cgit ScriptAlias in the vhost.
ScriptAliasMatch \
  "(?x)^/(.*/(HEAD | \
    info/refs | \
    objects/(info/[^/]+ | \
      [0-9a-f]{2}/[0-9a-f]{38,62} | \
      pack/pack-[0-9a-f]{40,64}\.(pack|idx)) | \
    git-(upload|receive)-pack))$" \
  /usr/libexec/git-core/git-http-backend/$1

<Directory "/usr/libexec/git-core">
    Options +ExecCGI
    Require all granted
</Directory>
# -------------------------------------------------------

Test the Apache configuration for errors after saving your changes:

# apachectl configtest

And reload the webserver gracefully (not aborting current connections):

# apachectl -k graceful

Now, let’s test the server response when we send it a request:

$ curl -sI "https://git.slackware.nl/info/refs?service=git-upload-pack" | grep -Ei 'HTTP/|Content-Type'
HTTP/1.1 200 OK
Content-Type: application/x-git-upload-pack-advertisement

The content-type of “application/x-git-upload-pack-advertisement” instead of something like “text/plain” or “octet-stream” means that we have a properly working HTTP backend for git now. Cloning the repository no longer returns an error:

$ git clone https://git.slackware.nl/current
Cloning into 'current'...
remote: Enumerating objects: 103427, done.
remote: Counting objects: 100% (103427/103427), done.
remote: Compressing objects: 100% (31583/31583), done.
remote: Total 103427 (delta 69643), reused 103103 (delta 69319), pack-reused 0 (from 0)
Receiving objects: 100% (103427/103427), 759.01 MiB | 69.60 MiB/s, done.
Resolving deltas: 100% (69643/69643), done.

This fix allowed me to mirror https://git.slackware.nl/current/ to https://forge.slackware.nl/slackware/distrodevelopment with a sync frequency of 1 hour.

Using Claude to create a work of art

© 2026 Eric Hameleers. All Rights Reserved.

Take the “work of art” with a grain of salt please 🙂 This is an article about computer-generated art but with my own photographs as the source material.

In May, the last of our four cats died. They were two pairs of Holy Birmans, first two little sisters who we took in when they were only 7 weeks old; and later two big brothers whom we adopted when they were over 8 years old.
For the first time in 30 years we do not have any cat in the house. It is silent and sometimes desolate, and I miss the little fluff-balls. But we need to be realistic – we also want to see more of the world and having cats means you need to take care of their well-being. These four are it. There will not be future cats.

Me and my wife decided we wanted to commemorate them by creating some kind of artwork and put that up on the living room wall. We wanted their pictures, and since they were four very different cats, we looked for defining features and old photos that showed their uniqueness. We succeeded in that part, but then came the question, what form and shape should this take? The pictures had different backgrounds, the lighting created different colors, the cats in the pictures had different sizes.

I came up with the idea to create solarized versions of these pictures, give them a kind of Warhol effect with primary colors and bold planes. I looked into ImageMagick, and could not find a good way forward. I looked at online AI image generators and manglers, and none of that was any good either, no consistency in the results.

So I turned to Anthropic’s Claude chat bot. I started with a simple question:

I have four pictures of my cats. I need the cats without the background and primarily the cat heads and/or bodies in a composite picture, which has the solarized style of an Andy Warhol painting

To which the bot responded (it knows I work on Slackware):

Good news: this is very achievable with a Python script using a couple of well-suited libraries, and you can run it entirely on your Slackware machine. Here’s the plan:
Tool stack:

rembg – AI-powered background removal (uses a U2Net model), works excellently on pets/animals. This is the part where ImageMagick would genuinely struggle.
Pillow (PIL) – for cropping, compositing, posterizing, colorizing, and assembling the grid.
Both installable via pip.

The pipeline per cat photo:

Remove background with rembg (outputs a clean RGBA PNG)
Auto-crop to the cat’s bounding box (head/body)
Posterize (reduce to ~4 color levels) to get that flat, graphic look
Apply a flat color tint per panel (Warhol used vivid, clashing hues)
Arrange all four panels in a 2×2 grid

What I need from you to write the script:

Confirm you can install Python packages via pip on your Slackware machine (or in a venv)
Any preference on output size (e.g. 2000x2000px total, so 1000×1000 per panel)?
Do you want each cat in a different color scheme, or the same cat repeated Warhol-style (like the Marilyn print where it’s one subject, four colorways)?
Should the background of each panel be a solid flat color, or transparent/black?

Once you confirm, I’ll write you a clean, self-contained Python script that takes your four JPEGs as input and produces a single composite PNG.

I checked that I could indeed install the dependencies without any issue. I gave it some additional information:

I can install any package using pip, no problem. The image dimensions of 2000×2000 sounds fine.
Each cat should have a different primary color and I would like to associate the four input pictures with specific colors myself. The background is a good question, since I do not yet know what will give the best result. For now I would go with a gradient background that contrasts with the primary colors I will select for the cats and potentially add some smudging to that background.

That produced a script in a few seconds that actually did everything I had imagined for the resulting bitmap wich consisted of 4 panels in a 2×2 grid, one solarized cat image per panel.

Of course, then the creative mind wanted more. It is interesting how this works. I have ideas, I conceptualize them into a prompt, the AI returns Python code that evolves with every new question I have, and actually every iteration of the script does everything I wanted from it.
Eventually, the script was capable of a lot more, tweaks that created better and visually more pleasing versions of the WarholCats.

What was added during this “discussion”:

  • Per-panel configuration:
    • Define the primary color (required) and optionally specify a different background color than the default color complement of the foreground.
    • An optional (x,y) offset to place each cat squarely in the panel’s center.
    • Background styles, several gradients are possible: diagonal, vertical, horizontal, radial; as well as a simple monochrome background.
  • The bot documented all of these configurable parameters in a PANELS block. All parameters were given sensible fallback values in case they are not provided.
  • Optionally a black outline drawn around the cats to make them stand out more – looks better against a monochrome background.
  • Three layouts: a 2×2, 4×1, or 1×4 canvas.
  • The script has defaults set for my wallmount project (I intend to have the result directly printed on dibond aluminium): my LAYOUT = “4×1” and PANEL_SIZE = 2000, allowing for roughly 127 dpi when the image is applied to a 160×40 cm dibond.

Variables like FILL_FRACTION (defaulting to 0.90) and PADDING_FRACTION (defaulting to 0.06), allow for a middle ground for the framing of the cat images. Eventually I also needed an OFFSET variable to move individual cat images into the center of their panel.
The result is the picture at the top of this article. The Python script can be found in the Slackware Forge: https://forge.slackware.nl/alienbob/randomstuff/src/branch/main/WarholCats/warhol_cats.py
The four original cat photos are attached to this blog:

© 2026 Eric Hameleers. All Rights Reserved.

© 2026 Eric Hameleers. All Rights Reserved.

© 2026 Eric Hameleers. All Rights Reserved.

© 2026 Eric Hameleers. All Rights Reserved.

That’s it for today. I wanted to share how a Large Language Model like Anthropic’s Claude is able to boost your creativity with respect for your precious free time. No… this is not vibe coding. The Python code is simple and clean, and is easy to follow. No weird functionality, and proper inlined comments all over.
Feel free to use the script as you see fit. I would however appreciate that you do not share the pictures of my cats or the resulting solarized bitmap any further. The images are copyrighted.
Cheers, Eric

Using the Slackware Community Forge

I wanted to share some news with you. After weeks of hard work and being forced to learn new tech from scratch, the Slackware Community Forge, a git software forge, is now available at https://forge.slackware.nl/ .
It’s not just a git repository server but also a Docker container registry!

 

What the Forge?

I created this Forge as an autonomous and European based alternative to the popular git forges like Github and Gitlab. I have  (well not only I, but a lot of people have) issues with the fact that Github is owned by Microsoft, is fully proprietary and enforces the Microsoft CoPilot AI in weird and unacceptible ways (even though it was ‘by accident’, the tendency and the intent is clear). And Gitlab recently moved office to the US which makes them subjugated to the US administration. Also, Gitlab recently announced their commitment to AI and at the same time will fire 30% of their workforce because of it.
The Slackware  Community Forge is not connected to any form of AI, and it is powered by Forgejo, a fully open source software governed by a European company. meant to be used for hosting free, Open Source and Open Standards Software (OSOSS).

I am not principally opposed to US based companies and their software.  I worked at IBM, use software from Red Hat and my friend Patrick Volkerding runs the US based Slackware Linux company. But I do have concerns about the dangers of potentially having my data controlled by US based entities. Even if my data is encrypted so that content cannot be accessed, the US administration can still request that my own access to my own data is revoked.
My Slackware Cloud Server series of articles is meant to help you (individuals, groups, communities or companies) to implement self-hosted variants of online services that are under your own control, to prevent the risk of losing access to your data, or having your data being monetized by training AI models or by selling it to advertisement platforms.
I invite you to also read those articles!

Now, the Forge.

The Slackware Community Forge is a web-based familiar  interface to manage your own git repositories, use CI/CD runners to validate the changes to your code. The site offers workflows to generate release tarballs. There’s also command-line access via SSH connections using SSH keys.

The CI/CD workflows make use of Slackware Docker images. They are available for stable Slackware release 15.0 and for -current at the time of writing this. Those images come in both 32bit and 64bit flavors. The Slackware Docker images are kept up to date with the changes in Slackware: the images are automatically re-generated when an update to the Slackware ChangeLog.txt is detected.

Of course you can download and use these Docker images locally, the Docker registry is public and does not require an account to download from. For the Slackware “base” images which are really small, the registry URL is https://forge.slackware.nl/slackware/-/packages/container/slackware/versions . The Forge also offers Slackware “builder” images of nearly 2 GB in size, offering all the build tools you would need to compile your project; their registry URL is https://forge.slackware.nl/slackware/-/packages/container/slackware-builder/versions .

If you access the registry via Docker, the hostnames ‘forge.slackware.nl‘ and ‘registry.slackware.nl‘ will both work.

As an example, if you have Docker installed and want to test the image for 64bit Slackware-current, you can run:
$ docker run --rm registry.slackware.nl/slackware/slackware:current bash -c "cat /etc/os-release"
...
Unable to find image 'registry.slackware.nl/slackware/slackware:current' locally
current: Pulling from slackware/slackware
Digest: sha256:74a1caaababd145d40196ee29207c8c0a10602f39463a5077ea1bbe9f05a54d6
Status: Downloaded newer image for registry.slackware.nl/slackware/slackware:current
NAME=Slackware
VERSION="15.0"
ID=slackware
VERSION_ID=15.0
PRETTY_NAME="Slackware 15.0 x86_64 (post 15.0 -current)"
ANSI_COLOR="0;34"
CPE_NAME="cpe:/o:slackware:slackware_linux:15.0"
HOME_URL="http://slackware.com/"
SUPPORT_URL="http://www.linuxquestions.org/questions/slackware-14/"
BUG_REPORT_URL="http://www.linuxquestions.org/questions/slackware-14/"
VERSION_CODENAME=current

The Slackware Community Forge accepts users and organizations that have a relationship to the Slackware ecosystem. If you work on a project that matters to Slackware users, or users of Slackware derivatives, you are invited to request an account. Send an email to forge@slackware.nl from the email address that you want to have associated with your Forge account. I will also need your First and Lastname and the login userID that you want to use.
I will send you the temporary password in reply.

Once you receive your credentials, browse to https://forge.slackware.nl/ and click “Sign In”.
On the sign-in page, click “Sign in with Keycloak”:

This will redirect to the Keycloak server which is the Identity Provider that handles the Single Sign On for Slackware Community Services:

Once you enter your userid and the temporary password you received. you are asked to create a new permanent password.
When the login is complete and you have memorized your new password, you will be directed back from Keycloak to the Forge. There you will be asked whether you want to register a new account or link your account to an existing local account.
Your account only exists in Keycloak, so you select “Register new account” and then Forgejo will create an account in its own database which it will link to your actual Keycloak identity:

You are now ready to start using the Forge in earnest.

Pushing your commits to your repository

Your account lives in the Keycloak Identity Provider (IP). Forgejo’s web interface offers the “Sign in with keycloak” button but when you push your commits to your repository via the commandline interface or via https, Forgejo will not recognize your credentials (it will only recognize local accounts). This is a fundamental aspect of how OIDC authentication works in Forgejo, and it cannot be “fixed” to make Keycloak passwords work for “git push”. This is by design. The OIDC flow requires a browser redirect. There is no way to retrofit it into a non-interactive git credential prompt.
There’s two solutions to this issue:

1: Add a SSH key to your Forge account.

This is recommended for any developer doing regular git work and who wants to access their repositories over a SSH connection.
Assuming that you already have a SSH public/private key pair on your computer called “/home/your_username/.ssh/id_ecdsa_forgejo” that you want to use with the Forge, add that public key in Forgejo:

  • ‘Settings > SSH / GPG keys > Manage SSH keys’ (or browse directly to https://forge.slackware.nl/user/settings/keys)
  • Click ‘Add key’
  • Copy the ASCII text of your public key into the provided field that says:
    Begins with “ssh-ed25519”, “ssh-rsa”, “ecdsa-sha2-nistp256”, “ecdsa-sha2-nistp384”, “ecdsa-sha2-nistp521”, “sk-ecdsa-sha2-nistp256@openssh.com”, or “sk-ssh-ed25519@openssh.com”
  • Give your key a name so that you can recognize it when you add more
  • Click ‘Add key’ again.

Then on your local computer:

  • Add  the following lines to your ~/.ssh.config file (create the file if it does not yet exist and do a “chmod 600” on the file or else ssh will simply refuse to use it):
Host forge.slackware.nl
  Port 2222
  User git
  ServerAliveInterval 20
  IdentityFile /home/your_username/.ssh/id_ecdsa_forgejo
  • Change directory to the clone of your remote repository, and add the remote as follows (it’s a one-time setup, works forever, for all your repositories, and there are no passwords involved at all.):
$ git remote set-url origin forge.slackware.nl:your_username/your_repository.git

All you need to do to push your commits to the remote repository is a:

$ git push origin

No credentials need to be entered at all.
And if this is the first time you connect to the Forge via SSH, you need to accept its SSH server key to continue. This is also a one-time action.

2: Forgejo API token

This works well for  HTTPS workflows or in environments where SSH is blocked. The API token (aka Access token) takes the place of a regular password.
If you had already cloned your repository, the “origin” URL definition in the “.git/config” file inside that repository will look like this:

[remote "origin"]
    url = https://forge.slackware.nl/your_username/your_repository.git
    fetch = +refs/heads/*:refs/remotes/origin/*

You generate an API token as follows:

  • Login to Forgejo
  • Go to ‘Settings > Applications > Access token’ (or go directly to https://forge.slackware.nl/user/settings/applications)
  • Click ‘New access token’
  • Give the token a descriptive name, make it access to ‘All’
  • Select the permissions you want this token to have; at least that should be:
    • Repository: “read and write”
  • Click ‘generate token’
  • Copy and store the token string in a safe place; this token string can not be retrieved later. If you forget it, you can simply create a new token and use that instead.

Then use the token as the password for HTTPS connections:

$ git push origin
Username for 'https://forge.slackware.nl': your_username
Password for 'https://your_username@forge.slackware.nl':
Everything up-to-date

At the “Username” prompt enter your Forgejo username, and at the “Password” prompt enter your API token.

To avoid typing the API token every time, you can store it in git’s credential helper:

$ git config --global credential.helper store

Then do one successful push. Your credentials are saved to the file ~/.git-credentials with mode ‘0600’ which means that only you can read the contents, which look like this:

https://your_username:APITOKEN@forge.slackware.nl

Documentation

In the “forge-docs” repository of the Slackware organization in Forge, you can find:

Finally…

I hope you will appreciate this new service and also start migrating your Github / Gitlab repositories to the Slackware Community Forge.
Try the CI workflows and report any issues you encounter! Note that I am the single administrator and moderator. Be gentle.

 

My commitment is to run this Forge as a stable and long-term service to the Slackware community. I’ve written admin documentation and in time will look for more administrators. Let’s first see if this initiative is going to be used at all 😉

Have fun! Eric

Updated ‘ktown’ packages, and a heads-up

Time for a KDE Plasma6 package refresh.

On KDE’s announcement page, the releases of KDE Gear 26.04.1 and Frameworks 6.26.0 were announced yesterday and today. Since OS packagers have early access to the source tarballs, I had everything compiled and ready for days and could simply push everything into my ‘ktown’ repository today.

I also updated okteta to the new release 0.26.27 (unfortunately still Qt5 based).

Get the new packages from https://slackware.nl/alien-kde/current/latest/ (NL), https://us.slackware.nl/alien-kde/current/latest/ (US), or https://slackware.uk/people/alien-kde/current/latest/ (UK).
Or use their rsync URI’s for commandline downloads.

And a heads-up:

I went to the spring conference of the NLUUG (the Dutch Unix User Group) yesterday . My old colleague (from 40 years ago) and friend Jeroen Baten gave a demonstration of setting up and configuring Forgejo. This is a software forge software which is stewarded by Codeberg e.V in Germany. A fully open source, constraint-free and European alternative to Github or Gitlab. Absolutely relevant given the current political climate where the Orange Clown and his Big Tech billionaire minions try to control the whole world from a US “me! me! me!” perspective.
That same conference also had a presentation from a Dutch government team that maintains their software on code.overheid.nl which is also running Forgejo. It’s really cool to see that finally the Dutch government acts (somewhat) on the commitment to favor open source and open standards above commercial and closed software.

It made me decide that Slackware software projects need a space for their  code that is never in danger of being abused for AI training or where repositories are deleted and access revoked simply because the Orange Clown demands it. The final push to decide that I need to get my own projects off Github came recently when I read this: VS Code v1.117.0 automatically adds GitHub Copilot as your co-author.

My commitment: I am going to setup a Forgejo instance below the slackware.nl domain.

At first, I will work on getting the git repository server up and running with moderated creation of user accounts. Projects that can show a relevance for the Slackware Linux community will get an account. I will be using Keycloak for Identity and Access Management (IAM). Rather conveniently I already have a full setup guide in my Slackware Cloud Server series: https://blog.slackware.nl/slackware-cloud-server-series-episode-2-identity-and-access-management-iam/

The fun will not stop there. I also intend to allow runners and workloads on the Forgejo instance. That will give projects a chance to create CI/CD pipelines for their code. I will be offering Slackware 15.0 and -current Docker containers (64bit but also 32bit) for these runners and will also ensure that the Docker images are re-generated after a ChangeLog.txt update in the Slackware tree.

It’s a lot of ambition but this is something I really want to do. The process will likely end up as another article (or two) in the Slackware Cloud Server series.

I cannot give a timeline, it depends on the complexity of setting up the Docker infrastructure for the Forgejo runners. The git repository server with Keycloak should be rather straightforward. I’ll move my own projects from Github to Forgejo ASAP of course.

When I have updates you’ll hear it first on this blog!

« Older posts

© 2026 Alien Pastures

Theme by Anders NorenUp ↑