1
 
 

I've heard and read variations of this a lot. GitHub never was simply a git frontend. It always had a community and artefacts around the code.

When Github was stable and well loved, people defended it all the time. It was the place to upload code, find contributors, and (after Microslop bought it) even funding for those lucky few popular enough to get it. I understand that change is hard but GitHub's trajectory was written in stone the second Microslop bought it.

Of course, letting go of something is difficult, especially if it feels simple to use and everybody else seems to be using it. But when cracks start to show, the minority will react. The majority will simply tolerate enshittification and reject anything else, for many reasons. Some are valid, some not, it's perspective sometimes.

However, claiming that moving away from Github is easy because git is decentralised... that's either a profound lack of understanding or a bad faith argument. Maybe even both. If you honestly think that's the case, go see how fun it is to contribute to the Linux kernel (or any project using mailing lists). Go to a project hosted on Git Web and try to submit a bug report.

Alternatives

There is hope for one GitHub alternative in particular with a highly unfortunate name for reason I won't get into: forgejo. They have been trying for years to build a federated gitforge (without much success unfortunately), but hope might be on the horizon as Europe starts down the path of leaving foreign Big Tech behind. The Netherlands wants to contribute to forgejo.

Gitlab, another GitHub alternative, has many French institutions as customers, but they have done their absolute best to ignore any requests for federation support. Instead, they've jumped onto the bandwagon and gone all in on AI. Don't expect any progress on that front any time soon.

Why federation

As stated before, GitHub has many things besides git, the biggest one is the community. But to contribute, you need to create an account Microslop's platform. You cannot use that account for smooth experience once you move to an alternative. You can login with it, but that's about it.

Without federation, any alternative is fighting an already immense uphill battle. When you create your user with your repositories on ALTERNATIVE SERVER that cannot connect to ANOTHER SERVER, which forces you to create accounts on every other server.

Federation would solve that. You could search, find and contribute to repositories on the fediverse. It could (hopefully) put a dent in GitHub's omnipresence and allow for users to migrate away once, without creating accounts everywhere. Normal users could also contribute straight from the fediverse without having to create an account on Github first.

Let's hope European countries fund forgejo instead of forking it or starting a completely new project.

2
 
 

Opensource is undeniably a boon to the world. Without it, not only would there be few to no viable options to tech giants, competition would be rendered much more difficult. Fledgling companies would either have to pay for licensed code or implement everything themselves and that would lock out many from even starting companies and dare I say it, even programming as a whole.

But for all the good it has done, there is one thing (amongst many others) that irks me about the opensource community: the phrase "why don't you just...". It is uttered so easily and so thoughtlessly, as if the other person is either too dumb to have considered it, too lazy to have looked it up, or just unwilling to admit it's the right way to do things.

  • I can't figure out how to do X: why don't you just do Y?
  • Bug X has been hampering me: why don't you just fix it?
  • Software X has been crashing and I don't know why: why don't you just....

We could go on and on. Yes, of course, people new to opensource or software in general have trouble voicing their thoughts and approaching problems in the way we software developers are used to. We have experienced the pain of having to track down the source of a bug, had to dig through somebody else's code, read terrible documentation (and consider ourselves lucky it even exists), basically, we have been through the baptism of fire.

Having gone through the hardships, we forget what it was like when we first started and what it was like to acquire the knowledge we have. To some, going through the fire must be the only way because "if I suffered, so should you"; a self-righteous, unsympathetic notion I wholeheartedly loathe.

How to improve

Some might not actually mean it badly, but "just" don't know how to express themselves better. To those who do actually want to help and not sound belittling, please do consider alternative wording:

  • Have you thought of ...
  • Could you try ... and get back with the results?
  • I've had success with ...., maybe that could work for you
  • I think this could help ...

If you are one of those people though who genuinely don't see a problem with it, why don't you just understand?

3
 
 

If you followed ProxMox's wiki page Proxmox VE inside VirtualBox, you might have found yourself unable to connect to the VM, even with port-forwarding. Should that be case, this might help.

Setup

You followed the wiki and have 2 interfaces setup for your VM in virtualbox

  1. Host-only network interface (vboxnet0, or another one)
  2. NAT interface

Why is this happening?

Proxmox does not use systemd-networkd to configure its network interfaces. Everything is in /etc/network/interfaces. And thus, the VM boots with an unconfigured network.

Resolution

Step 1: Find the IP address of your host-only interface on the host

On Linux, macOS and Solaris Oracle VM VirtualBox will only allow IP addresses in 192.168.56.0/21 range to be assigned to host-only adapters.

- Virtualbox documentation

There's a good chance vboxnet0 will thus have 192.168.56.1\24, vboxnet1 then 192.168.57.1\24, and so on. To check, run

ip a | grep -A2 vboxnet

There are 2 VMs on mine and vboxnet1 has the proxmox VM with the IP 192.168.57.1/24

My output

