pmbr_boot flag on the GPT s protective MBR. Strict UEFIefidisk0 is empty and lacks both the trust certificatesEF00). Clear thepmbr_boot flag from the MBR. 2. Binaryshim and grub-efi packages. Usegrub2-mkconfig to populate the new ESP. 3. Trustvirt-fw-vars utility on theefidisk. 4. Boot Pinning: Explicitly setBootOrder to point to the shimx64.efivirt-fw-vars --append-boot-filepath.
root):
# Map and Clean MBR
DEV=$(rbd map pool/disk)
parted -s $DEV disk_set pmbr_boot off
# Inject Trust and Boot Path (VM must be stopped)
virt-fw-vars --inplace /dev/rbd/mapped_efidisk \
--enroll-redhat \
--add-db <GUID> /path/to/ipa-ca.crt \
--append-boot-filepath '\EFI\centos\shimx64.efi' \
--sb
| Series: | Sector General #7 |
| Publisher: | Orb |
| Copyright: | 1987 |
| Printing: | May 2003 |
| ISBN: | 0-7653-0663-8 |
| Format: | Trade paperback |
| Pages: | 252 |
A few months ago, in June 2025, I joined Chainguard, a company focused on software supply chain security.
This post is a reflection on how I got here, what I ve been doing, and why this role feels like a natural
fit for my interests in Linux and open source technology.
A map of Vietnam with points of places we went to labeled. CARTO MAPTILER OPENSTREETMAP
A picture of the park we roamed around in Ho Chi Minh City. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
This is the restaurant Badri s friend took us to. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
One of the dishes we had in the restaurant. This one was especially tasty. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
One of the dishes we had in the restaurant. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
These noodles are called Pho and are very popular in Vietnam. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
Interior of our train coach. Trains in Vietnam don t have side berths, unlike India. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
A picture of the berths from our coach. It had three tiers, similar to a 3 AC coach in Indian trains. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
The train had a cabin to put the bags in. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
Nha Trang train station. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
I got a complimentary cup of green tea along with coffee in Nha Trang. In this trip, Badri and I found out that this is customary at local places in Vietnam. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
Eggs being cooked on a pan for my order. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
The beach we went to in Nha Trang. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
This one was shot in the city center. In this trip, Badri and I found out that this is customary at local places in Vietnam. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
Inside a Highlands Coffee cafe in Nha Trang. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
A coffee I got from Highlands Coffee in Nha Trang. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
The restaurant we went to in Nha Trang. The word Chay in the name means it was a vegan restaurant. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
Soupy noodles we got at that restaurant. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
Dry noodles we got at that restaurant. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
This was the place we had our coffee in Tra Kieu. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
Photo of Badri with taxi driver. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
A picture of Tra Kieu area near the train station we got down at. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
Our breakfast in Hoi An. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
A photo of the hostel we stayed in Hoi An. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
Typical yellow house with gabled roof in Hoi An old town. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
Egg coffee I had in Hoi An. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
Bahn Bao in Hue. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
Hot Pot. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
Added soup to the noodles. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
Steamed rolls made of rice flour. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
Menu from a restaurant in Ho Chi Minh City with detailed description of the food. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
Our berths in the train. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
Egg coffee in Hanoi. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
Hanoi train street is a tourist attraction in Hanoi. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
A picture of pho we had in Hanoi. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
Bahn it is served packed in banana leaves. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
Bahn it. Photo by Ravi Dwivedi, released under CC-BY-SA 4.0.
WWW::Mechanize::Chrome library and its test suite. ThisResource was not cached errors duringsaveResources, we implemented a fully asynchronous fallback_saveResourceTree. By chaining_cached_document with DOM.getOuterHTMLfile:// access.File name too long errors,MAX_PATH limit is 260filenameFromUrl was hardened. The filenamedefault_executable_names was expanded to includeheadless_shell and search paths were updated to include/usr/lib64/chromium-browser/.DOM.documentUpdated events could invalidatenodeIds immediately after navigation, causing XPath queriessleep(0.25s) was added after page loads to ensure the DOMualarm was a blocker for Windows, wheret::helper::set_watchdog functionalarm() (seconds) on Windowsualarm (microseconds) on Unix-like systems, enablinglib/ and to always runmake clean and perl Makefile.PL to ensureMETA.json and META.yml reflect the newad2 Windows Server 2025 instance was restored andad2 Windows_future API.xpath, field,get, etc.) into thin wrappers around new non-blocking..._future counterparts. This moved timeout management tot/lib/t/helper.pm, was created tosafe_get,safe_xpath) were implemented there, usingFuture->wait_any to race asynchronous operations against# Example test helper implementation
sub safe_xpath
my ($mech, $query, %options) = @_;
my $timeout = delete $options timeout 5;
my $call_f = $mech->xpath_future($query, %options);
my $timeout_f = $mech->sleep_future($timeout)->then(sub Future->fail("Timeout") );
return Future->wait_any($call_f, $timeout_f)->get;
t/50-tick.t)WWW::Mechanize::Chrome::Node was storing[key, val, key, val]), which wast::helper that listens on an ephemeral port; the backgroundget_set_value_future non-blocking required first making its_field_by_name, asynchronous. This culminatedform_name,form_id, etc.) to use the new asynchronous_future lookups, which was a key step in mitigating the_process_eval_result helper to centralize the parsing ofRuntime.evaluate. This ensures consistenteval_in_page) and asynchronous (eval_future)$self and the $response object, creating aScalar::Util::weaken on both $self and any->then block that is stored on an object.
wantarray): AwantarrayFuture->then blocks. This causedxpath to return incorrect results (e.g., awantarray in the synchronous_future method, and# Synchronous Wrapper
sub xpath($self, $query, %options)
$options wantarray = wantarray; # 1. Capture
return $self->xpath_future($query, %options)->get; # 2. Pass
# Asynchronous Implementation
sub xpath_future($self, $query, %options)
my $wantarray = delete $options wantarray ; # 3. Retrieve
# ... async logic ...
return $doc->then(sub
if ($wantarray) # 4. Respect
return Future->done(@results);
else
return Future->done($results[0]);
);
decoded_content()__body_future. This was implemented by storing the$response-> __body_future ). To make this more robust,about:blankXMLSerializer to get the live DOM content.
Future->then. Callbacks were updated to use optionalsub($result = undef) ... ) to gracefullysetDocumentContent is parsed differently than contentdocument.evaluate) against the live DOM, bypassing the_future variants.t/lib/t/helper.pm), not in the core library.wantarrayFuture chain to ensure correctwarn, note, diag) should be$self->log('debug', ...)MutationObserver Saga (March 19)
With most of the library refactored to be asynchronous, one stubbornt/65-is_visible.t, continued to fail with timeouts.wait_until_visible polling logic with a moreMutationObserver.
repeat sleep loop with an event-drivenMutationObserver in JavaScript that would notify PerlcallFunctionOn_future.setTimeout, which expected milliseconds.MutationObserver sPromise would never resolve, even after thecheckVisibility JavaScript logic inside the observerconsole.log tracing, failed to resolve theChrome.pm module.MutationObserver approachMutationObserver, a strategic decision was made to revertMutationObserver implementation, when integrated viacallFunctionOn_future with awaitPromise,MutationObserver code fromWWW::Mechanize::Chrome.pm and restore the originalrepeat sleep polling mechanism. A stable,t/lib/t/helper.pmsafe_wait_until_* wrappers werewait_any andsleep_future) that raced against the underlying pollingt/78-memleak.t persisted, but only on the Windowsad2 environment. This required a different approach thanon_dialog event listener was not being broken on Windows,on_dialog(undef) in DESTROY) were notIO::Async event loop implementation on Windows, and theTest::Memory::Cycle module. The cycle report was identicalon_dialog(undef) call fromclose() to DESTROY().deleteing the listener and callbackDESTROY.$self->remove_listener and$self->target->unlisten in a mistaken attempt to findt/78-memleak.t was wrapped in a conditionalTODO block that only executes on Windowsif ($^O =~ /MSWin32/i)), formally acknowledging the bugprove --nocount --jobs 3 -I local/ -bl xt t directly. This-It/lib include path, whicht::helper module.Can't locate t/helper.pm in @INC.Makefile.PL revealed a custom MY::test block-It/lib flag into themake test command. This confirmed thatmake test is the correct, canonical way to run the test.github/workflows/linux.yml file was modified to replaceprove call with make test in theRun Tests step. This ensures the CI environment runs theWWW::Mechanize::Chrome test suite is now stable and
Linux kernel security modules provide a good additional layer of security around individual programs by restricting what they are allowed to do, and at best block and detect zero-day security vulnerabilities as soon as anyone tries to exploit them, long before they are widely known and reported. However, the challenge is how to create these security profiles without accidentally also blocking legitimate actions. For MariaDB in Debian and Ubuntu, a new AppArmor profile was recently created by leveraging the extensive test suite with 7000+ tests, giving good confidence that AppArmor is unlikely to yield false positive alerts with it.
AppArmor is a Mandatory Access Control (MAC) system, meaning that each process controlled by AppArmor has a sort of an allowlist called profile that defines all capabilities and file paths a program can access. If a program tries to do something not covered by the rules in its AppArmor profile, the action will be denied on the Linux kernel level and a warning logged in the system journal. This additional security layer is valuable because even if a malicious user found a security vulnerability some day in the future, the AppArmor profile severely restricts the ability to exploit it and gain access to the operating system.
AppArmor was originally developed by Novell for use in SUSE Linux, but nowadays the main driver is Canonical and AppArmor is extensively used in Ubuntu and Debian, and many of their derivatives (e.g. Linux Mint, Pop!_OS, Zorin OS) and in Arch. AppArmor s benefit compared to the main alternative SELinux (used mainly in the RedHat/Fedora ecosystem) is that AppArmor is easier to manage. AppArmor continues to be actively developed, with new major version 5.0 expected to arrive soon.
I also have some personal history contributing some notification handler scripts in Python and I also created the website that AppArmor.net still runs.
/var/log/audit/audit.log or run journalctl -ke --grep=apparmor.
A typical denial entry for MariaDB will look like this (split across multiple lines for legibility):
msg=audit(1700000000.123:456): apparmor="DENIED" operation="open"
profile="/usr/sbin/mariadbd" name="/custom/data/path/test.ibd" pid=1234
comm="mariadbd" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0open, mknod, file_mmap, file_perm)./usr/sbin/mariadbd profile).mariadbd).r for read, w for write)./etc/apparmor.d/ or drop a local customization file in at /etc/apparmor.d/local/. If the denied action looks malicious, the sysadmin should start a security investigation and if needed report a suspected zero-day vulnerability to the upstream software vendor (e.g. Ubuntu customers to Canonical, or MariaDB customers to MariaDB).
complain mode and iterated on the allowlist by running the full mariadb-test-run with all MariaDB plugins and features enabled until we had a comprehensive yet clean list of rules.
To be extra diligent, we also reworked the autopkgtest for MariaDB in Debian and Ubuntu CI systems to run with the AppArmor profile enabled and to print all AppArmor notices at the end of the run, making it easy to detect now and in the future if the MariaDB test suite triggers any AppArmor denials. If any test fails, the release would not get promoted further, protecting users from regressions.
While developing and triggering manual test runs we used the maximal achievable test suite with 7177 tests. The test is however so extensive it takes over two hours to run, and it also has some brittle tests, so the standard test run in Debian and Ubuntu autopkgtest is limited just to MariaDB s main suite with about 1000 tests. Having some tests fail while testing the AppArmor profile was not a problem, because we didn t need all the tests to pass we merely needed them to run as many code paths as possible to see if they run any system calls not accounted for in the AppArmor profile.
Note that extending the profile was not just mechanical copying of log messages to the profile. For example, even though a couple of tests involve running the dash shell, we decided to not allow it, as it opens too much of a path for a potential exploit to access the operating system.
The result of this effort is a modernized, robust profile that is now production-ready. Those interested in the exact technical details can read the Debian Bug#1130272 and the Merge Request discussions at salsa.debian.org, which hosts the Debian packaging source code.
complain mode, so AppArmor only logs would-be-denials without blocking anything. The AppArmor profile was switched to enforce mode only in the very latest MariaDB revision 1:11.8.6-4 in Debian, and a NEWS item issued to help increase user awareness of this change. It is also slated for the upcoming Ubuntu 26.04 Resolute Raccoon release next month, providing out-of-the-box hardening for the wider ecosystem.
While automated testing is extensive, it cannot simulate everything. Most notably various complicated replication topologies and all Galera setups are likely not covered. Thus, I am calling on the community to deploy this profile and monitor for any audit denials in the kernel logs. If you encounter unexpected behavior or legitimate denials, please submit a bug report via the Debian Bug Tracking System.
To ensure you are running the latest MariaDB version, run apt install --update --yes mariadb-server. To view the latest profile rules, run cat /etc/apparmor.d/mariadbd and to see if it is enforced review the output of aa-status. To quickly check if there were any AppArmor denials, simply run journalctl -k grep -i apparmor grep -i mariadb.
| Series: | Lady Astronaut #4 |
| Publisher: | Tor |
| Copyright: | 2025 |
| ISBN: | 1-250-23703-3 |
| Format: | Kindle |
| Pages: | 390 |
# dig -t txt _spf.google.com grep spf1 _spf.google.com. 300 IN TXT "v=spf1 ip4:74.125.0.0/16 ip4:209.85.128.0/17 ip6:2001:4860:4864::/56 ip6:2404:6800:4864::/56 ip6:2607:f8b0:4000::/36 ip6:2800:3f0:4000::/36 ip6:2a00:1450:4000::/36 ip6:2c0f:fb50:4000::/36 ~all" # dig -t txt outlook.com grep spf1 outlook.com. 126 IN TXT "v=spf1 include:spf2.outlook.com -all" # dig -t txt _spf.mail.yahoo.com grep spf1 _spf.mail.yahoo.com. 1800 IN TXT "v=spf1 ptr:yahoo.com ptr:yahoo.net ip4:34.2.71.64/26 ip4:34.2.75.0/26 ip4:34.2.84.64/26 ip4:34.2.85.64/26 ip4:34.2.64.0/22 ip4:34.2.68.0/23 ip4:34.2.70.0/23 ip4:34.2.72.0/22 ip4:34.2.78.0/23 ip4:34.2.80.0/23 ip4:34.2.82.0/23 ip4:34.2.84.0/24 ip4:34.2.86.0" "/23 ip4:34.2.88.0/23 ip4:34.2.90.0/23 ip4:34.2.92.0/23 ip4:34.2.85.0/24 ip4:34.2.94.0/23 ?all" # dig -t txt icloud.com grep spf1 icloud.com. 3586 IN TXT "v=spf1 ip4:17.41.0.0/16 ip4:17.58.0.0/16 ip4:17.142.0.0/15 ip4:17.57.155.0/24 ip4:17.57.156.0/24 ip4:144.178.36.0/24 ip4:144.178.38.0/24 ip4:112.19.199.64/29 ip4:112.19.242.64/29 ip4:222.73.195.64/29 ip4:157.255.1.64/29" " ip4:106.39.212.64/29 ip4:123.126.78.64/29 ip4:183.240.219.64/29 ip4:39.156.163.64/29 ip4:57.103.64.0/18" " ip6:2a01:b747:3000:200::/56 ip6:2a01:b747:3001:200::/56 ip6:2a01:b747:3002:200::/56 ip6:2a01:b747:3003:200::/56 ip6:2a01:b747:3004:200::/56 ip6:2a01:b747:3005:200::/56 ip6:2a01:b747:3006:200::/56 ~all"In most IM systems there is a strong connection between people who communicate. If I send you two direct messages they will appear in the same room, and if someone else tries forging messages from me (EG by replacing the c and e letters in my address with Cyrillic letters that look like them or by mis-spelling my name) a separate room will be created and it will be obvious that something unexpected is happening. Protecting against the same attacks in email requires the user carefully reading the message, given that it s not uncommon for someone to start a message to me with Hi Russel (being unable to correctly copy my name from the To: field of the message they are writing) it s obvious that any security measure relying on such careful reading will fail. The IM protections against casual forgery also apply to rooms with multiple users, a new user can join a room for the purpose of spamming but they can t send a casual message impersonating a member of the room. A user can join a Matrix room I m in with the name Russell from another server but the potential for confusion will be minimised by a message notifying everyone that another Russell has joined the room and the list of users will show two Russells. For email the protections against forgery when sending to a list server are no different than those when sending to an individual directly which means very weak protections. Authenticating the conversation context once as done with IM is easier and more reliable than authenticating each message independently. Is Email Sucking the Main Technical Difference? It seems that the problems with forgery, spam, and general confusion when using email are a large part of the difference between email and IM. But in terms of technical issues the fact that email has significantly more users (if only because you need an email account to sign up for an IM system) is a major difference. Internet email is currently a universal system (apart from when it breaks from spam) and it has historically been used to gateway to other email systems like Fidonet, Uucp, and others. The lack of tight connection between parties that exchange messages in email makes it easier to bridge between protocols but harder to authenticate communication. Most of the problems with Internet email are not problems for everyone at all times, they are technical trade-offs that work well for some situations and for some times. Unfortunately many of those trade-offs are for things that worked well 25+ years ago. The GUI From a user perspective there doesn t have to be a great difference between email and IM. Email is usually delivered quickly enough to be in the same range as IM. The differences in layout between IM client software and email client software is cosmetic, someone could write an email client that organises messages in the same way as Slack or another popular IM system such that the less technical users wouldn t necessarily know the difference. The significant difference in the GUI for email and IM software was a design choice. Conversation Organisation The most significant difference in the operation of email and IM at the transport level is the establishment of connections in IM. Another difference is the fact that there are no standards implemented for the common IM implementations to interoperate which is an issue of big corporations creating IM systems and deliberately making them incompatible. The methods for managing email need to be improved. Having an inbox that s an unsorted mess of mail isn t useful if you want to track one discussion, breaking it out into different sub folders for common senders (similar to IM folders for DMs) as a standard feature without having to setup rules for each sender would be nice. Someone could design an email program with multiple layouts, one being the traditional form (which seems to be copied from Eudora [3]) and one with the inbox (or other folders) split up into conversations. There are email clients that support managing email threads which can be handy in some situations but often isn t the best option for quickly responding to messages that arrived recently. Archiving Most IM systems have no method for selectively archiving messages, there s a request open for a bookmark function in Matrix and there s nothing stopping a user from manually copying a message. But there s nothing like the convenient ability to move email to an archive folder in most IM systems. Without good archiving IM is a transient medium. This is OK for conversations but not good for determining the solutions to technical problems unless there is a Wiki or other result which can be used without relying on archives. Composing Messages In a modern email client when sending a message it prompts you for things that it considers complete, so if you don t enter a Subject or have the word attached in the message body but no file is attached to the message then it will prompt you to confirm that you aren t making a mistake. In an IM client the default is usually that pressing ENTER sends the message so every paragraph is a new message. IM clients are programmed to encourage lots of short messages while email clients are programmed to encourage more complete messages. Social Issues Quality The way people think about IM and email is very different, as one example there was never a need for a site like nohello.net for email. The idea that it s acceptable to use even lower quality writing in IM than people tend to use in email seems to be a major difference between the communication systems. It can be a good thing to have a chatty environment with messages that are regarded as transient for socialising, but that doesn t seem ideal for business use. Ownership Email is generally regarded as being comparable to physical letters. It is illegal and widely considered to be socially wrong to steal a letter from someone s letterbox if you regret sending it. In email the only unsend function I m aware of is that in Microsoft software which is documented to only work within the same organisation, and that only works if the recipient hasn t read the message. The message is considered to be owned by the recipient. But for IM it s a widely supported and socially acceptable function to delete or edit messages that have been sent. The message is regarded as permanently the property of the sender. What Should We Do? Community Creators When creating a community (and I use this in the broadest sense including companies) you should consider what types of communication will work well. When I started the Flounder group [4] I made a deliberate decision that non-free communication systems go against the aim of the group, I started it with a mailing list and then created a Matrix room which became very popular. Now the list hardly gets any use. It seems that most of the communication in the group is fairly informal and works better with IM. Does it make sense to use both? Should IM systems be supplemented with other systems that facilitate more detail such as a Wiki or a Lemmy room/instance [5] to cover the lack of long form communication? I have created a Lemmy room for Flounder but it hasn t got much interest so far. It seems that almost no-one makes a strategic decision about such issues. Software Developers It would be good to have the same options for archiving IM as there are for email. Also some options to encourage quality in IM communication similar to the way email clients want confirmation before sending messages without a subject or that might be missing an attachment. It would also be good to have better options for managing conversations in email. The Inbox as currently used is good for some things but a button to switch between that and a conversation view would be good. There are email clients that allow selecting message sort order and aggregation (kmail has a good selection of options) but they are designed for choosing a single setup that you like not between multiple views based on the task you are doing. It would be good to have links between different communication systems, if users had the option of putting their email address in their IM profile it would make things much easier. Having entirely separate systems for email and IM isn t good for users. Users The overall communications infrastructure could be improved if more people made tactical decisions about where and how to communicate. Keep the long messages to email and the chatty things to IM. Also for IM just do the communication not start with hello . To discourage wasting time I generally don t reply to messages that just say hello unless it s the first ever IM from someone. Conclusion A large part of the inefficiencies in electronic communication are due to platforms and usage patterns evolving with little strategic thought. The only apparent strategic thought is coming from corporations that provide IM services and have customer lock in at the core of their strategies. Free software developers have done great work in developing software to solve tactical problems but the strategies of large scale communications aren t being addressed. Email is loosely coupled and universal while IM is tightly coupled, authenticated, and often siloed. This makes email a good option for initial contact but a risk for ongoing discussions. There is no great solution to these issues as they are largely a problem due to the installed user base. But I think we can mitigate things with some GUI design changes and strategic planning of communication.
fortunes-debian-hints and submitted possible changes in the hints.reportbug --ui gtk
detecting the wrong dependencies),
devscript (delete unused code from debrebuild
and add recommended dependency),
wcurl (format help for 80 columns).
Carles submitted a bug report for apt
not showing the long descriptions of packages.glibc/gcc-15/zlib transition for the s390 31-bit removal. This last one
included reviewing and requeueing lots of autopkgtests due to britney losing a
lot of results.poppler updates to experimental for a new transition.pycparser, python-confuse,
python-cffi, python-mitogen, python-pip, wheel, platformdirs,
python-authlib, and python-virtualenv.dh-python and merged MRs.musl-linux-any, hurd-any or s390x)
or specific packages (such as binutils, brotli or fontconfig).rocblas #1126608,
python-memray #1126944
upstream
and greetd #1129070 with varying success.build source job is handled by Salsa CI. Thanks a
lot to Jochen for his work on this.ipp-usb, brlaser and gutenprint.OpenSSH, both of which allowed code execution via ProxyCommand in some
cases. The trixie update also included a fix for
mishandling of PerSourceMaxStartups.bts forwarded commands to be discarded.pkg_resources module.Vcs-Git at it. However:
debian/, or something even stranger.
debian/1.2.3-7 tag on salsa corresponds precisely to what was actually uploaded. dput-based tooling (such as gbp buildpackage) doesn t cross-check the .dsc against git.
Vcs-Git and Salsa to build a Debian derivative? You could not.
tag2upload and dgit do solve this problem. When you upload, they:
archive/debian/1.2.3-7 tag to a single central git depository, *.dgit.debian.org;
Dgit field in .dsc so that clients can tell (using the ftpmaster API) that this was a git-based upload, what the corresponding git objects are, and where to find them.
dgit clone, as advertised in e.g. dgit-user(7). For dput-based uploads, it falls back to importing the source package.)
Adopting tag2upload - the minimal change
tag2upload is a substantial incremental improvement to many existing workflows. git-debpush is a drop-in replacement for building, signing, and uploading the source package.
So, you can just adopt it without completely overhauling your packaging practices. You and your co-maintainers can even mix-and-match tag2upload, dgit, and traditional approaches, for the same package.
Start with the wiki page and git-debpush(1) (ideally from forky aka testing).
You don t need to do any of the other things recommended in this article.
Overhauling your workflow, using advanced git-first tooling
The rest of this article is a guide to adopting the best and most advanced git-based tooling for Debian packaging.
Assumptions
gbp pq and/or quilt, and often used with git-buildpackage. You previously used gbp import-orig.
origin remote set to Salsa.
master. Personally I think we should use main but changing your main branch name is outside the scope of this article.
rationale Much traditional Debian tooling like
quiltandgbp pquses the patches-unapplied branch format, which stores the delta as patch files indebian/patches/, in a git tree full of unmodified upstream files. This is clumsy to work with, and can even be an alarming beartrap for Debian outsiders.
git merge when merging from upstream.
This is appropriate if your package has no or very few upstream changes. It is a good approach if the Debian maintainers and upstream maintainers work very closely, so that any needed changes for Debian are upstreamed quickly, and any desired behavioural differences can be arranged by configuration controlled from within debian/.
This is the approach documented more fully in our workflow tutorial dgit-maint-merge(7).
First, establish which upstream git tag corresponds to the version currently in Debian. From the sake of readability, I m going to pretend that upstream version isrationale Many maintainers have been importing upstream tarballs into git, for example by using
gbp import-orig. But in reality the upstream tarball is an intermediate build product, not (just) source code. Using tarballs rather than git exposes us to additional supply chain attacks; indeed, the key activation part of the xz backdoor attack was hidden only in the tarball! git offers better traceability than so-called pristine upstream tarballs. (The word pristine is even a joke by the author of pristine-tar!)
1.2.3, and that upstream tagged it v1.2.3.
Edit debian/watch to contain something like this:
version=4
opts="mode=git" https://codeberg.org/team/package refs/tags/v(\d\S*)You may need to adjust the regexp, depending on your upstream s tag name convention. If debian/watch had a files-excluded, you ll need to make a filtered version of upstream git.
Probably, the currentrationale We need some upstream tarball for the
3.0 (quilt)source format to work with. It needs to correspond to the git commit we re using as our upstream. We don t need or want to use a tarball from upstream for this. The.origis just needed so a nice legacy Debian source package (.dsc) can be generated.
.orig in the Debian archive, is an upstream tarball, which may be different to the output of git-archive and possibly even have different contents to what s in git. The legacy archive has trouble with differing .origs for the same upstream version .
So we must until the next upstream release change our idea of the upstream version number. We re going to add +git to Debian s idea of the upstream version. Manually make a tag with that name:
git tag -m "Compatibility tag for orig transition" v1.2.3+git v1.2.3~0
git push origin v1.2.3+gitIf you are doing the packaging overhaul at the same time as a new upstream version, you can skip this part.
git branch -f old-master # make a note of the old git representation
git reset --hard v1.2.3 # go back to the real upstream git tag
git checkout old-master :debian # take debian/* from old-master
git commit -m "Re-import Debian packaging on top of upstream git"
git merge --allow-unrelated-histories -s ours -m "Make fast forward from tarball-based history" old-master
git branch -d old-master # it's incorporated in our history nowIf there are any patches, manually apply them to your main branch with git am, and delete the patch files (git rm -r debian/patches, and commit). (If you ve chosen this workflow, there should be hardly any patches,)
rationale These are some pretty nasty git runes, indeed. They re needed because we want to restart our Debian packaging on top of a possibly quite different notion of what the upstream is.
git-debrebase -fdiverged convert-from-gbp upstream/1.2.3
git-debrebase -fdiverged -fupstream-not-ff new-upstream 1.2.3+gitIf you had patches which patched generated files which are present only in the upstream tarball, and not in upstream git, you will encounter rebase conflicts. You can drop hunks editing those files, since those files are no longer going to be part of your view of the upstream source code at all.
rationale The force option
-fupstream-not-ffwill be needed this one time because your existing Debian packaging history is (probably) not based directly on the upstream history.-fdivergedmay be needed because git-debrebase might spot that your branch is not based on dgit-ish git history.
dgit fetch
git show dgit/dgit/sid:debian/changelog
# check that you have the same version number
git merge -s ours --allow-unrelated-histories -m 'Declare fast forward from pre-git-based history' dgit/dgit/sidChange the source format
Delete any existing debian/source/options and/or debian/source/local-options.
debian/source/format to 1.0. Add debian/source/options containing -sn.
rationale We are using the 1.0 native source format. This is the simplest possible source format - just a tarball. We would prefer 3.0 (native) , which has some advantages, but dpkg-source between 2013 (wheezy) and 2025 (trixie) inclusive unjustifiably rejects this configuration. You may receive bug reports from over-zealous folks complaining about the use of the 1.0 source format. You should close such reports, with a reference to this article and to #1106402.
debian/source/format contains 3.0 (quilt).
README.source to at least mention dgit-maint-merge(7) or dgit-maint-debrebase(7), and to tell people not to try to edit or create anything in debian/patches/. Consider saying that uploads should be done via dgit or tag2upload.
Check that your Vcs-Git is correct in debian/control. Consider deleting or pruning debian/gbp.conf, since it isn t used by dgit, tag2upload, or git-debrebase.
debian/changelog about the git packaging change.
git-debrebase new-upstream will have added a new upstream version stanza to debian/changelog. Edit that so that it instead describes the packaging change. (Don t remove the +git from the upstream version number there!)
rationale Squashing could destroy your carefully-curated delta queue. It would also disrupt git-debrebase s git branch structure.
debian/salsa-ci.yml containing
include:
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.ymlIn your Salsa repository, under Settings / CI/CD , expand General Pipelines and set CI/CD configuration file to debian/salsa-ci.yml.
rationale Your project may have an upstream CI config in
.gitlab-ci.yml. But you probably want to run the Debian Salsa CI jobs. You can add various extra configuration todebian/salsa-ci.ymlto customise it. Consult the Salsa CI docs.
debian/salsa-ci.yml:
.git-debrebase-prepare: &git-debrebase-prepare
# install the tools we'll need
- apt-get update
- apt-get --yes install git-debrebase git-debpush
# git-debrebase needs git user setup
- git config user.email "salsa-ci@invalid.invalid"
- git config user.name "salsa-ci"
# run git-debrebase make-patches
# https://salsa.debian.org/salsa-ci-team/pipeline/-/issues/371
- git-debrebase --force
- git-debrebase --noop-ok make-patches
# make an orig tarball using the upstream tag, not a gbp upstream/ tag
# https://salsa.debian.org/salsa-ci-team/pipeline/-/issues/541
- git-deborig
.build-definition: &build-definition
extends: .build-definition-common
before_script: *git-debrebase-prepare
build source:
extends: .build-source-only
before_script: *git-debrebase-prepare
variables:
# disable shallow cloning of git repository. This is needed for git-debrebase
GIT_DEPTH: 0rationale Unfortunately the Salsa CI pipeline currently lacks proper support for git-debrebase (salsa-ci#371) and has trouble directly using upstream git for orig tarballs (#salsa-ci#541). These runes were based on those in the Xen package. You should subscribe to the tickets #371 and #541 so that you can replace the clone-and-hack when proper support is merged.
master. Set Allowed to merge to Maintainers . Set Allowed to push and merge to No one . Leave Allow force push disabled.
This means that the only way to land anything on your mainline is via a Merge Request. When you make a Merge Request, gitlab will offer Set to auto-merge . Use that.
gitlab won t normally merge an MR unless CI passes, although you can override this on a per-MR basis if you need to.
(Sometimes, immediately after creating a merge request in gitlab, you will see a plain Merge button. This is a bug. Don t press that. Reload the page so that Set to auto-merge appears.)
autopkgtests
Ideally, your package would have meaningful autopkgtests (DEP-8 tests) This makes Salsa CI more useful for you, and also helps detect and defend you against regressions in your dependencies.
The Debian CI docs are a good starting point. In-depth discussion of writing autopkgtests is beyond the scope of this article.
Day-to-day work
With this capable tooling, most tasks are much easier.
Making changes to the package
Make all changes via a Salsa Merge Request. So start by making a branch that will become the MR branch.
On your MR branch you can freely edit every file. This includes upstream files, and files in debian/.
For example, you can:
git cherry-pick an upstream commit.
git am a patch from a mailing list or from the Debian Bug System.
git revert an earlier commit, even an upstream one.
git-rebase to squash/edit/combine/reorder commits.
git-debrebase -i to squash/edit/combine/reorder commits. When you are happy, run git-debrebase conclude.
Do not edit debian/patches/. With git-debrebase, this is purely an output. Edit the upstream files directly instead. To reorganise/maintain the patch queue, use git-debrebase -i to edit the actual commits.
apt-get build-dep .
dpkg-buildpackage -uc -bIdeally this will leave git status clean, with no modified or un-ignored untracked files. If it shows untracked files, add them to .gitignore or debian/.gitignore as applicable.
If it dirties the tree, consider trying to make it stop doing that. The easiest way is probably to build out-of-tree, if supported upstream. If this is too difficult, you can leave the messy build arrangements as they are, but you ll need to be disciplined about always committing, using git clean and git reset, and so on.
For formal binaries builds, including for testing, use dgit sbuild as described below for uploading to NEW.
Uploading to Debian
Start an MR branch for the administrative changes for the release.
Document all the changes you re going to release, in the debian/changelog.
dgit fetch sid
gbp dch --ignore-branch --since=dgit/dgit/sid --git-log=^upstream/main(For the first upload after switching to using tag2upload or dgit you needrationale
--ignore-branchis needed because gbp dch wrongly thinks you ought to be running this onmaster, but of course you re running it on your MR branch. The--git-log=^upstream/mainexcludes all upstream commits from the listing used to generate the changelog. (I m assuming you have anupstreamremote and that you re basing your work on theirmainbranch.) If there was a new upstream version, you ll usually want to write a single line about that, and perhaps summarise anything really important.
--since=debian/1.2.3-1, where 1.2.3-1 is your previous DEP-14 tag, because dgit/dgit/sid will be a dsc import, not your actual history.)
UNRELEASED to the target suite, and finalise the changelog. (Note that dch will insist that you at least save the file in your editor.)
dch -r
git commit -m 'Finalise for upload' debian/changelogMake an MR of these administrative changes, and merge it. (Either set it to auto-merge and wait for CI, or if you re in a hurry double-check that it really is just a changelog update so that you can be confident about telling Salsa to Merge unverified changes .)
Now you can perform the actual upload:
git checkout master
git pull --ff-only # bring the gitlab-made MR merge commit into your local treegit-debpushgit-debpush --quilt=linear--quilt=linear is needed only the first time, but it is very important that first time, to tell the system the correct git branch layout.
dgit can help take care of the build and upload for you:
Prepare the changelog update and merge it, as above. Then:
git-deborig
git-debrebase quickrationale Source package format 3.0 (quilt), which is what I m recommending here for use with git-debrebase, needs an orig tarball; it would also be needed for 1.0-with-diff.
dgit sbuild
dgit push-builtNew upstream version Find the new upstream version number and corresponding tag. (Let s suppose it srationale You don t have to use
dgit sbuild, but it is usually convenient to do so, because unlike sbuild, dgit understands git. Also it works around a gitignore-related defect in dpkg-source.
1.2.4.) Check the provenance:
git verify-tag v1.2.4rationale Not all upstreams sign their git tags, sadly. Sometimes encouraging them to do so can help. You may need to use some other method(s) to check that you have the right git commit for the release.
git merge v1.2.4
dch -v1.2.4-1 'New upstream release.'git debrebase mew-upstream 1.2.4git merge or git (deb)rebase.
After you ve completed the merge, test your package and make any further needed changes. When you have it working in a local branch, make a Merge Request, as above.
Sponsorship
git-based sponsorship is super easy! The sponsee can maintain their git branch on Salsa, and do all normal maintenance via gitlab operations.
When the time comes to upload, the sponsee notifies the sponsor that it s time. The sponsor fetches and checks out the git branch from Salsa, does their checks, as they judge appropriate, and when satisfied runs git-debpush.
As part of the sponsor s checks, they might want to see all changes since the last upload to Debian:
dgit fetch sid
git diff dgit/dgit/sid..HEADOr to see the Debian delta of the proposed upload:
git verify-tag v1.2.3
git diff v1.2.3..HEAD ':!debian'git log -p v1.2.3..HEAD ':!debian'Don t look at debian/patches/. It can be absent or out of date.
dgit fetch sid
git diff master...dgit/dgit/sidIf the NMUer used dgit, then git log dgit/dgit/sid will show you the commits they made.
Normally the best thing to do is to simply merge the NMU, and then do any reverts or rework in followup commits:
git merge dgit/dgit/sidgit-debrebase quick at this stage, to check that the merge went OK and the package still has a lineariseable delta queue.
1.2.3-7, you can go back and see the NMU diff again with:
git diff debian/1.2.3-7...dgit/dgit/siddebian/patches/. Normally it s best to filter them out with git diff ... ':!debian/patches'
If you d prefer to read the changes to the delta queue as an interdiff (diff of diffs), you can do something like
git checkout debian/1.2.3-7
git-debrebase --force make-patches
git diff HEAD...dgit/dgit/sid -- :debian/patchesto diff against a version with debian/patches/ up to date. (The NMU, in dgit/dgit/sid, will necessarily have the patches already up to date.)
Initial filteringrationale Yes, this will end up including the non-free files in the git history, on official Debian servers. That s OK. What s forbidden is non-free material in the Debianised git tree, or in the source packages.
git checkout -b upstream-dfsg v1.2.3
git rm nonfree.exe
git commit -m "upstream version 1.2.3 DFSG-cleaned"
git tag -s -m "upstream version 1.2.3 DFSG-cleaned" v1.2.3+ds1
git push origin upstream-dfsgAnd now, use 1.2.3+ds1, and the filtered branch upstream-dfsg, as the upstream version, instead of 1.2.3 and upstream/main. Follow the steps for Convert the git branch or New upstream version, as applicable, adding +ds1 into debian/changelog.
If you missed something and need to filter out more a nonfree files, re-use the same upstream-dfsg branch and bump the ds version, eg v1.2.3+ds2.
Subsequent upstream releases
git checkout upstream-dfsg
git merge v1.2.4
git rm additional-nonfree.exe # if any
git commit -m "upstream version 1.2.4 DFSG-cleaned"
git tag -s -m "upstream version 1.2.4 DFSG-cleaned" v1.2.4+ds1
git push origin upstream-dfsgRemoving files by pattern
If the files you need to remove keep changing, you could automate things with a small shell script debian/rm-nonfree containing appropriate git rm commands. If you use git rm -f it will succeed even if the git merge from real upstream has conflicts due to changes to non-free files.
Common issuesrationale Ideally
uscan, which has a way of representing DFSG filtering patterns indebian/watch, would be able to do this, but sadly the relevant functionality is entangled with uscan s tarball generation.
.gitattributes to modify files as they are checked out.
Normally this doesn t cause a problem so long as any orig tarballs are generated the same way (as they will be by tag2upload or git-deborig). But if the package or build system relies on them, you may need to institute some workarounds, or, replicate the effect of the gitattributes as commits in git.
git rm the submodule.
gbp pq and/or quilt with a patches-unapplied branch.
gbp pq, manual use of quilt, git-dpm and so on.
--noop-ok to the Salsa CI runes. Thanks to Charlemagne Lasse for the report. Apologies if this causes Debian Planet to re-post this article as if it were new.
services: loki: # expose: - 3100/tcp labels: - traefik.enable=true - traefik.http.routers.loki.rule=PathPrefix( /loki )
/loki to its first exposed port. Colocating Traefik configuration
with the service definition is attractive. How do we achieve the same for
Prometheus metrics?
discovery.docker component. Just like Traefik,
it connects to the Docker socket.1 With a few relabeling rules, we teach
it to use Docker labels to locate and scrape metrics.
We define three labels on each service:
metrics.enable set to true enables metrics collection,metrics.port specifies the port exposing the Prometheus endpoint, andmetrics.path specifies the path to the metrics endpoint.metrics.port is mandatory. Otherwise,
it defaults to the only exposed port. The default value for metrics.path is
/metrics. The Loki service from earlier becomes:
services: loki: # expose: - 3100/tcp labels: - traefik.enable=true - traefik.http.routers.loki.rule=PathPrefix( /loki ) - metrics.enable=true - metrics.path=/loki/metrics
discovery.docker "docker" host = "unix:///var/run/docker.sock" refresh_interval = "30s" filter name = "label" values = ["com.docker.compose.project=akvorado"]
filter block restricts discovery to containers belonging
to the akvorado project, avoiding interference with unrelated containers on
the same host. For each discovered container, Alloy produces a target with
labels such as __meta_docker_container_label_metrics_port for the
metrics.port Docker label.
metrics.enable
set to true:
discovery.relabel "prometheus" targets = discovery.docker.docker.targets // Keep only targets with metrics.enable=true rule source_labels = ["__meta_docker_container_label_metrics_enable"] regex = true action = "keep" //
metrics.port:
// When metrics.port is set, override __address__. rule source_labels = ["__address__", "__meta_docker_container_label_metrics_port"] regex = (.+):\d+;(.+) target_label = "__address__" replacement = "$1:$2"
host network mode. When
__meta_docker_network_name equals host, Alloy rewrites the address to
host.docker.internal instead of localhost:3
// When host networking, override __address__ to host.docker.internal. rule source_labels = ["__meta_docker_container_label_metrics_port", "__meta_docker_network_name"] regex = (.+);host target_label = "__address__" replacement = "host.docker.internal:$1"
rule source_labels = ["__meta_docker_container_label_com_docker_compose_service"] regex = (.+)(?:-\d+)? target_label = "job" rule source_labels = ["__address__"] regex = (.+):\d+ target_label = "instance"
metrics.path, Alloy uses it. Otherwise, it defaults to
/metrics:
rule source_labels = ["__meta_docker_container_label_metrics_path"] regex = (.+) target_label = "__metrics_path__" rule source_labels = ["__metrics_path__"] regex = "" target_label = "__metrics_path__" replacement = "/metrics"
prometheus.scrape "docker" targets = discovery.relabel.prometheus.output forward_to = [prometheus.remote_write.default.receiver] scrape_interval = "30s" prometheus.remote_write "default" endpoint url = "http://prometheus:9090/api/v1/write"
prometheus.scrape periodically fetches metrics from the discovered targets.
prometheus.remote_write sends them to Prometheus.
prometheus.exporter.redis "docker" redis_addr = "redis:6379" discovery.relabel "redis" targets = prometheus.exporter.redis.docker.targets rule target_label = "job" replacement = "redis" prometheus.scrape "redis" targets = discovery.relabel.redis.output forward_to = [prometheus.remote_write.default.receiver] scrape_interval = "30s"
prometheus.exporter.kafka "docker" kafka_uris = ["kafka:9092"] discovery.relabel "kafka" targets = prometheus.exporter.kafka.docker.targets rule target_label = "job" replacement = "kafka" prometheus.scrape "kafka" targets = discovery.relabel.kafka.output forward_to = [prometheus.remote_write.default.receiver] scrape_interval = "30s"
job label explicitly since no Docker metadata can
provide it.
docker-compose.yml, just like adding a Traefik
route. Alloy picks it up automatically. You can apply the same pattern with
another discovery method, like discovery.kubernetes,
discovery.scaleway, or discovery.http.
extra_hosts:
["host.docker.internal:host-gateway"] in its definition.
This is a copy of an email I used to send internally at work and now made public. I'm not sure I'll make a habit of posting it here, especially not twice a year, unless people really like it. Right now, it's mostly here to keep with my current writing spree going.This is your bi-yearly reminder that time is changing soon!
Spring forward, fall backwards.This northern-centric (sorry!) proverb says that clocks will move forward by an hour this "spring", after moving backwards last "fall". This is why we lose an hour of work, sorry, sleep. It sucks, to put it bluntly. I want it to stop and will keep writing those advisories until it does. To see where and when, we, unfortunately, still need to go into politics.
When the Free Software movement started in the 1980s, most of the world
had just made a transition from free university-written software to
non-free, proprietary, company-written software. Because of that, the
initial ethical standpoint of the Free Software foundation was that it's
fine to run a non-free operating system, as long as all the software you
run on that operating system is free.
Initially this was just the
editor.
But as time went on, and the FSF managed to write more and more parts of
the software stack, their ethical stance moved with the times. This was
a, very reasonable, pragmatic stance: if you don't accept using a
non-free operating system and there isn't a free operating system yet,
then obviously you can't write that free operating system, and the
world won't move towards a point where free operating systems exist.
In the early 1990s, when
Linus initiated the
Linux kernel, the situation reached the point where the original dream
of a fully free software stack was complete.
Or so it would appear.
Because, in fact, this was not the case. Computers are physical objects,
composed of bits of technology that we refer to as "hardware", but in
order for these bits of technology to communicate with other bits of
technology in the same computer system, they need to interface with
each other, usually using some form of bus protocol. These bus protocols
can get very complicated, which means that a bit of software is required
in order to make all the bits communicate with each other properly.
Generally, this software is referred to as "firmware", but don't let
that name deceive you; it's really just a bit of low-level software that
is very specific to one piece of hardware. Sometimes it's written in an
imperative high-level language; sometimes it's just a set of very simple
initialization vectors. But whatever the case might be, it's always a
bit of software.
And although we largely had a free system, this bit of low-level
software was not yet free.
Initially, storage was expensive, so computers couldn't store as much
data as today, and so most of this software was stored in ROM chips on
the exact bits of hardware they were meant for. Due to this fact, it was
easy to deceive yourself that the firmware wasn't there, because you
never directly interacted with it. We knew it was there; in fact, for
some larger pieces of this type of
software it was possible, even in
those days, to install updates. But that was rarely if ever done at the
time, and it was easily forgotten.
And so, when the free software movement slapped itself on the back and
declared victory when a fully free operating system was available, and
decided that the work of creating a free software environment was
finished, that only keeping it recent was further required, and that we
must reject any further non-free encroachments on our fully free
software stack, the free software movement was deceiving itself.
Because a computing environment can never be fully free if the
low-level pieces of software that form the foundations of that computing
environment are not free. It would have been one thing if the Free
Software Foundation declared it ethical to use non-free low-level
software on a computing environment if free alternatives were not
available. But unfortunately, they did not.
In fact, something very strange happened.
In order for some free software hacker to be able to write a free
replacement for some piece of non-free software, they obviously need to
be able to actually install that theoretical free replacement. This
isn't just a random thought; in fact it has
happened.
Now, it's possible to install software on a piece of rewritable storage
such as flash memory inside the hardware and boot the hardware from
that, but if there is a bug in your software -- not at all unlikely if
you're trying to write software for a piece of hardware that you don't
have documentation for -- then it's not unfathomable that the
replacement piece of software will not work, thereby reducing your
expensive piece of technology to something about as useful as a
paperweight.
Here's the good part.
In the late 1990s and early 2000s, the bits of technology that made up
computers became so complicated, and the storage and memory available to
computers so much larger and cheaper, that it became economically more
feasible to create a small, tiny, piece of software stored in a ROM chip
on the hardware, with just enough knowledge of the bus protocol to
download the rest from the main computer.
This is awesome for free software. If you now write a replacement for
the non-free software that comes with the hardware, and you make a
mistake, no wobbles! You just remove power from the system, let the DRAM
chips on the hardware component fully drain, return power, and try
again. You might still end up with a brick of useless silicon if some
of the things you sent to your technology make it do things that it was
not designed to do and therefore you burn through some critical bits of
metal or plastic, but the chance of this happening is significantly
lower than the chance of you writing something that impedes the boot
process of the piece of hardware and you are unable to fix it because
the flash is overwritten. There is anecdotal
evidence
that there are free software hackers out there who do so. So, yay,
right? You'd think the Free Software foundation would jump at the
possibility to get more free software? After all, a large part of why we
even have a Free Software Foundation in the first place, was because of
some piece of hardware that was
misbehaving,
so you would think that the foundation's founders would understand the
need for hardware to be controlled by software that is free.
The strange thing, what has always been strange to me, is that this is
not what happened.
The Free Software Foundation instead decided that non-free software on
ROM or flash chips is fine, but non-free software -- the very same
non-free software, mind -- that touches the general storage device that
you as a user use, is not. Never mind the fact that the non-free
software is always there, whether it sits on your storage device or not.
Misguidedness aside, if some people decide they would rather not update
the non-free software in their hardware and use the hardware with the
old and potentially buggy version of the non-free software that it came
with, then of course that's their business.
Unfortunately, it didn't quite stop there. If it had, I wouldn't have
written this blog post.
You see, even though the Free Software Foundation was about Software,
they decided that they needed to create a hardware
certification program. And this hardware
certification program ended up embedding the strange concept that if
something is stored in ROM it's fine, but if something is stored on a
hard drive it's not. Same hardware, same software, but different
storage. By that logic, Windows respects your freedom as long as the
software is written to ROM. Because this way, the Free Software
Foundation could come to a standstill and pretend they were still living
in the 90s.
An unfortunate result of the "RYF" program is that it means that
companies who otherwise would have been inclined to create hardware that
was truly free, top to bottom, are now more incentivised by the RYF
program to create hardware in which the non-free low-level software
can't be replaced.
Meanwhile, the rest of the world did not pretend to still be living in
the nineties, and free hardware communities now exist. Because of how
the FSF has marketed themselves out of the world, these communities call
themselves "Open Hardware" communities, rather than "Free Hardware"
ones, but the principle is the same: the designs are there, if you have
the skill you can modify it, but you don't have to.
In the mean time, the open hardware community has evolved to a point
where even CPUs are designed in
the open, which you can design your own version of.
But not all hardware can be implemented as RISC-V, and so if you want a
full system that builds RISC-V you may still need components of the
system that were originally built for other architectures but that would
work with RISC-V, such as a network card or a GPU. And because the FSF
has done everything in their power to disincentivise people who would
otherwise be well situated to build free versions of the low-level
software required to support your hardware, you may now be in the weird
position where we seem to have somehow skipped a step.
My own suspicion is that the universe is not only queerer than we suppose, but queerer than we can suppose.-- J.B.S. Haldane (comments for this post will not pass moderation. Use your own blog!)
Note: I have not published blog posts about my academic papers over the past few years. To ensure that my blog contains a more comprehensive record of my published papers and to surface these for folks who missed them, I will be periodically (re)publishing blog posts about some older published projects. This post is closely based on a previously published post by Zarine Kharazian on the Community Data Science Blog.
For nearly a decade, the Croatian language version of Wikipedia was run by a cabal of far-right nationalists who edited articles in ways that promoted fringe political ideas and involved cases of historical revisionism related to the Usta e regime, a fascist movement that ruled the Nazi puppet state called the Independent State of Croatia during World War II. This cabal seized complete control of the encyclopedia s governance, banned and blocked those who disagreed with them, and operated a network of fake accounts to create the appearance of grassroots support for their policies.
Thankfully, Croatian Wikipedia appears to be an outlier. Though both the Croatian and Serbian language editions have been documented to contain nationalist bias and historical revisionism, Croatian Wikipedia seems unique among Wikipedia editions in the extent to which its governance institutions were captured by a small group of users.
The situation in Croatian Wikipedia was well documented and is now largely fixed, but we still know very little about why it was taken over, while other language editions seem to have rebuffed similar capture attempts. In a paper published in the Proceedings of the ACM: Human-Computer Interaction (CSCW), Zarine Kharazian, Kate Starbird, and I present an interview-based study that provides an explanation for why Croatian was captured while several other editions facing similar contexts and threats fared better.
The conceptual model from our paper, visualizing possible institutional configurations among Wikipedia projects that affect the risk of governance capture. Citation for the full paper: Kharazian, Zarine, Kate Starbird, and Benjamin Mako Hill. 2024. Governance Capture in a Self-Governing Community: A Qualitative Comparison of the Croatian, Serbian, Bosnian, and Serbo-Croatian Wikipedias. Proceedings of the ACM on Human-Computer Interaction 8 (CSCW1): 61:1-61:26. https://doi.org/10.1145/3637338.
This blog post and the paper it describes are collaborative work by Zarine Kharazian, Benjamin Mako Hill, and Kate Starbird.
Since Generative AI is currently the most popular topic, I wanted to get my
hands dirty and learn something new. I was learning about the Model Context
Protocol at the time and wanted to apply it to build something simple.
apt-get install $(debsecan --suite sid --format packages --only-fixed)
"servers":
"debsecan-mcp":
"command": "uv",
"args": [
"--directory",
"/home/vasudev/Documents/personal/FOSS/debsecan-mcp/debsecan-mcp",
"run",
"debsecan-mcp"
]
,
"inputs": []
You might see a verification screen pop up on more and more Debian web properties. Unfortunately the AI world of today is meeting web hosts that use Perl CGIs and are not built as multi-tiered scalable serving systems. The issues have been at three layers:Optimally we would go and solve some scalability issues with the services, however there is also a question of how much we want to be able to serve - as AI scraper demand is just a steady stream of requests that are not shown to humans.
DSA has now stood up some VMs with Varnish for proxying. Incoming TLS is provided by hitch, and TLS "on-loading" is done using haproxy. That way TLS goes in and TLS goes out. While Varnish does cache, if the content is cachable (e.g. does not depend on cookies) - that is not the primary reason for using it: It can be used for flexible query and response rewriting.
If no cookie with a proof of work is provided, the user is redirected to a challenge page that does some webcrypto in Javascript - because that looked similar to what other projects do (e.g. haphash that originally inspired the solution). However so far it looks like scrapers generally do not run with Javascript enabled, so this whole crypto proof of work business could probably be replaced with just a Javascript-based redirect. The existing solution also has big (security) holes in it. And, as we found out, Firefox is slower at webcrypto than Chrome. I have recently reduced the complexity, so you should notice it blocking you significantly less.
Once you have the cookie, you can keep accessing the site for as long as the cookie is valid. Please do not make any assumptions about the cookies, or you will be broken in the future.For legitimate scrapers that obey robots.txt, there is now an automatically generated IP allowlist in place (thanks, Marco d'Itri). Turns out that the search engines do not actually run Javascript either and then loudly complain about the redirect to the challenge page. Other bots are generally exempt.
Note: I have not published blog posts about my academic papers over the past few years. To ensure that my blog contains a more comprehensive record of my published papers and to surface these for folks who missed them, I will be periodically (re)publishing blog posts about some older published projects. It seems natural to think of online communities competing for the time and attention of their participants. Over the last few years, I ve worked with a team of collaborators led by Nathan TeBlunthuis to use mathematical and statistical techniques from ecology to understand these dynamics. What we ve found surprised us: competition between online communities is rare and typically short-lived. When we started this research, we figured competition would be most likely among communities discussing similar topics. As a first step, we identified clusters of such communities on Reddit. One surprising thing we noticed in our Reddit data was that many of these communities that used similar language also had very high levels of overlap among their users. This was puzzling: why were the same groups of people talking to each other about the same things in different places? And why don t they appear to be in competition with each other for their users time and activity? We didn t know how to answer this question using quantitative methods. As a result, we recruited and interviewed 20 active participants in clusters of highly related subreddits with overlapping user bases (for example, one cluster was focused on vintage audio). We found that the answer to the puzzle lay in the fact that the people we talked to were looking for three distinct things from the communities they worked in:
Figure from No Community Can Do Everything: Why People Participate in Similar Online Communities depicts three key benefits that people seek from online communities and how individual communities tend not to optimally provide all three. For example, large communities tend not to afford a tight-knit homophilous community.This work was published as a paper at CSCW: TeBlunthuis, Nathan, Charles Kiene, Isabella Brown, Laura (Alia) Levi, Nicole McGinnis, and Benjamin Mako Hill. 2022. No Community Can Do Everything: Why People Participate in Similar Online Communities. Proceedings of the ACM on Human-Computer Interaction 6 (CSCW1): 61:1-61:25. https://doi.org/10.1145/3512908.
This work was supported by the National Science Foundation (awards IIS-1908850, IIS-1910202, and GRFP-2016220885). A full list of acknowledgements is in the paper.
Next.