๐พ Archived View for perso.pw โบ blog โบ rss.xml captured on 2023-01-29 at 02:52:08.
โฌ ๏ธ Previous capture (2022-07-16)
โก๏ธ Next capture (2023-03-20)
-=-=-=-=-=-=-
<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> <channel> <title>Solene'%</title> <description></description> <link>gemini://perso.pw/blog/</link> <atom:link href="gemini://perso.pw/blog/rss.xml" rel="self" type="application/rss+xml" /> <item> <title>Configure syncthing to sync a single file</title> <description> <![CDATA[ <pre># Introduction Quick blog entry to remember about something that wasn't as trivial as I thought. I needed to use syncthing to keep a single file in sync (KeePassXC database) without synchronizing the whole directory. You have to use mask exclusion feature to make it possible. Put it simple, you need the share to forbid every file, except the one you want to sync. This configuration happens in the `.stignore` file in the synchronized directory, but can also be managed from the Web interface. => https://docs.syncthing.net/users/ignoring.html Syncthing documentation about ignoring files # Example If I want to only sync KeePassXC files (they have the `.kdbx` extension), I have this in my `.stignore` file:
!*.kdbx
And that's all! Note that this must be set on all nodes using this share, otherwise you may have surprises. </pre> ]]> </description> <guid>gemini://perso.pw/blog//articles/syncthing-single-file.gmi</guid> <link>gemini://perso.pw/blog//articles/syncthing-single-file.gmi</link> <pubDate>Sat, 28 Jan 2023 00:00:00 GMT</pubDate> </item> <item> <title>How to boot on a BTRFS snapshot</title> <description> <![CDATA[ <pre># Introduction I always wanted to have a simple rollback method on Linux systems, NixOS gave me a full featured one, but it wasn't easy to find a solution for other distributions. Fortunately, with BTRFS, it's really simple thanks to snapshots being mountable volumes. # Setup You need a Linux system with a BTRFS filesystem, in my examples, the root subvolume (where `/` is) is named `gentoo`. I use `btrbk` to make snapshots of `/` directly in `/.snapshots`, using the following configuration file:
snapshot_preserve_min 30d
volume /
snapshot_dir .snapshots
subvolume .
With a systemd service, it's running once a day, so I'll have for 30 days of snapshots to restore my system if needed. This creates snapshots named like the following:
$ ls /.snapshots/
ROOT.20230102
ROOT.20230103
ROOT.20230104
A snapshot address from BTRFS point of view looks like `gentoo/.snapshots/ROOT.20230102`. I like btrbk because it's easy to use and configure, and it creates easy to remember snapshots names. # Booting on a snapshot When you are in the bootloader (GRUB, systemd-boot, Lilo etc..), edit the command line, and add the new option (replace if already exists) with the following, the example uses the snapshot `ROOT.20230102`:
rootflags=subvol=gentoo/.snapshots/ROOT.20230103
Boot with the new command line, and you should be on your snapshot as the root filesystem. # Be careful When you are on a snapshot, this mean any change will be specific to this volume. If you use a separate partition for `/boot`, an older snapshot may not have the kernel (or its module) you are trying to boot. # Conclusion This is a very simple but effective mecanism, more than enough to recover from a bad upgrade, especially when you need the computer right now. # Going further There is a project grub-btrfs which can help you adding BTRFS snapshots as boot choices in GRUB menus. => https://github.com/Antynea/grub-btrfs grub-btrfs GitHub project page </pre> ]]> </description> <guid>gemini://perso.pw/blog//articles/boot-on-btrfs-snapshot.gmi</guid> <link>gemini://perso.pw/blog//articles/boot-on-btrfs-snapshot.gmi</link> <pubDate>Wed, 04 Jan 2023 00:00:00 GMT</pubDate> </item> <item> <title>Booting Gentoo on a BTRFS from multiple LUKS devices</title> <description> <![CDATA[ <pre># Introduction This is mostly a reminder for myself. I installed Gentoo on a machine, but I reused the same BTRFS filesystem where NixOS is already installed, the trick is the BTRFS filesystem is composed of two partitions (a bit like raid 0) but they are from two different LUKS partitions. It wasn't straightforward to unlock that thing at boot. # Fix grub error Grub was trying to autodetect the root partition to add `root=/dev/something`, but as my root filesystem requires `/dev/mapper/ssd1` and `/dev/mapper/ssd2`, it was simply adding `root=/dev/mapper/ssd1 /dev/mapper/ssd2`, which is wrong. This required a change in the file `/etc/grub.d/10_linux` where I entirely deleted the `root=` parameter. # Compile systemd with cryptsetup A mistake I made was to try to boot without systemd compiled with cryptsetup support, this was just failing because in the initramfs, some systemd services were used to unlock the partitions, but without proper support for cryptsetup it didn't work. # Linux command line parameters In `/etc/default/grub`, I added this line, it contains the UUID of both LUKS partitions needed, and a `root=/dev/dm-0` which is unexpectedly the first unlocked device path, and `rd.luks=1` to enble LUKS support.
GRUB_CMDLINE_LINUX="rd.luks.uuid=24682f88-9115-4a8d-81fb-a03ec61d870b rd.luks.uuid=1815e7a4-532f-4a6d-a5c6-370797ef2450 rootfs=btrfs root=/dev/dm-0 rd.luks=1"
# Run Dracut and grub After the changes, I did run `dracut --force --kver 5.15.85-gentoo-dist` and `grub-mkconfig -o /boot/grub/grub.cfg` # Conclusion It's working fine now, I thought it would require me to write a custom initrd script, but dracut is providing all I needed, but there were many quirks on the path with no really helpful message to understand what's failing. Now, I can enjoy my dual boot Gentoo / NixOS (they are quite antagonists :D), but they share the same filesystem and I really enjoy this weird setup. </pre> ]]> </description> <guid>gemini://perso.pw/blog//articles/multi-luks-btrfs-boot-gentoo.gmi</guid> <link>gemini://perso.pw/blog//articles/multi-luks-btrfs-boot-gentoo.gmi</link> <pubDate>Mon, 02 Jan 2023 00:00:00 GMT</pubDate> </item> <item> <title>Export Flatpak programs from a computer to another</title> <description> <![CDATA[ <pre># Introduction As a flatpak user, but also someone with a slow internet connection, I was looking for a way to export a flatpak program to install it on another computer. It turns out flatpak supports this, but it's called "create-usb" for some reasons. So today, I'll show how to export a flatpak program from a computer to another. => https://www.flatpak.org/ Flatpak official website => https://docs.flatpak.org/en/latest/usb-drives.html Flatpak documentation about usb drives # Pre-requisites For some reasons, the default flathub parameters doesn't associate it a "Collection ID", which is required for the create-usb feature to work, so we need to associate a "Collection ID" to the flathub remote repository on both systems. We can use the example from the official documentation:
flatpak remote-modify --collection-id=org.flathub.Stable flathub
# Export The export process is simple, create a directory in which you want the flatpak application to be exported, we will use `~/export/` in the examples, with the program `org.mozilla.firefox`.
flatpak create-usb ~/export/ org.mozilla.firefox
The export process will display a few lines and tell you when it finished. If you export multiple programs into the same directory, the export process will be smart and skip already existing components. # Import Take the `~/export/` directory, either on a USB drive, or copy it using rsync, share it over NFS/Samba etc... It's up to you. In the example, `~/export/` refers to the same directory transferred from the previous step onto the new system. Now, we can run the import command to install the program.
flatpak install --sideload=~/export/.ostree/repo/ flathub org.mozilla.firefox
If it's working correctly, it should be very fast. # Limitation Because the flatpak components/dependencies of a program can differ depending on the host (for example if you have an NVIDIA card, it will pull some NVIDIA dependencies), so if you export a program from a non-NVIDIA system to the other, it won't be complete to work reliably on the new system, but the missing parts can be downloaded on the Internet, it's still reducing the bandwidth requirement. # Conclusion I kinda like Flatpak, it's convenient and reliable, and allow handling installed programs without privileges escalation. The programs can be big, it's cool to be able to save/export them for later use. </pre> ]]> </description> <guid>gemini://perso.pw/blog//articles/flatpak-export-import.gmi</guid> <link>gemini://perso.pw/blog//articles/flatpak-export-import.gmi</link> <pubDate>Sun, 01 Jan 2023 00:00:00 GMT</pubDate> </item> <item> <title>Authentication gateway with SSH on OpenBSD</title> <description> <![CDATA[ <pre># Introduction A neat feature in OpenBSD is the program authpf, an authenticating gateway using SSH. Basically, it allows to dynamically configure the local firewall PF by connecting/disconnecting into a user account over SSH, either to toggle an IP into a table or rules through a PF anchor. # Use case This program is very useful for the following use case:
Now, you can edit `/etc/pf.conf` and use the default table name `authpf_users`. With the following PF snippet, we will only allow authenticated users to go through the NAT.
table <authpf_users> persist
match out on egress inet from <authpf_users> to any nat-to (egress)
Reload your firewall, and when Chloe will connect, she will be able to go through the NAT. # Conclusion The program authpf is an efficient tool for the network administrator's toolbox. And with the use of PF anchors, you can really extend its potential as you want, it's really not limited to tables. # Going further The man page contains a lot of extra information for customization, you should definitely read it if you plan to use authpf. => https://man.openbsd.org/authpf OpenBSD man page of authpf(8) ## Blocking users It's possible to ban users, for various reasons you may want to block someone with a message asking to reach the help desk. This can be done by creating a file name after the username, like in the following example for user `chloe`: `/etc/authpf/banned/chloe`, the file text content will be displayed to the user upon connection. ## Greeeting message It's possible to write a custom greeting message displayed upon connection, this can be global or per user, just write a message in `/etc/authpf/authpf.message` for a global one, or `/etc/authpf/users/chloe/authpf.message` for user `chloe`. </pre> ]]> </description> <guid>gemini://perso.pw/blog//articles/openbsd-authpf.gmi</guid> <link>gemini://perso.pw/blog//articles/openbsd-authpf.gmi</link> <pubDate>Thu, 01 Dec 2022 00:00:00 GMT</pubDate> </item> <item> <title>Automatic prompt to unlock remote encrypted partitions</title> <description> <![CDATA[ <pre># Introduction I have remote systems that only have /home as encrypted partitions, the reason is it ease a lot of remote management without a serial access, it's not ideal if you have critical files but in my use case, it's good enough. In this blog post, I'll explain how to get the remote system to prompt you the unlocking passphrase automatically when it boots. I'm using OpenBSD in my example, but you can achieve the same with Linux and cryptsetup (LUKS), if you want to push the idea on Linux, you could do this from the initramfs to unlock your root partition. # Requirement
ssh solene@10.42.42.102 | bioctl -s -c C -l 1a52f9ec20246135.k softraid0
if [ $? -eq 0 ]
then
mount /home
fi
In this script, `solene@10.42.42.102` is my user@laptop-address, and `1a52f9ec20246135.k` is my encrypted partition. The file `/etc/rc.local` is run at boot after most of the services, including networking. You should get a display like this when the system boots: => static/unlock.png a GUI window asking for a passphrase to unlock the /home partition of the computer named T400 # Conclusion With this simple setup, I can reboot my remote systems and wait for the passphrase to be asked quite reliably. Because of ssh, I can authenticate which system is asking for a passphrase, and it's sent encrypted over the network. It's possible to get more in depth in this idea by using a local password database to automatically pick the passphrase, but you lose some kind of manual control, if someone steals a machine you may not want to unlock it after all ;) It would also be possible to prompt a Yes/No dialog before piping the passphrase from your computer, do what feels correct for you. </pre> ]]> </description> <guid>gemini://perso.pw/blog//articles/openbsd-remote-unlock.gmi</guid> <link>gemini://perso.pw/blog//articles/openbsd-remote-unlock.gmi</link> <pubDate>Sun, 20 Nov 2022 00:00:00 GMT</pubDate> </item> <item> <title>Pinafore: a light Mastodon web client</title> <description> <![CDATA[ <pre># Intro This blog post is for Mastodon users who may not like the official Mastodon web interface. It has a lot of features, but it's using a lot of CPU and requires a large screen. Fortunately, there are alternatives front-ends to Mastodon, this is possible through calls between the front-end to then instance API. I would like to introduce you Pinafore. => https://github.com/nolanlawson/pinafore Pinafore GitHub client => https://pinafore.social/ Pinafore.social website # What's Pinafore? Pinafore is a "web application" consisting of a static website, this implies nothing is actually store on the server hosting Pinafore, think about it like a page loaded in your browser that stores data in your browser and make API calls from your browser. This design is elegant because it delegates everything to the browser and requires absolutely no processing on the Pinafore hosting server, it's just a web server there serving static files once. As I said previously, Pinafore is a Mastodon (but also extends to other Fediverse instances whenever possible) front-end with a bunch of features such as: - accessibility (for content warning content, greyscale mode, contrast, key bindings) - only one column, it's really compact - simple design, fast to load and doesn't eat much CPU (especially compared to official Mastodon interface) - read-only support if you visit your Pinafore host when not connected, I find this very useful (remember that cache is stored in your browser) - can handle multiple accounts at once This being said, Pinafore doesn't target minimalism either, it needs javascript and a modern web browser. # How to use Pinafore? There are two ways to use it, either by using the official hosted service, or by hosting it yourself. Whether you choose the official or self-hosted, the principle is the following: you enter your account instance address in it the first time, this will trigger an oauth authentication on your instance and will ask if you want pinafore to use your account through the API (this can be revoked later from your Mastodon account). Accept, and that's it! ## Pinafore.social The official service is run by the developers and kept up to date. You can use it without installing anything, simply visit the address below and go through the login process. => https://pinafore.social Pinafore.social website This is a very convenient way to use pinafore, but it comes with a tradeoff: it involves a third party between your social network account and your client. While pinafore.social is trustable, this doesn't mean it can't be compromised and act as a "Man In The Middle". As I mentionned earlier, no data are stored by Pinafore because everything is in your browser, but nothing prevent a malicious attacker to modify the hosted Pinafore code to redirect data from your browser to a remote server they control in order to steal information. ## Self Hosting It's possible to create Pinafore static files from your system and host it on any web server. While it's more secure than pinafore.social (if your host is secure), it still involves extra code that could "potentially" be compromised through a rogue commit, but it's not realistic to encounter this case when using Pinafore releases versions. For this step, I'll link to the according documentation in the project: => https://github.com/nolanlawson/pinafore#exporting Exporting Pinafore # Trivia Pinafore is the recommended web front-end for the Mastodon server implementation GoToSocial which only provide a backend. => https://github.com/superseriousbusiness/gotosocial/ GoToSocial GitHub project page </pre> ]]> </description> <guid>gemini://perso.pw/blog//articles/mastodon-light-client.gmi</guid> <link>gemini://perso.pw/blog//articles/mastodon-light-client.gmi</link> <pubDate>Fri, 18 Nov 2022 00:00:00 GMT</pubDate> </item> <item> <title>Hard user separation with two NixOS as one</title> <description> <![CDATA[ <pre># Credits This blog post is a republication of the article I published on my employer's blog under CC BY 4.0. I'm grateful to be allowed to publish NixOS related content there, but also to be able to reuse it here! => https://creativecommons.org/licenses/by/4.0/ License CC by 4.0 => https://www.tweag.io/blog/2022-11-01-hard-user-separation-with-nixos/ Original publication place: Hard user separation with NixOS # Introduction This guide explains how to install NixOS on a computer, with a twist. If you use the same computer in different contexts, let's say for work and for your private life, you may wish to install two different operating systems to protect your private life data from mistakes or hacks from your work. For instance a cryptolocker you got from a compromised work email won't lock out your family photos. But then you have two different operating systems to manage, and you may consider that it's not worth the effort and simply use the same operating system for your private life and for work, at the cost of the security you desired. I offer you a third alternative, a single NixOS managing two securely separated contexts. You choose your context at boot time, and you can configure both context from either of them. You can safely use the same machine at work with your home directory and confidential documents, and you can get into your personal context with your private data by doing a reboot. Compared to a dual boot system, you have the benefits of a single system to manage and no duplicated package. For this guide, you need a system either physical or virtual that is supported by NixOS, and some knowledge like using a command line. You don't necessarily need to understand all the commands. The system disk will be erased during the process. You can find an example of NixOS configuration files to help you understand the structure of the setup on the following GitHub repository: => https://github.com/tweag/nixos-specialisation-dual-boot tweag/nixos-specialisation-dual-boot GitHub repository # Disks Here is a diagram showing the whole setup and the partitioning. => static/setup-diagram.png Picture showing a diagram of disks and partitions ## Partitioning We will create a 512 MB space for the /boot partition that will contain the kernels, and allocate the space left for an LVM partition we can split later.
parted /dev/sda -- mklabel gpt
parted /dev/sda -- mkpart ESP fat32 1MiB 512MiB
parted /dev/sda -- mkpart primary 512MiB 100%
parted /dev/sda -- mkpart set 1 esp on
Note that these instructions are valid for UEFI systems, for older systems you can refer to the NixOS manual to create a MBR partition. => https://nixos.org/manual/nixos/stable/index.html#sec-installation-partitioning NixOS manual: disks and partitioning. ## Create LVM volumes We will use LVM so we need to initialize the partition and create a Volume Group with all the free space.
pvcreate /dev/sda2
vgcreate pool /dev/sda2
We will then create three logical volumes, one for the store and two for our environments:
lvcreate -L 15G -n root-private pool
lvcreate -L 15G -n root-work pool
lvcreate -l 100%FREE -n nix-store pool
NOTE: The sizes to assign to each volume is up to you, the nix store should have at least 30GB for a system with graphical sessions. LVM allows you to keep free space in your volume group so you can increase your volumes size later when needed. ## Encryption We will enable encryption for the three volumes, but we want the nix-store partition to be unlockable with either of the keys used for the two root partitions. This way, you don't have to type two passphrases at boot.
cryptsetup luksFormat /dev/pool/root-work
cryptsetup luksFormat /dev/pool/root-private
cryptsetup luksFormat /dev/pool/nix-store # same password as work
cryptsetup luksAddKey /dev/pool/nix-store # same password as private
We unlock our partitions to be able to format and mount them. Which passphrase is used to unlock the nix-store doesn't matter.
cryptsetup luksOpen /dev/pool/root-work crypto-work
cryptsetup luksOpen /dev/pool/root-private crypto-private
cryptsetup luksOpen /dev/pool/nix-store nix-store
Please note we don't encrypt the boot partition, which is the default on most encrypted Linux setup. While this could be achieved, this adds complexity that I don't want to cover in this guide. Note: the nix-store partition isn't called `crypto-nix-store` because we want the nix-store partition to be unlocked after the root partition to reuse the password. The code generating the ramdisk takes the unlocked partitions' names in alphabetical order, by removing the prefix `crypto` the partition will always be after the root partitions. ## Formatting We format each partition using ext4, a performant file-system which doesn't require maintenance. You can use other filesystems, like xfs or btrfs, if you need features specific to them.
mkfs.ext4 /dev/mapper/crypto-work
mkfs.ext4 /dev/mapper/crypto-private
mkfs.ext4 /dev/mapper/nix-store
## The boot partition The boot partition should be formatted using fat32 when using UEFI with `mkfs.fat -F 32 /dev/sda1`. It can be formatted in ext4 if you are using legacy boot (MBR). # Preparing the system Mount the partitions onto `/mnt` and its subdirectories to prepare for the installer.
mount /dev/mapper/crypto-work /mnt
mkdir -p /mnt/etc/nixos /mnt/boot /mnt/nix
mount /dev/mapper/nix-store /mnt/nix
mkdir /mnt/nix/config
mount --bind /mnt/nix/config /mnt/etc/nixos
mount /dev/sda1 /mnt/boot
We generate a configuration file:
nixos-generate-config --root /mnt
Edit `/mnt/etc/nixos/hardware-configuration.nix` to change the following parts:
fileSystems."/" =
{ device = "/dev/disk/by-uuid/xxxxxxx-something";
fsType = "ext4";
};
boot.initrd.luks.devices."crypto-work" = "/dev/disk/by-uuid/xxxxxx-something";
by
fileSystems."/" =
{ device = "/dev/mapper/crypto-work";
fsType = "ext4";
};
boot.initrd.luks.devices."crypto-work" = "/dev/pool/root-work";
We need two configuration files to describe our two environments, we will use `hardware-configuration.nix` as a template and apply changes to it.
sed '/imports =/,+3d' /mnt/etc/nixos/hardware-configuration.nix > /mnt/etc/nixos/work.nix
sed '/imports =/,+3d ; s/-work/-private/g' /mnt/etc/nixos/hardware-configuration.nix > /mnt/etc/nixos/private.nix
rm /mnt/etc/nixos/hardware-configuration.nix
Edit `/mnt/etc/nixos/configuration.nix` to make the `imports` code at the top of the file look like this:
imports =
[
./work.nix
./private.nix
];
Remember we removed the file `/mnt/etc/nixos/hardware-configuration.nix` so it shouldn't be imported anymore. Now we need to hook each configuration to become a different boot entry, using the NixOS feature called specialisation. We will make the environment you want to be the default in the boot entry as a non-specialised environment and non-inherited so it's not picked up by the other, and a specialisation for the other environment. For the hardware configuration files, we need to wrap them with some code to create a specialisation, and the "non-specialisation" case that won't propagate to the other specialisations. Starting from a file looking like this, some code must be added at the top and bottom of the files depending on if you want it to be the default context or not. Content of an example file:
{ config, pkgs, modulesPath, ... }:
{
boot.initrd.availableKernelModules = ["ata_generic" "uhci_hcd" "ehci_pci" "ahci" "usb_storage" "sd_mod"];
boot.initrd.kernelModules = ["dm-snapshot"];
boot.kernelModules = ["kvm-intel"];
boot.extraModulePackages = [];
fileSystems."/" = {
device = "/dev/mapper/crypto-private";
fsType = "ext4";
};
---8<-----
[more code here]
---8<-----
swapDevices = [];
networking.useDHCP = lib.mkDefault true;
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}
Example result of the default context: => https://github.com/tweag/nixos-specialisation-dual-boot/blob/master/configuration/private.nix GitHub example ifle
({ lib, config, pkgs, ...}: {
config = lib.mkIf (config.specialisation != {}) {
boot.initrd.availableKernelModules = ["ata_generic" "uhci_hcd" "ehci_pci" "ahci" "usb_storage" "sd_mod"];
boot.initrd.kernelModules = ["dm-snapshot"];
boot.kernelModules = ["kvm-intel"];
boot.extraModulePackages = [];
fileSystems."/" = {
device = "/dev/mapper/crypto-private";
fsType = "ext4";
};
---8<-----
[more code here]
---8<-----
swapDevices = [];
networking.useDHCP = lib.mkDefault true;
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
};
})
Note the extra leading `(` character that must also be added at the very beginning. Example result for a specialisation named `work` => https://github.com/tweag/nixos-specialisation-dual-boot/blob/master/configuration/work.nix GitHub example file
{ config, lib, pkgs, modulesPath, ... }:
{
specialisation = {
work.configuration = {
system.nixos.tags = [ "work" ];
boot.initrd.availableKernelModules = ["ata_generic" "uhci_hcd" "ehci_pci" "ahci" "usb_storage" "sd_mod"];
boot.initrd.kernelModules = ["dm-snapshot"];
boot.kernelModules = ["kvm-intel"];
boot.extraModulePackages = [];
fileSystems."/" = {
device = "/dev/mapper/crypto-work";
fsType = "ext4";
};
---8<-----
[more code here]
---8<-----
swapDevices = [];
networking.useDHCP = lib.mkDefault true;
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
};
};
}
# System configuration It's now the time to configure your system as you want. The file `/mnt/etc/nixos/configuration.nix` contains shared configuration, this is the right place to define your user, shared packages, network and services. The files `/mnt/etc/nixos/private.nix` and `/mnt/etc/nixos/work.nix` can be used to define context specific configuration. ## LVM Workaround During the numerous installation tests I've made to validate this guide, on some hardware I noticed an issue with LVM detection, add this line to your global configuration file to be sure your disks will be detected at boot.
boot.initrd.preLVMCommands = "lvm vgchange -ay";
# Installation ## First installation The partitions are mounted and you configured your system as you want it, we can run the NixOS installer.
nixos-install
Wait for the copy process to complete after which you will be prompted for the root password of the current crypto-work environment (or the one you mounted here), you also need to define the password for your user now by chrooting into your NixOS system.
New password:
Retape new password:
passwd: password updated successfully
From now, you have a password set for root and your user for the crypto-work environment, but no password are defined in the crypto-private environment. ## Second installation We will rerun the installation process with the other environment mounted:
mount /dev/mapper/crypto-private /mnt
mkdir -p /mnt/etc/nixos /mnt/boot /mnt/nix
mount /dev/mapper/nix-store /mnt/nix
mount --bind /mnt/nix/config /mnt/etc/nixos
mount /dev/sda1 /mnt/boot
As the NixOS configuration is already done and is shared between the two environments, just run `nixos-install`, wait for the root password to be prompted, apply the same chroot sequence to set a password to your user in this environment. You can reboot, you will have a default boot entry for the default chosen environment, and the other environment boot entry, both requiring their own passphrase to be used. Now, you can apply changes to your NixOS system using `nixos-rebuild` from both work and private environments. # Conclusion Congratulations for going through this long installation process. You can now log in to your two contexts and use them independently, and you can configure them by applying changes to the corresponding files in `/etc/nixos/`. # Going further ## Swap and hibernation With this setup, I chose to not cover swap space because this would allow to leak secrets between the contexts. If you need some swap, you will have to create a file on the root partition of your current context, and add the according code to the context filesystems. If you want to use hibernation in which the system stops after dumping its memory into the swap file, your swap size must be larger than the memory available on the system. It's possible to have a single swap for both contexts by using a random encryption at boot for the swap space, but this breaks hibernation as you can't unlock the swap to resume the system. ## Declare users' passwords As you noticed, you had to run `passwd` in both contexts to define your user password and root's password. It is possible to define their password declaratively in the configuration file, refers to the documentation of`users.mutableUsers` and `users.extraUsers.<name>.initialHashedPassword` for more information. ## Rescue the installation If something is wrong when you boot the first time, you can reuse the installer to make changes to your installation: you can run again the `cryptsetup luksOpen` and `mount` commands to get access to your filesystems, then you can edit your configuration files and run `nixos-install` again. </pre> ]]> </description> <guid>gemini://perso.pw/blog//articles/two-nixos-as-one.gmi</guid> <link>gemini://perso.pw/blog//articles/two-nixos-as-one.gmi</link> <pubDate>Thu, 17 Nov 2022 00:00:00 GMT</pubDate> </item> <item> <title>Mirroring sources used in nixpkgs (software preservation)</title> <description> <![CDATA[ <pre># Introduction This may appear like a very niche use case, in my quest of software conservancy for nixpkgs I didn't encounter many people understanding why I was doing this. I would like to present you a project I made to easily download all the sources files required to build packages from nixpkgs, allowing to keep offline copies. Why would you like to keep a local copy? If upstream disappear, you can't get access to the sources anymore, except maybe in Hydra, but you rely on a third party to access the sources, so it's still valuable to have local copies of software you care about, just to make copies. It's not that absolutely useful for everyone, but it's always important to have such tools available. => https://tildegit.org/solene/nixpkgs-mirror-tarballs nixpkgs-mirror-tarballs project page # How to use it You must run it on a system with `nix` installed. After cloning and 'cd-ing' into the directory, simply run `./run.sh some package list | ./mirror.pl`. The command `run.sh` will generate a JSON structure containing all the dependencies used by the packages listed as arguments, and the script `mirror.pl` will iterate over the JSON list and use nix's fetcher to gather the sources in the nix store, verifying the checksum on the go. This will create a directory `distfiles` containing symlinks to the sources files stored in the store. The symlinks are very important as they will prevent garbage collection from the store, and it's also used internally to quickly check if a file is already in the store. To delete a file from the store, remove its symlink and run the garbage collector. # Limitation I still need to figure how to get a full list of all the packages, I currently have a work in progress relying on `nix search --json` but it doesn't work on 100% of the packages for some reasons. It's currently not possible to easily trim distfiles that aren't useful anymore, I plan to maybe add it someday. # Trivia This task is natively supported in the OpenBSD tool building packages (dpb), it can fetch multiples files in parallel and automatic remove files that aren't used anymore. This was really complicated to figure how to replicate this with nixpkgs. </pre> ]]> </description> <guid>gemini://perso.pw/blog//articles/nixpkgs-fetch-all-sources.gmi</guid> <link>gemini://perso.pw/blog//articles/nixpkgs-fetch-all-sources.gmi</link> <pubDate>Thu, 03 Nov 2022 00:00:00 GMT</pubDate> </item> <item> <title>Nushell: Introduction to a new kind of shell</title> <description> <![CDATA[ <pre># What is nushell Let me introduce you to a nice project I found while lurking on the Internet. It's called nushell and is a non-POSIX shell, so most of your regular shells knowledge (zsh, bash, ksh, etcโฆ) can't be applied on it, and using it feels like doing functional programming. It's a good tool for creating robust data manipulation pipelines, you can think of it like a mix of a shell which would include awk's power, behave like a SQL database, and which knows how to import/export XML/JSON/YAML/TOML natively. You may want to try nushell only as a tool, and not as your main shell, it's perfectly fine. With a regular shell, iterating over a command output can be complex when it involves spaces or newlines, for instance, that's why `find` and `xargs` have a `-print0` parameter to have a special delimited between "items", but it doesn't compose well with other tools. Nushell handles correctly this situation as its manipulates the data using indexed entries, given you correctly parsed the input at the beginning. => https://www.nushell.sh/ Nushell official project page => https://www.nushell.sh/book/ Nushell documentation website # How to get it Nushell is a rust program, so it should work on every platform where Rust/Cargo are supported. I packaged it for OpenBSD, so it's available on -current (and will be in releases after 7.3 is out), the port could be used on 7.2 with no effort. With Nix, it's packaged under the name `nushell`, the binary name is `nu`. For other platforms, it's certainly already packaged, otherwise you can find installation instructions to build it from sources. => https://www.nushell.sh/book/installation.html#build-from-source Nushell documentation: Building nushell from sources # Configuration At first run, you are prompted to use default configuration files, I'd recommend accepting, you will have files created in `~/.config/nushell/`. The only change I made from now is to make Tab completion case-sensitive, so `D[TAB]` completes to `Downloads` instead of asking between `dev` and `Downloads`. Look for `case_sensitive_completions` in `.config/nushell/config.nu` and set it to `true`. # Examples If you are like me, and you prefer learning by doing instead of reading a lot of documentation, I prepared a bunch of real world use case you can experiment with. The documentation is still required to learn the many commands and syntax, but examples are a nice introduction. ## Getting help Help from nushell can be parsed directly with nu commands, it's important to understand where to find information about commands. Use `help a-command` to learn from a single command:
help help
Display help information about commands.
Usage:
> help {flags} ...(rest)
Flags:
-h, --help - Display this help message
-f, --find <String> - string to find in command names, usage, and search terms
[cut so it's not too long]
Use `help commands` to list all available commands (I'm limiting to 5 between there are a lot of commands)
help commands | last 5
โญโโโโฌโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโฌโโโโโโโโโโโโฌโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโฎ
โ # โ name โ category โ is_plugin โ is_custom โ is_keyword โ usage โ search_terms โ
โโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโผโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโค
โ 0 โ window โ filters โ false โ false โ false โ Creates a sliding window of `window_size` that slide by n rows/elements across input. โ โ
โ 1 โ with-column โ dataframe or lazyframe โ false โ false โ false โ Adds a series to the dataframe โ โ
โ 2 โ with-env โ env โ false โ false โ false โ Runs a block with an environment variable set. โ โ
โ 3 โ wrap โ filters โ false โ false โ false โ Wrap the value into a column. โ โ
โ 4 โ zip โ filters โ false โ false โ false โ Combine a stream with the input โ โ
โฐโโโโดโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโดโโโโโโโโโโโโดโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโฏ
Add `sort-by category` to list them... sorted by category.
help commands | sort-by category
Use `where category == filters` to only list commands from the `filters` category.
help commands | where category == filters
Use `find foobar` to return lines containing `foobar`.
help commands | find insert
## General examples ### Converting a data structure into another This is just an example from YAML to JSON, but you can convert much more formats into other formats.
open dev/home-impermanence/tests/impermanence.yml | to json
{
"directories":
[
"Documents",
"Downloads",
"Datastore/Music",
"Datastore",
"Datastore/",
"Datastore/Music/Band1",
".config",
"foo/bar",
"foo/bar/hello"
],
"size": "500m",
"files":
[
".Xdefaults",
".profile",
".xsession",
]
}
### Parsing sysctl output
sysctl -a | parse -r "(?<key>.*?)=(?<value>.*)"
Because the output would be too long, here is how you get 10 random keys from sysctl.
sysctl -a | parse -r "(?<key>.*?)=(?<value>.*)" | shuffle | last 10 | sort-by key
โญโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโฎ
โ # โ key โ value โ
โโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโค
โ 0 โ fs.quota.reads โ 0 โ
โ 1 โ net.core.high_order_alloc_disable โ 0 โ
โ 2 โ net.ipv4.conf.all.drop_gratuitous_arp โ 0 โ
โ 3 โ net.ipv4.conf.default.rp_filter โ 2 โ
โ 4 โ net.ipv4.conf.lo.disable_xfrm โ 1 โ
โ 5 โ net.ipv4.conf.lo.forwarding โ 0 โ
โ 6 โ net.ipv4.ipfrag_low_thresh โ 3145728 โ
โ 7 โ net.ipv6.conf.all.ioam6_id โ 65535 โ
โ 8 โ net.ipv6.conf.all.router_solicitation_interval โ 4 โ
โ 9 โ net.mptcp.enabled โ 1 โ
โฐโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโฏ
### Recursively convert FLAC files to OPUS A complicated task using a regular shell, recursively find files matching a pattern and then run a given command on each of them, in parallel. Which is exactly what you need if you want to convert your music library into another format, let's convert everything from FLAC to OPUS in this example. In the following command line, we will look for every `.flac` file in the subdirectories, then run in parallel using `par-each` the command `ffmpeg` on it, from its current name to the old name with `.flac` changed to `.opus`. The `let convert` and `| complete` commands are used to store the output of each command into a result table, and store it in the variable `convert` so we can query it after the job is done.
let convert = (ls **/*flac | par-each { |file| do -i { ffmpeg -i $file.name ($file.name | str replace flac opus) } | complete })
Now, we have a structure in `convert` that contains the columns `stdout`, `stderr` and `exit_code`, so we can look if all the commands did run correctly using the following query.
$convert | where exit_code != 0
### Convert PDF/CBR/CBZ pages into webp and CBZ archives I have a lot of digitalized books/mangas/comics, this conversion is a handy operation reducing the size of the files by 40% (up to 70%).
def conv [] {
if (ls | first | get name | str contains ".jpg") {
ls *jpg | par-each {|file| do -i { cwebp $file.name -o ($file.name | str replace jpg webp) } | complete }
rm *jpg
}
if (ls | first | get name | str contains ".ppm") {
ls *ppm | par-each {|file| do -i { cwebp $file.name -o ($file.name | str replace ppm webp) } | complete }
rm *ppm
}
}
ls * | each {|file| do -i {
if ($file.name | str contains ".cbz") { unzip $file.name -d ./pages/ } ;
if ($file.name | str contains ".cbr") { unrar e -op./pages/ $file.name } ;
if ($file.name | str contains ".pdf") { mkdir pages ; pdfimages $file.name pages/page } ;
cd pages ; conv ; cd ../ ; ^zip -r $"($file.name).webp.cbz" pages ; rm -fr pages
} }
### Parse gnu tar output
ใtar vtf nushell.tgz | parse -r "(.*?) (.*?)\/(.*?)\\s+(.*?) (.*?) (.*?) (.*)" | rename mode owner group size date time path
โญโโโโฌโโโโโโโโโโโโโฌโโโโโโโโโฌโโโโโโโโฌโโโโโโโโฌโโโโโโโโโโโโโฌโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโฎ
โ # โ mode โ owner โ group โ size โ date โ time โ path โ
โโโโโผโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโผโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโค
โ 0 โ drwxr-xr-x โ solene โ wheel โ 0 โ 2022-10-30 โ 16:45 โ nushell โ
โ 1 โ -rw-r--r-- โ solene โ wheel โ 519 โ 2022-10-30 โ 13:41 โ nushell/Makefile โ
โ 2 โ -rw-r--r-- โ solene โ wheel โ 29304 โ 2022-10-29 โ 18:49 โ nushell/crates.inc โ
โ 3 โ -rw-r--r-- โ solene โ wheel โ 75003 โ 2022-10-29 โ 13:16 โ nushell/distinfo โ
โ 4 โ drwxr-xr-x โ solene โ wheel โ 0 โ 2022-10-30 โ 00:00 โ nushell/pkg โ
โ 5 โ -rw-r--r-- โ solene โ wheel โ 337 โ 2022-10-29 โ 18:52 โ nushell/pkg/DESCR โ
โ 6 โ -rw-r--r-- โ solene โ wheel โ 14 โ 2022-10-29 โ 18:53 โ nushell/pkg/PLIST โ
โฐโโโโดโโโโโโโโโโโโโดโโโโโโโโโดโโโโโโโโดโโโโโโโโดโโโโโโโโโโโโโดโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโฏ
### Opening spreadsheets
ใopen --raw freq.ods | from ods | get Sheet1 | headers
โญโโโโฌโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโฌโโโโโโโโโโโโฌโโโโโโโโโโฌโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโฌโโโโโโโโฌโโโโโโโโโโฌโโโโโโโโโโฌโโโโโโโโโโโฎ
โ # โ Policy โ Compile time โ Idle time โ column3 โ Compile power โ Idle power โ Total โ column8 โ column9 โ column10 โ
โโโโ๏ฟฝ๏ฟฝ๏ฟฝโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโโผโโโโโโโโโโผโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโผโโโโโโโโโโผโโโโโโโโโโผโโโโโโโโโโโค
โ 0 โ powersaving โ 1123.00 โ 0.00 โ โ 5.90 โ 0.00 โ 5.90 โ โ โ โ
โ 1 โ auto โ 871.00 โ 252.00 โ โ 5.60 โ 0.74 โ 6.34 โ โ 0.44 โ 6.94 โ
โฐโโโโดโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโดโโโโโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโดโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโโฏ
We can format new strings from columns values.
ใopen --raw freq.ods | from ods | get Sheet1 | headers | each {|row| do { echo $"($row.Policy) = ($row.'Compile power' + $row.'Idle power') Watts" } }
โญโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ 0 โ powersaving = 5.9 Watts โ
โ 1 โ auto = 6.34 Watts โ
โฐโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
### Filter and sort a JSON There is a website listing packages that can be updated on OpenBSD at https://portroach.openbsd.org, it provides json of data for rendering. We can use this data to sort which maintainer has the most up to date percentage, but only if they manage more than 30 packages.
fetch https://portroach.openbsd.org/json/totals.json | get results | where total > 30 | sort-by percentage
## NixOS examples ### Query profiles packages
nix profile list | parse "{index} {flake} {source} {store}"
โญโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ # โ flake โ source โ store โ
โโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 0 โ flake:nixpkgs#legacyPackages.x86_64-linux.libreoffice โ path:/nix/store/iw3xi0bfszikb0dmyywp7pm590jvbqvs-source?lastModified=1663494472& โ /nix/store/1m6wp1pznhf2nrvs7xwmvig5x3nspq0j-libreoffice-7.2.6.2 โ
โ โ โ narHash=sha256-fSowlaoXXWcAM8m9wA6u+eTJJtvruYHMA+Lb%2ftFi%2fqM=&rev=f677051b8dc0 โ โ
โ โ โ b5e2a9348941c99eea8c4b0ff28f#legacyPackages.x86_64-linux.libreoffice โ โ
โ 1 โ flake:nixpkgs#legacyPackages.x86_64-linux.dino โ path:/nix/store/9cj1830pvd88lrwmmxw65achd3lw2q9n-source?lastModified=1667050928& โ /nix/store/ljhn4n1q5pk7wr337v681m1h39jp5l2y-dino-0.3.0 โ
โ โ โ narHash=sha256-xOn0ZgjImIyeecEsrjxuvlW7IW5genTwvvnDQRFncB8=&rev=fdebb81f45a1ba2c โ โ
โ โ โ 4afca5fd9f526e1653ad0949#legacyPackages.x86_64-linux.dino โ โ
โฐโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
### Query flakes
nix flake show --json | from json
โญโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโฎ
โ defaultPackage โ {record 5 fields} โ
โ packages โ {record 5 fields} โ
โฐโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโฏ
nix flake show --json | from json | get packages
โญโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโฎ
โ aarch64-darwin โ {record 2 fields} โ
โ aarch64-linux โ {record 2 fields} โ
โ i686-linux โ {record 2 fields} โ
โ x86_64-darwin โ {record 2 fields} โ
โ x86_64-linux โ {record 2 fields} โ
โฐโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโฏ
nix flake show --json | from json | get packages.x86_64-linux
โญโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโฎ
โ nix-dev-html โ {record 2 fields} โ
โ nix-dev-pyenv โ {record 3 fields} โ
โฐโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโฏ
### Parse a flake.lock file
open flake.lock | from json | get nodes.nixpkgs.locked
โญโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ lastModified โ 1663494472 โ
โ narHash โ sha256-fSowlaoXXWcAM8m9wA6u+eTJJtvruYHMA+Lb/tFi/qM= โ
โ path โ /nix/store/iw3xi0bfszikb0dmyywp7pm590jvbqvs-source โ
โ rev โ f677051b8dc0b5e2a9348941c99eea8c4b0ff28f โ
โ type โ path โ
โฐโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
## OpenBSD examples ### Parse /etc/fstab
open /etc/fstab | from ssv -m 1 -n | rename device mountpoint fs options freq passno
_โโโโโฌโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโฌโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโฌโโโโโโโโ_
โ # โ device โ mountpoint โ fs โ options โ freq โ passno โ
โโโโโโผโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโผโโโโโโโโโค
โ 0 โ 55a6c21017f858cb.b โ none โ swap โ sw โ __ โ __ โ
โ 1 โ 55a6c21017f858cb.a โ / โ ffs โ rw,noatime,softdep โ 1 โ 1 โ
โ 2 โ 55a6c21017f858cb.l โ /home โ ffs โ rw,noatime,wxallowed,softdep,nodev,nosuid โ 1 โ 2 โ
โ 3 โ 55a6c21017f858cb.d โ /tmp โ ffs โ rw,noatime,softdep,nodev,nosuid โ 1 โ 2 โ
โ 4 โ 55a6c21017f858cb.f โ /usr โ ffs โ rw,noatime,softdep,nodev โ 1 โ 2 โ
โ 5 โ 55a6c21017f858cb.g โ /usr/X11R6 โ ffs โ rw,noatime,softdep,nodev โ 1 โ 2 โ
โ 6 โ 55a6c21017f858cb.h โ /usr/local โ ffs โ rw,noatime,softdep,wxallowed,nodev โ 1 โ 2 โ
โ 7 โ 55a6c21017f858cb.k โ /usr/obj โ ffs โ rw,noatime,softdep,nodev,nosuid โ 1 โ 2 โ
โ 8 โ 55a6c21017f858cb.j โ /usr/src โ ffs โ rw,noatime,softdep,nodev,nosuid โ 1 โ 2 โ
โ 9 โ 55a6c21017f858cb.e โ /var โ ffs โ rw,noatime,softdep,nodev,nosuid โ 1 โ 2 โ
โ 10 โ afebb2a83a449265.b โ /build โ ffs โ rw,noatime,softdep,wxallowed,nosuid โ 1 โ 2 โ
โ 11 โ afebb2a83a449265.a โ /build/pobj โ ffs โ rw,noatime,softdep,nodev,wxallowed,nosuid โ 1 โ 2 โ
โ 12 โ 55a6c21017f858cb.b โ /build/pobj_mfs โ mfs โ -s1G,wxallowed,noatime,rw โ 0 โ 0 โ
โฐโโโโโดโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโดโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโดโโโโโโโโ_
### Parse /var/log/messages
open /var/log/messages | parse -r "(?<date>\\w+ \\d+ \\d+:\\d+:\\d+) (?<hostname>\\w+) (?<program>\\w+)\\[?(?<pid>\\d+)?\\]?: (?<message>.*)"
โญโโโโฌโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโโโฌโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ # โ date โ hostname โ program โ pid โ message โ
โโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 0 โ Oct 31 10:27:32 โ fx6 โ collectd โ 55258 โ uc_update: Value too old: name = fx6openbsd/swap/swap-free; value time = 1667208452.108; last cache update = 1667208452.108; โ
โ 1 โ Oct 31 10:43:02 โ fx6 โ collectd โ 55258 โ uc_update: Value too old: name = fx6openbsd/swap/percent-free; value time = 1667209382.102; last cache update = 1667209382.102; โ
โ 2 โ Oct 31 11:00:01 โ fx6 โ syslogd โ 4629 โ restart โ
โ 3 โ Oct 31 11:05:26 โ fx6 โ pkg_delete โ โ Removed helix-22.08.1 โ
โ 4 โ Oct 31 11:05:29 โ fx6 โ pkg_add โ โ Added helix-22.08.1 โ
โ 5 โ Oct 31 11:16:49 โ fx6 โ pkg_add โ โ Added llvm-13.0.0p3 โ
โ 6 โ Oct 31 11:20:18 โ fx6 โ pkg_add โ โ Added clang-tools-extra-13.0.0p2 โ
โ 7 โ Oct 31 11:20:32 โ fx6 โ pkg_add โ โ Added bash-5.2.2 โ
โ 8 โ Oct 31 11:20:34 โ fx6 โ pkg_add โ โ Added fzf-0.34.0 โ
โ 9 โ Oct 31 11:21:01 โ fx6 โ pkg_delete โ โ Removed fzf-0.34.0 โ
โฐโโโโดโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโโโดโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
### Parse pkg_info output
pkg_info | str trim | parse -r "(?<package>.*?)-(?<version>[a-zA-Z0-9\\.]*?) (?<description>.*)" | str trim description
โญโโโโโฌโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ # โ package โ version โ description โ
โโโโโโผโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 0 โ athn-firmware โ 1.1p4 โ firmware binary images for athn(4) driver โ
โ 1 โ collectd โ 5.12.0 โ system metrics collection engine โ
โ 2 โ curl โ 7.85.0 โ transfer files with FTP, HTTP, HTTPS, etc. โ
โ 3 โ gettext-runtime โ 0.21p1 โ GNU gettext runtime libraries and programs โ
โ 4 โ intel-firmware โ 20220809v0 โ microcode update binaries for Intel CPUs โ
โ 5 โ inteldrm-firmware โ 20220913 โ firmware binary images for inteldrm(4) driver โ
โ 6 โ kakoune โ 2021.11.08 โ modal code editor with a focus on interactivity โ
โ 7 โ libgcrypt โ 1.10.1p0 โ crypto library based on code used in GnuPG โ
โ 8 โ libgpg-error โ 1.46 โ error codes for GnuPG related software โ
โ 9 โ libiconv โ 1.17 โ character set conversion library โ
โ 10 โ libstatgrab โ 0.91p5 โ system statistics gathering library โ
โ 11 โ libxml โ 2.10.3 โ XML parsing library โ
โ 12 โ libyajl โ 2.1.0 โ small JSON library written in ANSI C โ
โ 13 โ nghttp2 โ 1.50.0 โ library for HTTP/2 โ
โ 14 โ nushell โ 0.70.0 โ a new kind of shell โ
โ 15 โ obsdfreqd โ 1.0.3 โ userland daemon to manage CPU frequency โ
โ 16 โ quirks โ 6.42 โ exceptions to pkg_add rules and cache โ
โ 17 โ rsync โ 3.2.5pl0 โ mirroring/synchronization over low bandwidth links โ
โ 18 โ ttyplot โ 1.4p0 โ realtime plotting utility for terminals โ
โ 19 โ vmm-firmware โ 1.14.0p0 โ firmware binary images for vmm(4) driver โ
โ 20 โ xz โ 5.2.7 โ LZMA compression and decompression tools โ
โ 21 โ yash โ 2.52 โ POSIX-compliant command line shell โ
โฐโโโโโดโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
# Conclusion Nushell is very fun, it's terribly different from regular shells, but it comes with a powerful language and tooling. I always liked shells because of pipes commands, allowing to construct a complex transformation/analysis step by step, and easily inspect any step, or be able to replace a step by another. With nushell, it feels like I finally have a better tool to create more reliable, robust, portable and faster command pipelines. The learning curve didn't feel too hard, but maybe it's because I'm already used to functional programming. </pre> ]]> </description> <guid>gemini://perso.pw/blog//articles/nushell.gmi</guid> <link>gemini://perso.pw/blog//articles/nushell.gmi</link> <pubDate>Mon, 31 Oct 2022 00:00:00 GMT</pubDate> </item> </channel> </rss>