Modularize the systemd features into its own notes

This commit is contained in:
Gabriel Arazas 2021-08-09 14:04:42 +08:00
parent f868f3b3da
commit c137dcbdcb
7 changed files with 210 additions and 206 deletions

View File

@ -0,0 +1,57 @@
:PROPERTIES:
:ID: 8505f1f0-f15b-4b04-91fc-12be01913ce6
:END:
#+title: systemd-boot
#+date: 2021-08-07 20:08:09 +08:00
#+date_modified: 2021-08-07 20:08:31 +08:00
#+language: en
systemd also comes with a bootloader aptly named =systemd-boot= though it only supports UEFI-based firmware.
Just like GRUB, they can be configured through plain-text files.
For detailed information about the bootloader, see the manual page =systemd-boot.7=.
With a complete installation, the bootloader config folder may look like the following list.
#+begin_src
/boot/
`-- loader
|-- entries # (ref:loader-entries)
| `-- arch.conf
|-- loader.conf # (ref:loader-conf)
`-- random-seed
#+end_src
- [[(loader-entries)][=loader/entries/=]] is a directory containing all of the entries available to be booted.
- [[(loader-conf)][=loader.conf=]] contains the loader configuration.
Most Linux distros with systemd installed should have a sample config file somewhere. [fn:: In case of Arch Linux, it has an example file at =/usr/share/systemd/bootctl/=.]
As an example, we'll show what those look like.
=loader.conf= is the configuration for the boot loader including the timeout seconds among others.
Here is a sample of a bootloader configuration.
#+begin_src
default arch
timeout 4
#+end_src
In this config, this simply makes the =arch= loader entry to be default when no actions has occurred.
It will start loading it automatically after a timeout of 4 seconds.
The =arch= loader entry can be found at =${ESP}/loader/entries/arch.conf=.
The following code block shows what a loader entry looks like.
#+begin_src
title Arch Linux
linux /vmlinuz-linux
initrd /initramfs-linux.img
options root="PARTUUID=${PARTUUID}"
#+end_src
You can customize and create extra entries for the same installation.
This is what roam:NixOS does with its package generations, letting the user to boot to a specific point in time from the boot loader.
Very useful for emergency boots in case the current generation breaks for whatever reason.
For complete details of the configuration file, you can see =loader.conf.5= manual page.

View File

@ -0,0 +1,24 @@
:PROPERTIES:
:ID: 3c67e623-c269-4c9b-9bdf-4ad677d46a35
:END:
#+title: systemd environment directives
#+date: 2021-08-07 19:58:29 +08:00
#+date_modified: 2021-08-07 19:59:45 +08:00
#+language: en
systemd enables setting the environment through environment directives.
Just like how [[id:c7edff80-6dea-47fc-8ecd-e43b5ab8fb1e][systemd at user-level]], you can set it at user-level by placing them in certain user-level load paths (e.g., =$XDG_CONFIG_HOME/environment.d=).
It needs a =*.conf= file in one of the load paths (seen from the =environment.d.5= manual page).
Keep in mind it does not use the shell and instead makes use of shell-like syntax.
The following code block is an example of setting Nix-related environment variables to enable desktop integrations.
#+begin_src ini
# Enable desktop integration with Nix-installed applications.
NIX_PATH=$HOME/.nix-defexpr/channels${NIX_PATH:+:}$NIX_PATH
PATH=${PATH:+$PATH:}$HOME/.nix-profile/bin
XDG_DATA_DIRS=${XDG_DATA_DIRS:+$XDG_DATA_DIRS:}$HOME/.nix-profile/share/
#+end_src

View File

@ -0,0 +1,18 @@
:PROPERTIES:
:ID: d83c099a-fc11-4ccc-b265-4de97c85dcbe
:END:
#+title: systemd-journald
#+date: 2021-08-07 20:12:30 +08:00
#+date_modified: 2021-08-07 20:17:23 +08:00
#+language: en
systemd has a journal service storing logs from units.
It provides a consistent and structured way how to check the logs.
The service also has the following interfaces.
- =journald= is the system logging functionality of systemd.
- It comes with the system daemon service and the =journalctl= command.
See [[id:941e0a85-1bb4-45be-a729-1b577c7ee317][Command line: journalctl]] for more details.

View File

@ -0,0 +1,44 @@
:PROPERTIES:
:ID: e4dba4ef-71dd-4d30-9a2c-4ad97223510b
:END:
#+title: systemd-networkd
#+date: 2021-08-07 20:01:23 +08:00
#+date_modified: 2021-08-07 20:06:47 +08:00
#+language: en
With a systemd-ful environment, you can run the network daemon (i.e., =systemd-networkd=).
Once enabled, you can run =networkctl= to list all of the network devices. [fn:: You can also run ~ip address~ for it.]
#+begin_src shell :cache yes
networkctl
#+end_src
#+results[84c83a400d07ef38e6813bc9ce677cef8a38bd66]:
: IDX LINK TYPE OPERATIONAL SETUP
: 1 lo loopback carrier unmanaged
: 2 enp1s0 ether routable configured
: 3 wlan0 wlan routable configured
:
: 3 links listed.
To configure network manager, you can create a network file in one of systemd unit file paths in the system.
Each of the device will be assigned an IP address.
You can either assign an IP address or dynamically assign them in some way.
One of the common ways to do dynamic IP addresses is installing a DHCP server (which is another thing to be configured).
Here's an example of configuring any wireless devices and assigning a dynamic IP addresses with [[https://wiki.archlinux.org/title/Network_configuration#DHCP][DHCP]].
#+begin_src
[Match]
Type=wlan
[Network]
DHCP=yes
IPv6PrivacyExtensions=yes
[DHCPv4]
RouteMetric=1024
[DHCPv6]
RouteMetric=1024
#+end_src

View File

@ -3,7 +3,7 @@
:END:
#+title: Exploring systemd features
#+date: "2021-05-20 22:37:22 +08:00"
#+date_modified: "2021-08-02 12:02:46 +08:00"
#+date_modified: "2021-08-07 20:21:53 +08:00"
#+language: en
#+property: header-args :eval no
@ -16,6 +16,11 @@ Among other things, it has the following list of features.
- [[id:f1b21fc8-86a5-47cd-b3d8-da6ac7a34427][systemd timers]] which can replace cron for task scheduling.
- [[id:cd5f0d04-d9bb-44e8-a0f2-630ea58c1e94][systemd services]] along with the usual antics of a service manager such as managing dependencies and commands to run when killed.
- [[id:a602f900-cdcf-4090-9278-d5926d80eedc][systemd transient units]] for quickly creating and scheduling one-off services.
- [[id:14b49597-011c-4da1-b955-bed6059af4a3][systemd unit templates]] is handy for managing units that have common structure, enabling to start them quickly and dynamically.
- [[id:3c67e623-c269-4c9b-9bdf-4ad677d46a35][systemd environment directives]] enable setting environment variables from a systemd-ful session.
- [[id:e4dba4ef-71dd-4d30-9a2c-4ad97223510b][systemd-networkd]] is the network configuration manager in case you want to do [[id:a208dd50-2ebc-404d-b407-3ec2f556535e][Network configuration in Linux]].
- [[id:8505f1f0-f15b-4b04-91fc-12be01913ce6][systemd-boot]] is a bootloader mainly for UEFI-based systems.
- [[id:d83c099a-fc11-4ccc-b265-4de97c85dcbe][systemd-journald]] is the system logging service providing a structured way to manage your logs from different units.
@ -43,206 +48,3 @@ systemctl show-environment
systemctl --user start $SERVICE
#+end_src
* Unit templates
You can create unit templates which is useful for simple services that only requires an argument.
Rather than creating individual simple service files, let systemd handle it.
For example, you may want to spawn a service for Borgmatic with multiple repos.
If you don't know templates, the dumb way to serve multiple repos is to create individual unit files for each.
If you want to schedule them, you also have to create a timer unit for each.
The more efficient solution is to use templates.
To make a unit template, there are only a handful of requirements:
- Addition of =%i= to represent the template value.
- The unit file name has to end with =@= (e.g., =unit-name@.service=, =unit-name@.timer=).
This could be compressed into a template for a service unit.
The following code shows how to create one.
#+begin_src ini
[Unit]
Description=Periodic safety backup for %i
Documentation=man:borg(1) https://www.borgbackup.org/
[Service]
Type=simple
ExecStart=borgmatic --config %i --verbose
[Install]
WantedBy=default.target
#+end_src
To use the service, you have to give it a value — e.g., ~systemctl --user start borg-backup@test.yaml.service~.
That's all good but what about scheduling them?
What if you want to create an archive every hour starting at 08:00?
You can just create a templated timer unit.
#+begin_src ini
[Unit]
Description=Periodic safety backup for %i
Documentation=man:borg(1) https://www.borgbackup.org/
[Timer]
Unit=borg-backup@%i.service
Calendar=08/1:00:00
Persistent=true
[Install]
WantedBy=default.target
#+end_src
* Bootloader configuration
systemd also comes with a bootloader aptly named =systemd-boot= though it only supports UEFI-based firmware.
Just like GRUB, they can be configured through plain-text files.
For detailed information about the bootloader, see the manual page =systemd-boot.7=.
With a complete installation, the bootloader config folder may look like the following list.
#+begin_src
/boot/
`-- loader
|-- entries # (ref:loader-entries)
| `-- arch.conf
|-- loader.conf # (ref:loader-conf)
`-- random-seed
#+end_src
- [[(loader-entries)][=loader/entries/=]] is a directory containing all of the entries available to be booted.
- [[(loader-conf)][=loader.conf=]] contains the loader configuration.
Most Linux distros with systemd installed should have a sample config file somewhere. [fn:: In case of Arch Linux, it has an example file at =/usr/share/systemd/bootctl/=.]
As an example, we'll show what those look like.
=loader.conf= is the configuration for the boot loader including the timeout seconds among others.
Here is a sample of a bootloader configuration.
#+begin_src
default arch
timeout 4
#+end_src
In this config, this simply makes the =arch= loader entry to be default when no actions has occurred.
It will start loading it automatically after a timeout of 4 seconds.
The =arch= loader entry can be found at =${ESP}/loader/entries/arch.conf=.
The following code block shows what a loader entry looks like.
#+begin_src
title Arch Linux
linux /vmlinuz-linux
initrd /initramfs-linux.img
options root="PARTUUID=${PARTUUID}"
#+end_src
You can customize and create extra entries for the same installation.
This is what roam:NixOS does with its package generations, letting the user to boot to a specific point in time from the boot loader.
Very useful for emergency boots in case the current generation breaks for whatever reason.
For complete details of the configuration file, you can see =loader.conf.5= manual page.
* Network manager configuration
:PROPERTIES:
:ID: e4dba4ef-71dd-4d30-9a2c-4ad97223510b
:END:
With a systemd-ful environment, you can run the network daemon (i.e., =systemd-networkd=).
Once enabled, you can run =networkctl= to list all of the network devices. [fn:: You can also run ~ip address~ for it.]
#+begin_src shell :cache yes
networkctl
#+end_src
#+results[84c83a400d07ef38e6813bc9ce677cef8a38bd66]:
: IDX LINK TYPE OPERATIONAL SETUP
: 1 lo loopback carrier unmanaged
: 2 enp1s0 ether routable configured
: 3 wlan0 wlan routable configured
:
: 3 links listed.
To configure network manager, you can create a network file in one of systemd unit file paths in the system.
Each of the device will be assigned an IP address.
You can either assign an IP address or dynamically assign them in some way.
One of the common ways to do dynamic IP addresses is installing a DHCP server (which is another thing to be configured).
Here's an example of configuring any wireless devices and assigning a dynamic IP addresses with [[https://wiki.archlinux.org/title/Network_configuration#DHCP][DHCP]].
#+begin_src
[Match]
Type=wlan
[Network]
DHCP=yes
IPv6PrivacyExtensions=yes
[DHCPv4]
RouteMetric=1024
[DHCPv6]
RouteMetric=1024
#+end_src
* DNS server configuration
While the network manager is enabled, you can access the internet.
But only with raw IP addresses (e.g., 1.1.1.1 from Cloudflare, 93.174.95.27 for Library Genesis). [fn:: You can find the IP addresses with DNS clients such as [[https://github.com/ogham/dog][dog]] or the [[https://nodejs.org/api/dns.html][DNS library from NodeJS]].]
Accessing the domain names as you would browse the web normally is an additional layer of the web.
To access a domain name, you need a DNS client that can resolve them.
While there are plenty of DNS resolvers, systemd has a component =systemd-resolved= which you can control with =resolvectl= binary.
systemd-resolved takes a configuration from =/etc/resolve.conf= which most third-party programs also relies on.
* Log management
systemd has a journal service storing logs from units.
It provides a consistent and structured way how to check the logs.
It uses =journalctl= as the command for managing logs.
See [[id:941e0a85-1bb4-45be-a729-1b577c7ee317][Command line: journalctl]] for more details.
#+begin_src shell
journalctl --user-unit backup.service --follow --boot
#+end_src
* Environment directive
systemd enables setting the environment through environment directives.
Just like how [[id:c7edff80-6dea-47fc-8ecd-e43b5ab8fb1e][systemd at user-level]], you can set it at user-level.
Useful for setting specific environment only for that user.
It needs a =*.conf= file in one of the load paths (seen from the =environment.d.5= manual page).
Keep in mind it does not use the shell and instead makes use of shell-like syntax.
The following code block is an example of setting Nix-related environment variables to enable desktop integrations.
#+begin_src
# Enable desktop integration with Nix-installed applications.
NIX_PATH=$HOME/.nix-defexpr/channels${NIX_PATH:+:}$NIX_PATH
PATH=${PATH:+$PATH:}$HOME/.nix-profile/bin
XDG_DATA_DIRS=${XDG_DATA_DIRS:+$XDG_DATA_DIRS:}$HOME/.nix-profile/share/
#+end_src

View File

@ -3,7 +3,7 @@
:END:
#+title: systemd timers
#+date: 2021-07-19 21:45:47 +08:00
#+date_modified: 2021-08-02 11:55:59 +08:00
#+date_modified: 2021-08-07 19:29:15 +08:00
#+language: en
@ -16,6 +16,8 @@ systemd has different ways to denote time.
- Timestamps refer to a specific point in time — e.g., =2021-04-02=, =today=, =now=.
- Calendar events can refer to more than one point of time — e.g., =*-*-4/2=, =Sun,Wed,Fri *-1/2-1/8=.
To find more details about time notation, you can view the =systemd.time.5= manual page.
Here's an example of setting a timer for an example backup service.
The following timer unit sets it to execute every day at 18:00.
@ -36,7 +38,7 @@ WantedBy=graphical.target
If the timer unit is started, this will trigger =borg-backup.service= from the load path.
But you can omit it if you named the timer unit file similarly (e.g., =borg-backup.timer= with =borg-backup.service=).
You can find more information about it from the =systemd.time.5= manual page.
You can find more information about it from the =systemd.timer.5= manual page.
Furthermore, systemd has a testing tool for time with ~systemd-analyze {timespan,timestamp,calendar}~.
#+begin_src shell :eval yes

View File

@ -0,0 +1,57 @@
:PROPERTIES:
:ID: 14b49597-011c-4da1-b955-bed6059af4a3
:END:
#+title: systemd unit templates
#+date: 2021-08-07 19:55:05 +08:00
#+date_modified: 2021-08-07 19:55:26 +08:00
#+language: en
You can create unit templates which is useful for simple services that only requires an argument.
Rather than creating individual simple service files, let systemd handle it.
For example, you may want to spawn a service for Borgmatic with multiple repos.
If you don't know templates, the dumb way to serve multiple repos is to create individual unit files for each.
If you want to schedule them, you also have to create a timer unit for each.
The more efficient solution is to use templates.
To make a unit template, there are only a handful of requirements:
- Addition of =%i= to represent the template value.
- The unit file name has to end with =@= (e.g., =unit-name@.service=, =unit-name@.timer=).
This could be compressed into a template for a service unit.
The following code shows how to create one.
#+begin_src ini
[Unit]
Description=Periodic safety backup for %i
Documentation=man:borg(1) https://www.borgbackup.org/
[Service]
Type=simple
ExecStart=borgmatic --config %i --verbose
[Install]
WantedBy=default.target
#+end_src
To use the service, you have to give it a value — e.g., ~systemctl --user start borg-backup@test.yaml.service~.
That's all good but what about scheduling them?
What if you want to create an archive every hour starting at 08:00?
You can just create a templated timer unit.
#+begin_src ini
[Unit]
Description=Periodic safety backup for %i
Documentation=man:borg(1) https://www.borgbackup.org/
[Timer]
Unit=borg-backup@%i.service
Calendar=08/1:00:00
Persistent=true
[Install]
WantedBy=default.target
#+end_src