3: vboxnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 0a:00:27:00:00:00 brd ff:ff:ff:ff:ff:ff
    inet 192.168.56.1/24 scope global vboxnet0
       valid_lft forever preferred_lft forever
    inet6 fe80::800:27ff:fe00:0/64 scope link proto kernel_ll 
--
10: vboxnet1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 0a:00:27:00:00:01 brd ff:ff:ff:ff:ff:ff
    altname enx0a0027000001
    inet 192.168.57.1/24 brd 192.168.57.255 scope global vboxnet1
       valid_lft forever preferred_lft forever
    inet6 fe80::800:27ff:fe00:1/64 scope link proto kernel_ll 
--
11: vboxnet2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 0a:00:27:00:00:02 brd ff:ff:ff:ff:ff:ff
    altname enx0a0027000002
12: vboxnet3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 0a:00:27:00:00:03 brd ff:ff:ff:ff:ff:ff
    altname enx0a0027000003
13: vboxnet4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 0a:00:27:00:00:04 brd ff:ff:ff:ff:ff:ff
    altname enx0a0027000004

As for the NAT network interface, the virtualbox doc says

The virtual machine receives its network address and configuration on the private network from a DHCP server integrated into Oracle VM VirtualBox. The IP address thus assigned to the virtual machine is usually on a completely different network than the host. As more than one card of a virtual machine can be set up to use NAT, the first card is connected to the private network 10.0.2.0, the second card to the network 10.0.3.0 and so on.

Therefore we don't need to note down a IP and subnet here.

Step 2: Note the names of the network interfaces in the VM

Linux names the interfaces dynamically, which can be a pain sometimes, so the interface names here might be different from yours!

Lists the network interfaces and their information with

ip address # Or simply `ip a`

I have:

  • enp0s3 as the host-only interface
  • enp0s8 as the NAT interface

My output

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,DOWN,LOWER_UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
    link/ether 08:00:27:e4:f4:50 brd ff:ff:ff:ff:ff:ff
3: enp0s8: <BROADCAST,MULTICAST,DOWN,LOWER_UP> mtu 1500 qdisc pfifo_fast master vmbr0 state DOWN group default qlen 1000
    link/ether 08:00:27:bc:39:f4 brd ff:ff:ff:ff:ff:ff
4: vmbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 08:00:27:e4:f4:50 brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.2/24 scope global vmbr0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fee4:f450/64 scope link 
       valid_lft forever preferred_lft forever

In my output you can already see the problem. vmbr0, which is the bridge interface for VMs that Proxmox will create has 2 problems:

  1. It's using the wrong network interface as a slave (enp0s8 is the NAT network interface; it's the second one)
  2. Had it chosen the right interface (host-only interface has enp0s3 in my setup), the IP address and subnet would've been wrong anyway!

Step 2: Update /etc/network/interfaces

Time to:

  • assign a manually chosen IP address to the bridge interface (vmbr0)
    • I picked 192.168.57.2/24
  • set the bridge interface as the master of the correct interface (enp0s3 is the host-only interface in my case)
  • let DHCP configure the NAT interface (enp0s8 in my case)
IP_SUB="192.168.57.2/24"
IFACE_HOST_ONLY="enp0s3"
IFACE_NAT="enp0s8"
cd /etc/network/
cp interfaces interfaces.bak
# Write configuration
echo " # Manually edited, might be overwritten by Proxmox
auto lo
iface lo inet loopback

auto $IFACE_NAT
iface $IFACE_NAT inet dhcp

auto $IFACE_HOST_ONLY
iface $IFACE_HOST_ONLY inet manual

auto vmbr0
iface vmbr0 inet static
        address $IP_SUB
        bridge-ports $IFACE_HOST_ONLY
        bridge-stp off
        bridge-fd 0
" > interfaces

# Reload networking
ifreload -a

Step 3: test

You should now be able to access Proxmox VE from the host-only network interface using the IP address you chose. In my case that's https://192.168.57.2:8006/

Conclusion

It would be great if Proxmox used systemd-networkd and shoved configuration files into /etc/systemd/network. They are much easier to read, honestly and systemd does a good job at managing stuff. It would work "auto-magically" regardless of environment.

Hopefully this helped somebody and you didn't have to spend a few hours trying to figure this out.

4
 
 

To preface this, no I do not have kids nor am I a child educator. The involvement I have with children is having been one.

TL; DR educate yourself, educate your kids, ease into stuff, explain why


So, what's this about? Well, I've seen it in my private circles, online, and quite recently by multiple governments proposals that children shouldn't access social media, have smartphones, or in some cases even no access to technology. It's a stance I find is borne in fear, uncertainty, doubt, and often ignorance. Now, I cannot claim to be much more educated on the subject than everybody else, but just like everybody has an asshole, I have opinion.

Abstinence is not often a solution to a problem. Sure, you could get pedantic and say abstaining from deadly things like alcohol, drugs and stupid actions, but to that I respond: it's all about the dose. Nigh everything has a lethal dose, even water. Anyway, abstinence from sex is the most common example of abstinence I know of, and it is not known to help. In fact, places that preach and teach abstinence only are more likely to have teenage pregnancies, youth and adults alike who know little to nothing about their bodies, safe sex, consent, and so on.

