aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--store/home/config/nvim/lua/setup/plugins/lint.lua14
-rw-r--r--www/.markdownlintrc4
-rw-r--r--www/content/posts/nspawn.md102
-rw-r--r--www/content/posts/pattern-in-cpp.md25
4 files changed, 83 insertions, 62 deletions
diff --git a/store/home/config/nvim/lua/setup/plugins/lint.lua b/store/home/config/nvim/lua/setup/plugins/lint.lua
index 688e5ca..55ccc2b 100644
--- a/store/home/config/nvim/lua/setup/plugins/lint.lua
+++ b/store/home/config/nvim/lua/setup/plugins/lint.lua
@@ -18,7 +18,19 @@ local cspell = {
fast = true,
}
-local linters = { cspell }
+local markdownlint = {
+ name = "markdownlint",
+ config_patterns = {
+ ".markdownlint.jsonc",
+ ".markdownlint.json",
+ ".markdownlint.yaml",
+ ".markdownlint.yml",
+ ".markdownlintrc",
+ },
+ fast = true,
+}
+
+local linters = { cspell, markdownlint }
local linter_names = vim.tbl_map(function(l) return l.name end, linters)
diff --git a/www/.markdownlintrc b/www/.markdownlintrc
new file mode 100644
index 0000000..22879bc
--- /dev/null
+++ b/www/.markdownlintrc
@@ -0,0 +1,4 @@
+{
+ "default": true
+}
+
diff --git a/www/content/posts/nspawn.md b/www/content/posts/nspawn.md
index 8dc06f3..526e1a6 100644
--- a/www/content/posts/nspawn.md
+++ b/www/content/posts/nspawn.md
@@ -1,7 +1,7 @@
---
title: "Use systemd-nspawn to Create a Development Sandbox"
date: 2025-03-04T23:22:23+08:00
-lastmod: 2025-03-27T01:32:40+08:00
+lastmod: 2025-03-27T17:46:24+08:00
---
*systemd-nspawn* is a great tool for creating development sandboxes. Compared to
@@ -29,62 +29,60 @@ Debian.
## Usage
-I'll demonstrate how to create a *Ubuntu 20.04* VM on Arch Linux as an example.
-You should adjust the commands based on your own situation.
-
*systemd-nspawn* consists of two parts that work together to achieve its VM
functionality:
+
1. The program `systemd-nspawn`, which runs other programs in an isolated
environment with user-specified settings. Each running VM is essentially a
group of processes launched via `systemd-nspawn`.
2. Components for defining and managing VMs, possibly utilizing
`systemd-nspawn`.
-*systemd-nspawn* has similar usage to *systemd service*:
+*systemd-nspawn* has a user interface similar to *systemd service*:
-- `[name].service` => `[name].nspawn`: VM definitions.
+- `[name].service` => `[name].nspawn`: Define VMs.
- Should be placed in `/etc/systemd/nspawn/`, where `machinectl` scans for VM
definitions.
- - `[name]` serves as the VM's name and should be used to specify the VM when
- calling `machinectl`. Note: You'd better use the VM's hostname as its value
- (avoid illegal characters like `.`) to prevent weird issues caused by the
- inconsistency.
+ - `[name]` serves as the VM's name. Use it to specify the VM when calling
+ `machinectl`. Note: You'd better use a valid hostname (avoid illegal
+ characters like `.`) to prevent weird errors.
- The options available roughly mirror `systemd-nspawn`'s CLI arguments, with
some adjustments to better fit VM semantics.
- Isolation-related options are usually prefixed with `Private` (e.g.,
`PrivateUsers=`).
-- `systemctl` => `machinectl`: VM management.
+- `systemctl` => `machinectl`: Manage VMs.
- `enable`/`disable`: Set whether the VM starts automatically at system boot.
- `start`/`poweroff`/`reboot`/`terminate`/`kill`: Control the VM's running
state.
- `login`/`shell`: Do things inside the VM.
+I'll demonstrate how to create a Debian-based VM on Arch Linux as an example.
+You should adjust the commands based on your own situation.
+
### Create Root Filesystem
The root filesystem of a distribution can be created using a special tool from
-its **package manager**. For Debian-based distributions, it's `debootstrap`. If
-your OS uses a different package manager ecosystem, the target distribution's
-one and its keyrings (which might reside somewhere else) need to be installed
-first.
+its package manager. For Debian-based distributions, it's `debootstrap`. If your
+OS uses a different package manager ecosystem, the target distribution's one and
+its keyrings (which might reside somewhere else) have to be installed first.
```bash-session
# pacman -S debootstrap debian-archive-keyring ubuntu-keyring
```
Regular directories work perfectly as root filesystems, but other directory-like
-things should work, too, such as `btrfs` subvolume and snapshot.
+things should work, too, such as `btrfs` subvolume.
```bash-session
-# btrfs subvolume create /var/lib/machines/ubuntu204
+# btrfs subvolume create /var/lib/machines/[name]
```
-Now, run `debootstrap` to create a minimal filesystem. The following command
-should be modified with the target distribution's codename and one of its
-mirrors selected by you.
+Now, run `debootstrap` to create a minimal filesystem. Update the command with
+the target distribution's codename and one of its mirrors you select.
```bash-session
-# debootstrap --include=dbus,libpam-systemd focal \
- /var/lib/machines/ubuntu204 https://mirrors.ustc.edu.cn/ubuntu/
+# debootstrap --include=dbus,libpam-systemd [codename] \
+ /var/lib/machines/[name] [mirror]
```
At this point, the filesystem contains only the distribution's essential
@@ -100,8 +98,8 @@ one based on it or from scratch.
2. Disable network isolation: `[Network] Private=no`
3. Create a user with the same username, group name, UID and GIDs: should be
done inside the VM.
-4. Only bind a subdirectory under *home*: `[Files] Bind=/home/crupest/codes`
-5. Set the hostname: `Hostname=[xxx]`
+4. Only bind a subdirectory under *home*: `[Files] Bind=/home/[user]/[subdir]`
+5. Set the hostname: `[Exec] Hostname=[hostname]`
I disable user isolation because it's implemented using the kernel's user
namespace, which adds many inconveniences due to UID/GID mapping.
@@ -109,14 +107,14 @@ namespace, which adds many inconveniences due to UID/GID mapping.
So, the final `.nspawn` file is like:
```systemd
-/etc/systemd/nspawn/ubuntu204.nspawn
+/etc/systemd/nspawn/[name].nspawn
---
[Exec]
PrivateUsers=no
-Hostname=crupest-arch-ubuntu204
+Hostname=[hostname]
[Files]
-Bind=/home/crupest/codes
+Bind=/home/[user]/[subdir]
[Network]
Private=no
@@ -128,7 +126,7 @@ run commands inside it. `--resolv-conf=bind-host` binds the host's
`/etc/resolv.conf` file to make the network work.
```bash-session
-# systemd-nspawn --resolv-conf=bind-host -D /var/lib/machines/ubuntu204
+# systemd-nspawn --resolv-conf=bind-host -D /var/lib/machines/[name]
```
Now, inside the VM, you can do whatever you like. In my configuration, a correct
@@ -139,23 +137,20 @@ user must be created manually.
build-essential git
# dpkg-reconfigure locales
-# useradd -m -G sudo -s /usr/bin/bash crupest
-# passwd crupest
+# useradd -m -G sudo -s /usr/bin/bash [user]
+# passwd [user]
```
Some setup may need to be done manually, especially those usually handled by the
distribution's installer.
-```plain
-/etc/hostname
----
-crupest-arch-ubuntu204
-```
+1. Update `/etc/hostname` with the VM's real hostname.
+2. Update `/etc/hosts`.
```plain
/etc/hosts
---
-127.0.0.1 localhost crupest-arch-ubuntu204
+127.0.0.1 localhost [hostname]
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
@@ -174,3 +169,38 @@ deb https://mirrors.ustc.edu.cn/ubuntu/ focal-backports main
deb https://mirrors.ustc.edu.cn/ubuntu/ focal-security main
```
+### Use
+
+The following command starts a new shell session for the specified user inside
+the VM, where you can run commands and perform tasks.
+
+```bash-session
+# machinectl shell [user]@[name]
+```
+
+Another way is to use `login` command to enter the *login console*. From there,
+you can log in as a user to start a shell session.
+
+```bash-session
+# machinectl login [name]
+```
+
+To exit a VM session (especially in the *login console*), press `CTRL+]` three
+times quickly in a row.
+
+### Snapshot
+
+The easiest way to backup/snapshot a VM is to create an archive of the VM's
+filesystem. You can use any archive tool you prefer, such as the simple `tar`.
+If the VM's filesystem is a `btrfs` subvolume, native `btrfs` snapshots can be
+used here. Before creating a snapshot, you should power off the VM to avoid
+archiving runtime files.
+
+```bash-session
+# machinectl poweroff [name]
+# btrfs subvolume snapshot /var/lib/machines/[name] \
+ /var/lib/machines/btrfs-snapshots/[name]/[snapshot-name]
+```
+
+`machinectl` also provides an *image* feature similar to Docker, though I've
+never tried it. Feel free to explore it if you're interested!
diff --git a/www/content/posts/pattern-in-cpp.md b/www/content/posts/pattern-in-cpp.md
deleted file mode 100644
index 1709ad4..0000000
--- a/www/content/posts/pattern-in-cpp.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "Pattern in C++"
-date: 2022-01-24T15:57:34+08:00
-categories: coding
-tags:
- - c++
-description: The secret ingredient of secret ingredient soup is ...
----
-
-> The secret ingredient of secret ingredient soup is ...
-> Nothing!
-
-This is a script from Kung Fu Panda, which is one of my favorite film.
-
-People have been struggling for days to find a pattern in which they can code better. Especially those who use Java. They even wrote a book called "Programming Pattern" (or another name since I might forget the name) to show the common patterns.
-
-<!--more-->
-
-I don't mean patterns are bad. However there exists many people who strive to the patterns, stick to the patterns or even get stubborn to patterns. Maybe there exists a way to achieve their goals with some not that patterned code but they don't want to use them at all just because the code is not patterned.
-
-I love C++. And the pattern of C++ is exactly *NO PATTERN*. You write code in the way that they do the task most effectively and neatly. You don't need to apply a pattern to achieve your goal. You just write your code naturally with the way you are most comfortable with.
-
-Tools including programming language serve for people but not vice versa. Don't let tools constrain your hands. And when you find tools not convenient, just fix them or make a new one. Just like C++ is evolving all the time. So are all languages.
-
-The best is code is those that express meanings most clearly and achieve goals most effectively and do nothing with patterns.