A lack of education and experience is not a solution I can feel comfortable with. Don't misconstrue my distaste for abstinence as a call for complete freedom. As with many things, everything in moderation (even moderation).

What am I actually proposing then? Education, my fellow humans. Educated actions. Children aren't stupid, they are just vessels that have just started being filled with knowledge, understanding and experience. Teach them about the things they are using or will use. Help them understand the advantages and disadvantages of things. Help them make informed decisions and provide guardrails based upon existing knowledge.

A specific example, too much screentime has been shown to impact mental and oral development in children. They get less time practicing how to flap their lips, discovering their physical limits, training their bodies and aiding physical development, and many other things. (Adults are of course not immune)
However, this world runs on screens and the things displaying things on them. Being unable to operate these devices leaves people behind technologically and reduces independence. Some people never get comfortable with electronic devices. Some because they lack the experience, some out of resistance, some are just afraid of looking dumb, and there are of course many other reasons.
The solution isn't to ban screentime entirely, but to introduce it slowly, provide alternatives, and explain why. But not just "I don't like it" or "you're too young". I hated those as a kid and probably you did too.

I understand that not all parents are educated enough to make informed decisions and that is a much bigger topic than for this brain dump. However just because it isn't that way, doesn't mean we should give up and not try to improve it.

5
 
 

It's been a while since picking up rust, but until now, most of what I've written has been CLI tools, proc macro libs, and async networking stuff. Web/application servers have been kept at arm's length while waiting for something to come around like Django.

For those not in the know, Django is a web framework written in Python. It's opinionated, extensive, has many features, and has stellar documentation. It's old too and had major problems taking advantage of (back them) python's new async capabilities as well as "new" technologies like WebSockets. Popular frameworks popped up in the meantime like Flask and FastAPI that do use new technologies and python language features like type hints, however nothing has really come to be quite like Django.

Django's ORM

As usual, there are camps when it comes to this, but I'm in the "keep SQL away from me" or "one language for all" camp. Django's ORM does a mighty fine job of doing so. It's possible to write a django application without ever seeing a line of SQL. It helps me immensely to just think about models, application logic, and presentation.

Django allows defining your models in python, generating and handling database migrations, making complex queries of 1-1, 1-n, m-n relations without an SQL syntax, storing objects, locking rows, optimising queries (again without knowing SQL), and much more.

Queries

My favorite, powerful query simplifications are QuerySet.select_related() and QuerySet.prefetch_related(). An example of Queryset.select_related:

This is useful for a tree of 1-n objects. An example from the documentation: a Book has an author (foreignkey) which is a Person (1-n), with a hometown (foreignkey) that is a City (1-n). An author can have written many books (n-1), a city can have many people (1-n).

Say you wanted to find 10 books from an author that lives in "Marrakesh" with the associated objects (Book, Person, City). In Django that's

# Hits the database with joins to the author and hometown tables.
books = Book.objects
  .filter(author_hometown__name="Marrakesh")
  .select_related("author__hometown")[:10]
book = book[0]
person = book.author  # Doesn't hit the database.
city = person.hometown  # Doesn't hit the database.

QuerySet.prefetch_related() does the same for m-n / many-to-many relationships and some other queries (see doc). No messing around with SQL, just python.

Migrations

The ORM also takes care of generating and managing migrations for you. To me, that's a major plus as it offloads the need for me to think about whether a specific type exists in the DB of choice. Most of the time django will handle it transparently. There are even django extensions / apps to optimise more SQL query generation like adding views, or choosing which index to use for a specific type or table, and so on.

Django's documentation

If I'm not mistaken, it follows the diátaxis method of documentation

diataxis

which fits the project very well and allows getting started with django very easily as well as finding good, low-level, in-depth information quickly. Many projects have documentation but it's everywhere and nowhere in terms of location (where to find specific things) and depth (high-level vs low-level), making it less optimal for beginners and experts alike. If you want to step up your documentation game, do give diátaxis a shot.

What prompted this

I'm currently 3 days into exploring the rust web framework ecosystem and banging my head against it. It's very commendable what people have written in their free time and shared with the world, so I will not disparage any projects here. It would just be really cool if a django-like, batteries-included project started or reached production quality sometime. The closest candidate I found is Cot.

Cot started in June 2024 and is a long way from django's level but has already grown to something quite impressive. If time allowed it and the project weren't on GitHub, and had a matrix chatroom, it would surely get contributions from me. Here's the announcement on the main dev's blog, which reflects some of my frustrations with the current web framework ecosystem in Rust.

Until Cot is ready, I'll probably be using axum for application server, diesel for the DB-glue, and possibly leptos, yew, or just plain Rinja. Unless of course somebody knows of a django-like web framework in rust that isn't on awesome-rust...

Anti Commercial-AI license