diff --git a/feed_rss_created.xml b/feed_rss_created.xml index bc304f8..9a1cc2e 100644 --- a/feed_rss_created.xml +++ b/feed_rss_created.xml @@ -13,8 +13,8 @@ en - Thu, 21 Dec 2023 11:30:41 -0000 - Thu, 21 Dec 2023 11:30:41 -0000 + Thu, 21 Dec 2023 11:36:02 -0000 + Thu, 21 Dec 2023 11:36:02 -0000 1440 diff --git a/feed_rss_updated.xml b/feed_rss_updated.xml index 3ca602e..0bbe7ee 100644 --- a/feed_rss_updated.xml +++ b/feed_rss_updated.xml @@ -13,8 +13,8 @@ en - Thu, 21 Dec 2023 11:30:41 -0000 - Thu, 21 Dec 2023 11:30:41 -0000 + Thu, 21 Dec 2023 11:36:02 -0000 + Thu, 21 Dec 2023 11:36:02 -0000 1440 diff --git a/ha/index.html b/ha/index.html index 3a5a7df..884406f 100644 --- a/ha/index.html +++ b/ha/index.html @@ -27,7 +27,7 @@ - Overview - dreknix - Documentation + Home Assistent - dreknix - Documentation @@ -287,7 +287,7 @@
- Overview + Home Assistent
diff --git a/hardware/index.html b/hardware/index.html index 19aa3a6..ec49c36 100644 --- a/hardware/index.html +++ b/hardware/index.html @@ -27,7 +27,7 @@ - Overview - dreknix - Documentation + Hardware - dreknix - Documentation @@ -287,7 +287,7 @@
- Overview + Hardware
diff --git a/search/search_index.json b/search/search_index.json index c8dbef8..11bbbe2 100644 --- a/search/search_index.json +++ b/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"index.html","title":"Overview","text":"

This Wiki is stored in the GitHub repository dreknix/wiki and can be found on GitHub pages.

"},{"location":"tags.html","title":"Tags","text":"

Following is a list of relevant tags:

"},{"location":"tags.html#homeassistant","title":"HomeAssistant","text":""},{"location":"tags.html#proxmox","title":"Proxmox","text":""},{"location":"tags.html#truenas","title":"TrueNAS","text":""},{"location":"tags.html#ubuntu","title":"Ubuntu","text":""},{"location":"tags.html#windows","title":"Windows","text":""},{"location":"tags.html#yaml","title":"YAML","text":""},{"location":"tags.html#bash","title":"bash","text":""},{"location":"tags.html#tmux","title":"tmux","text":""},{"location":"blog/index.html","title":"Blog","text":"

The RSS feed of the blog is created by the MkDocs RSS plugin.

"},{"location":"blog/index.html#articles","title":"Articles","text":""},{"location":"blog/2023/11/21/enable-gx-in-nvchad.html","title":"Enable gx in NvChad","text":"

The command gx opens the filename under the the cursor with vim.ui.open() (see :help netrw-gx). Then handling is provided by the internal netrw plugin. This plugin is disabled when using NvChad.

NvChad is using nvim-tree/nvim-tree.lua. In the configuration of this plugin, NvChad disables netrw, but allows the usage of netrw by the hijacking setup option (see lua/plugins/configs/nvimtree.lua).

This options will allow the usage of gx. But NvChad also disables the plugin in the configuration of the plugin manager folke/lazy.nvim. The netrw plugin is disabled with the option performance.rtp.disabled_plugins in the file plugins/configs/lazy_nvim.lua.

To enable the gx command the entry netrwPlugin must be removed from this option. But the configuration mechanism in NvChad allows only to overwrite an option. Therefore the most straightforward way is to overwrite the option with the complete list without netrwPlugin in custom/chadrc.lua:

chadrc.lua
local M = {}\nM.lazy_vim = {\n  performance = {\n    rtp = {\n      disabled_plugins = {\n        \"2html_plugin\",\n        ...\n        \"ftplugin\",\n      }\n    }\n  }\n}\nreturn M\n

The drawback of this method is, that whenever the NvChad configuration is changed, this list must be updated.

The better solution is to load the list and remove the favored plugins:

chadrc.lua
local M = {}\n-- load default list of disabled plugins in NvChad\nlocal default = require('plugins.configs.lazy_nvim')\nlocal default_disabled_plugins = default.performance.rtp.disabled_plugins\n\n-- specify which plugins should be removed from default disabled list\nlocal enabled = {\n  netrwPlugin = true,\n}\n-- enable those plugins\nlocal i=1\nwhile i <= #default_disabled_plugins do\n    if enabled[default_disabled_plugins[i]] then\n        table.remove(default_disabled_plugins, i)\n    else\n        i = i + 1\n    end\nend\n\nM.lazy_nvim = {\n  performance = {\n    rtp = {\n      disabled_plugins = default_disabled_plugins,\n    },\n  },\n}\nreturn M\n

Info

When you only want to use the gx command, there are other solutions like using a separate plugin, e.g., chrishrb/gx.nvim. This is also an example, how to overwrite configuration settings by removing an option in NvChad.

Tip

A table can be printed with the following commands:

print(vim.inspect(require('plugins.configs.lazy_nvim')))\nprint(vim.inspect(default_disabled_plugins))\n
"},{"location":"blog/2023/11/20/finding-glyph-in-fonts.html","title":"Finding Glyph in Fonts","text":"

Sometimes it is necessary to find fonts that contain a specific glyph. The tool albatross can be used for that task.

Finding a font by providing the glyph Snowman Emoji:

albatross \u2603\n

Finding a font by providing the code of the glyph in multiset union notation:

albatross U+2603\n

A detailed description of all options can be found in the CTAN package documentation or albatross(1).

Possible Unicode characters and their code point can be searched on symbl.cc.

Info

On Debian or Ubuntu the tool is part of the package texlive-font-utils. The command is not available. Instead the following command can be used:

java -jar /usr/share/texlive/texmf-dist/scripts/albatross/albatross.jar 0x2603\n
"},{"location":"blog/2023/11/20/imap-based-authentication-in-php.html","title":"IMAP-based Authentication in PHP","text":"

When using IMAP-based user authentication in applications written in PHP (i.e. Nextcloud, DokuWiki, etc.), debugging with a test script is essential. The idea of using curl for authentication, is based on the external user authentication plugin (see: nextcloud/user_external) of Nextcloud.

imap-test.php
#!/usr/bin/env php\n<?php\n$version = phpversion();\nprint(\"Current PHP version: {$version}\\n\");\n\n$url = 'imaps://imap.example.org:993';\n$email = 'user@example.org';\n$password = 'password'; # password must be in '...'\n\n$ch = curl_init();\n\n# see: https://www.php.net/manual/en/function.curl-setopt.php\ncurl_setopt($ch, CURLOPT_URL, $url);\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_USERPWD, \"{$email}:{$password}\");\ncurl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);\n\n# equal to: curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'CAPABILITY');\ncurl_setopt($ch, CURLOPT_CONNECT_ONLY, true);\n\n# get more debug information\ncurl_setopt($ch, CURLOPT_CERTINFO, true);\ncurl_setopt($ch, CURLOPT_VERBOSE, true);\n\nprint(\"Connecting to: {$url}\\n\");\ncurl_exec($ch);\n\n$errorcode = curl_errno($ch);\n\nif ($errorcode === 0) {\n  print(\"OK\\n\");\n} else if ($errorcode === 67) {\n  print(\"ERROR(\" . $errorcode . \"): Login denied! Wrong credentials?\\n\");\n} else {\n  print(\"ERROR(\" . $errorcode . \"): \" . curl_error($ch) . \"\\n\");\n}\n?>\n

Tip

It is important to use the same PHP version for testing, as used for the application. To ensure the correct version Docker/Podman can be used.

docker run -it --rm \\\n           --name php-test \\\n           -v \"./imap-test.php:/work/imap-test.php\" \\\n           -w /work php:8.2-cli \\\n           php imap-test.php\n
"},{"location":"blog/2023/12/04/qemu-and-windows-keys.html","title":"QEMU and Windows Keys","text":"

OEM Windows keys are often stored in the software licensing (SLIC) or Microsoft data management (MSDM) table. When a key is stored the unattended installation can use a generic key and the stored key is than used and activated. The usage of such a key can be tested with QEMU/libvirt.

The SLIC or MSDM table can be read via the Advanced Configuration and Power Interface (ACPI) in Linux. To read the Windows license key the following command can be used:

egrep -ao '[[:alnum:]-]{29}' /sys/firmware/acpi/tables/MSDM\n

Under Windows the following PowerShell snippet can be used to extract the license key:

Get-CimInstance -query 'select * from SoftwareLicensingService'\n

The key is stored in the OA3xOriginalProductKey attribute.

The table file needs to be stored in /usr/share/seabios/ due to AppArmor. If the file is not stored in this directory, a permission denied error is thrown. The MSDM (or SLIC) table is included by using additional QEMU parameters:

<qemu:commandline>\n  <qemu:arg value='-acpitable'/>\n  <qemu:arg value='file=/usr/share/seabios/MSDM'/>\n</qemu:commandline>\n

In order to \"simulate\" the OEM hardware the system management BIOS (SMBIOS) can be used:

<qemu:commandline>\n<qemu:arg value='-smbios'/>\n<qemu:arg value='type=0,version=??,date=??'/>\n<qemu:arg value='-smbios'/>\n<qemu:arg value='type=1,manufacturer=??,product=??,version=??,serial=??,uuid=??,sku=??,family=??'/>\n

The concrete values can be extracted with the dmidecode tool:

dmidecode -t 0\ndmidecode -t 1\n

The embedded license key can be activated with the following commands. First the key is read from the SLIC or MSDM table and than stored in Windows. The last command activates the license key:

$key = (Get-CimInstance -query 'select * from SoftwareLicensingService').OA3xOriginalProductKey\ncscript.exe \"$env:SystemRoot\\System32\\slmgr.vbs\" /ipk \"$key\"\ncscript.exe \"$env:SystemRoot\\System32\\slmgr.vbs\" /ato\n
"},{"location":"blog/2023/11/22/using-spice-with-truenas-scale-cobia-2310.html","title":"Using SPICE with TrueNAS Scale Cobia (23.10)","text":"

TrueNAS Scale Cobia (23.10) disabled the option to access VM displays via VNC. The connection method is changed to SPICE.

There are many different clients, which support Spice. Under Debian the tool Remmina is available that is a GTK-based remote desktop client. This tool supports many different protocols: RDP, VNC, SPICE, X2Go, SSH, etc. Some of the protocols, i.e. SPICE, are only available via additional plugins.

To install Remina with the SPICE plugin (the RDP and VNC plugins are installed by default):

sudo apt install remmina remmina-plugin-spice\n

When Remina is installed, you can connect to the server via the SPICE protocol:

remmina spice://server.example.org\n

If multiple VMs are running the different ports can be found in the details of the display device.

Tip

If a VM was created before version 23.10 the display of the VM must be deleted and newly created. Since version 23.10 only the SPICE protocol is available and password, which protects the connection, must be set.

Sometimes the VM must use UEFI in order to work properly with the SPICE protocol.

"},{"location":"blog/2023/11/20/using-tex-files-in-vi.html","title":"Using TeX files in Vi","text":"

In Vim/Neovim the filetype plugin uses three different type for different TeX flavors (see :help ft-tex-plugin).

Which filetype the current buffer was assigned, can be shown with :set filetype? (or :LspInfo if LSP is enabled).

All files with the extension *.tex are of type plaintex. When the file type plugin finds specific keywords the file type is than changed to tex or context.

The automatic guessing can be disabled with the following two mechanisms.

Add the TeX flavor in the first line of a *.tex file:

%&latex\n

Or set the global variable tex_flavor:

VimNeovim
let g:tex_flavour = \"latex\"\n
vim.g.tex_flavor = 'latex'\n

See :help lua-guide-variables for more information about the Lua wrappers for different variable scopes.

"},{"location":"blog/2023/12/11/zram-and-swap.html","title":"zram and Swap","text":"

The zram kernel module creates compressed RAM-based block devices named /dev/zramX. These zram devices allow fast I/O and the compression provides RAM space savings.

"},{"location":"blog/2023/12/11/zram-and-swap.html#install-zram","title":"Install zram","text":"

Install zram in Debian:

sudo apt install zram-tools\n

In order to enable zram, the computer needs to be rebooted.

"},{"location":"blog/2023/12/11/zram-and-swap.html#configure-zram","title":"Configure zram","text":"

The status of the zram module can be queried with systemctl status zramswap.service. The configuration and usage can be shown with zramctl:

$ zramctl\nNAME       ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT\n/dev/zram0 lz4           256M   4K   63B   20K       8 [SWAP]\n

Change the configuration parameters by editing the file /etc/default/zramswap:

ALGO=zstd\nPERCENT=25\n

The will change the default compression algorithm from lz4 to zstd and the default size from 256 MiB to 25 % of the total RAM.

$ zramctl\nNAME       ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT\n/dev/zram0 zstd          7.8G   4K   59B   20K       8 [SWAP]\n

If the computer has a configured swap file or swap partition, the zram swap gets a higher priority (100) instead of the default of -2:

$ swapon\nNAME       TYPE      SIZE USED PRIO\n/dev/dm-2  partition   4G   0B   -2\n/dev/zram0 partition 7.8G   0B  100\n

When the computer uses suspend to disk, a swap file or swap partition is needed besides zram.

"},{"location":"ha/index.html","title":"Home Assistent","text":"","tags":["HomeAssistant"]},{"location":"ha/index.html#first-steps","title":"First Steps","text":"

TODO: see video

","tags":["HomeAssistant"]},{"location":"ha/devices.html","title":"Devices","text":"","tags":["HomeAssistant"]},{"location":"ha/devices.html#shelly-plug-s","title":"Shelly Plug S","text":"

Shelly Plug S can be used with the Tasmota firmware.

Connect to Wifi SSID of Shelly Plug S and connect to web interface http://192.168.33.1/ and configure local wifi network.

Install the firmware:

http://shellyip/ota?url=http://ota.tasmota.com/tasmota/shelly/mg2tasmota-ShellyPlugS.zip\n

Connect to Tasmota Wifi SSID and configure the plug. After that open the URL http://shellyip/.

Configure template (Configure > Configure Other):

{\"NAME\":\"Shelly Plug S\",\"GPIO\":[57,255,56,255,0,134,0,0,131,17,132,21,0],\"FLAG\":2,\"BASE\":45}\n

Configure device (Configure > Configure Module):

BlitzWolf SHP (45)\n

Configure MQTT (Configure > Configure MQTT:

Calibrate the device (with readings of 235V and 35W):

savedata 1\nVoltageSet 235\nPowerSet 35.0\nsavedata 0\n

The information can be found in this video.

","tags":["HomeAssistant"]},{"location":"ha/videos.html","title":"Videos","text":"","tags":["HomeAssistant"]},{"location":"ha/videos.html#first-steps","title":"First Steps","text":"","tags":["HomeAssistant"]},{"location":"ha/videos.html#templates","title":"Templates","text":"","tags":["HomeAssistant"]},{"location":"hardware/index.html","title":"Hardware","text":""},{"location":"hardware/framework.html","title":"Framework 13 AMD","text":"

Framework 13 AMD

"},{"location":"hardware/framework.html#debian-13-trixie-testing","title":"Debian 13 trixie (testing)","text":"

Basic installation from network installer (netisnt) ISO image with disk encryption and btrfs flat volume layout.

After the first reboot tweak the fresh installation.

"},{"location":"hardware/framework.html#install-missing-firmware","title":"Install Missing Firmware","text":""},{"location":"hardware/framework.html#mediatek-mt7922","title":"MEDIATEK MT7922","text":"

Install mt7921e for MEDIATEK MT7922 802.11ax Wireless Network Adapter:

sudo apt install firmware-misc-nonfree\n
"},{"location":"hardware/framework.html#amd-radeon-780m","title":"AMD Radeon 780M","text":"

The package firmware-amd-graphics must not be installed:

sudo apt purge firmware-amd-graphics\n

Downloading specific firmware is described in the Debian Wiki.

` console mkdir firmware cd firmware/ wget -r \\ -nd \\ -e robots=no \\ -A '*.bin' \\ --accept-regex '/plain/' \\ https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/amdgpu/ sudo mkdir /lib/firmware/amdgpu/ sudo mv *.bin /lib/firmware/amdgpu/ sudo update-initramfs -c -k all

"},{"location":"hardware/lenovo.html","title":"Lenovo ThinkPad","text":""},{"location":"hardware/lenovo.html#firmware-update","title":"Firmware Update","text":"

Download boot ISO image from Lenovo support.

Extract image from ISO:

$ geteltorito -o e480.img ~/Downloads/r0puj37wd.iso\n

Get the device of the USB stick with lsblk. And write the image to the USB stick.

$ sudo dd if=e480.img of=/dev/sdb bs=64K\n
"},{"location":"hardware/nuc11atkc4.html","title":"NUC 11 Essential Kit","text":""},{"location":"hardware/nuc11atkc4.html#boot","title":"Boot","text":""},{"location":"hardware/nuc11atkc4.html#debian-11-bullseye","title":"Debian 11 - bullseye","text":""},{"location":"hardware/nuc11atkc4.html#firmware","title":"Firmware","text":"

The following package must be installed:

$ sudo apt install firmware-linux-nonfree firmware-realtek firmware-iwlwifi\n
"},{"location":"hardware/nuc11atkc4.html#luks-dropbear","title":"LUKS - Dropbear","text":"
$ sudo apt install dropbear-initramfs\n

Create /etc/dropbear-initramfs/authorized_keys and update the initramfs.

$ sudo update-initramfs -u\n

Unlock the LUKS encryption: cryptroot-unlook

"},{"location":"hardware/nuc11atkc4.html#dmidecode","title":"dmidecode","text":"
$ sudo dmidecode -s system-product-name\nNUC11ATKC4\n$ sudo dmidecode -s system-serial-number\nXXXXXXXXXXXX\n$ sudo dmidecode -s bios-version\nATJSLCPX.0037.2022.0715.1547\n
"},{"location":"tools/container/debugging.html","title":"Debugging Slim Containers","text":"

In order to debug a slim or distroless container the Nixery can be used.

Start a simple slim container:

$ docker run --rm -p 8080:80 --name slim-container traefik/whoami\n

Attach a debug container based on Nixery (with the packages ps, tree, and vim) to the slim container namespaces pid and network.

$ docker run \\\n           -it --rm \\\n           --name debugger \\\n           --pid container:slim-container \\\n           --network container:slim-container \\\n           nixery.dev/shell/ps/tree/vim \\\n           bash\n

Now the processes of the slim container are visible.

# ps -e\nUID          PID    PPID  C STIME TTY          TIME CMD\n0              1       0  0 18:28 ?        00:00:00 /whoami\n0             18       0  0 18:29 pts/0    00:00:00 bash\n0             24      18  0 18:30 pts/0    00:00:00 ps -ef\n#\n

The filesystem of the slim container is visible under /proc/1/root.

# ls /proc/1/root\ndev  etc  proc  sys  usr  whoami\n#\n

To work directly on the filesystem of the slim container you need to chroot into /proc/1/root. In order to use the tools from the Nixery image the directories /bin and /nix must be accessible from the filesystem of the slim container. This can only be achieved via the /proc filesystem.

# ln -s /proc/$$/root/bin /proc/1/root/nix-bin\n# ln -s /proc/$$/root/nix /proc/1/root/nix\n# export PATH=${PATH}:/nix-bin\n# chroot /proc/1/root /nix-bin/bash\n

Now you can debug a running slim container from within and use every tool you like.

Note

iximiuz/cdbug

A tool for container debugging. Based on the ideas descripted in the blog post \"Docker: How To Debug Distroless And Slim Containers\" from Ivan Velichko

Note

At DockerCon 2023 docker debug was announced.

"},{"location":"tools/container/baseimages/nixery.html","title":"Nixery","text":"

Nixery is acontainer image registry that provides small base images with only the packages specified in the URL, separated by slashes.

When the first element is shell than the bash and coreutils are part of the image. After that packages from the Nix package manager can be added. Any package available at https://search.nixos.org/packages can be installed.

The following command starts a shell in a container based on a Nixery image that contains the coreutils with bash and the packages git and python312.

$ docker run -it --rm nixery.dev/shell/git/python312 bash\n

Nixery can be used to debug slim containers.

"},{"location":"tools/vi/index.html","title":"Vi / Vim / Neovim","text":""},{"location":"tools/vi/index.html#general-informations","title":"General Informations","text":"

There are several starting point for informations:

"},{"location":"tools/vi/index.html#motions","title":"Motions","text":"

See: :help motion

"},{"location":"tools/vi/index.html#left-right-motions","title":"Left-Right Motions","text":"

See: :help left-right-motions

"},{"location":"tools/vi/index.html#up-down-motions","title":"Up-Down Motions","text":"

See: :help up-down-motions

"},{"location":"tools/vi/index.html#word-motions","title":"Word Motions","text":"

See: :help word-motions

"},{"location":"tools/vi/index.html#text-object-motions","title":"Text Object Motions","text":"

See: :help object-motions

"},{"location":"tools/vi/index.html#text-object-selection","title":"Text Object Selection","text":"

See: :help text-objects

"},{"location":"tools/vi/index.html#quickfix","title":"Quickfix","text":"

See: :help quickfix

The quickfix commands are used to work with a list of positions in files. A location list is a window-local quickfix list.

:vim word ** or :vim /pattern/ ** searches the word or pattern in all files recursively beneath the current directory. And opens the first location. After that the following commands are working on this quickfix list.

"},{"location":"tools/vi/index.html#commands-starting-with-g","title":"Commands starting with g","text":"

See: :help *g*

Jump through or work with changes:

"},{"location":"tools/vi/index.html#misc","title":"Misc","text":""},{"location":"tools/vi/index.html#search-in-key-mappings","title":"Search in Key Mappings","text":"

Besides the plugin Telescope the command :filter allows to search through all available key mappings.

Search for key mappings in insert mode:

:filter pattern imap\n

Search for key mappings in normal mode:

:filter pattern imap\n

To print the content of a mapping:

:verbose map <Leader>x\n
"},{"location":"tools/vi/index.html#clear-search-highlight","title":"Clear Search Highlight","text":"

With the option :hlsearch all matches of the last search are highlighted. To clear all highlights the command :nohlsearch can be used. Often this command is mapped to C-L. In NeoVim the following default mapping exists:

nnoremap <C-L> <Cmd>nohlsearch<Bar>diffupdate<Bar>normal! <C-L><CR>\n
"},{"location":"tools/vi/index.html#indenting-code","title":"Indenting Code","text":"

With == or = code can be formatted.

"},{"location":"tools/vi/index.html#avoid-wrong-formatting-during-paste","title":"Avoid Wrong Formatting During Paste","text":"

Set the configuration :set paste before pasting into Vi. Disable this option afterwards with :set nopaste.

"},{"location":"tools/vi/index.html#remove-lines-matching-a-pattern","title":"Remove Lines Matching a Pattern","text":""},{"location":"tools/vi/index.html#non-greedy-regular-expression","title":"Non-Greedy Regular Expression","text":"

See: :help non-greedy

{\n  \"key1\": \"valueA\",\n  \"key2\": \"valueB\"\n}\n

The regular expression \".*\" will select \"key1\": \"valueA\" because it is greedy. It tries to match as many as possible characters.

The regular expression \".\\{-\\}\" will select only \"key1\". It will match the fewest number of characters as possible. The last \\ is optional, so the expression \".\\{-}\" is also possible.

"},{"location":"tools/vi/vim.html","title":"Vim","text":"

mhinz/vim-galore

"},{"location":"tools/vi/vim.html#general","title":"General","text":"
\" enter current millenium\nset nocompatible\n\n\" enable syntax and plugins (for netrw)\nsyntax enable\nfiletype plugin on\n
"},{"location":"tools/vi/vim.html#finding-files","title":"Finding Files","text":"
\" search down into subfolders\n\" provides tab-completion for all file-related tasks\nset path+=**\n\n\" ignore different file types\nset wildignore+=*.aux,*.log,*.out,*.pdf,*.o\n\n\" ignore a specific folder\nset wildignore+=**/node_modules/**\n\n\" give suffixes a low priority (list at end)\nset suffixes+=.pdf\n\n\" display all matching files when we tab complete\nset wildmenu\n\n\" Hit tab to :find by partial match\n\" Use * to make it fuzzy\n\n\" :b lets you autocomplete any open buffer\n
"},{"location":"tools/vi/vim.html#autocomplete","title":"Autocomplete","text":"

More shortcuts can be found in |ins-completion|

\" ^x^n - for just this file\n\" ^x^f - for filenames\n\" ^x^] - for tags only\n\" ^n   - for anything by the 'complete' option\n\n\" move than with ^n and ^p in the suggestion list\n
"},{"location":"tools/vi/vim.html#spell-checking-and-word-completion","title":"Spell Checking and Word Completion","text":"
\" Spell-check language\nset spelllang=en_us\n\n\" Automatically set by plugin vim-markdown\n\"\" Define new filetype markdown\n\"autocmd BufRead,BufNewFile *.md set filetype=markdown\n\n\" Spell-check Markdown files\nautocmd FileType markdown setlocal spell\n\n\" Spell-check Git messages\nautocmd FileType gitcommit setlocal spell\n\n\" Set spellfile to location that is guaranteed to exist,\n\" can be symlinked to Dropbox or kept in Git\n\" and managed outside of thoughtbot/dotfiles using rcm.\nset spellfile=$HOME/.vim/spell-en.utf-8.add\n\n\" Autocomplete with dictionary words when spell check is on\nset complete+=kspell\n
"},{"location":"tools/vi/vim.html#file-browsing","title":"File Browsing","text":"
\" tweaks for browsing\nlet g:netrw_banner=0        \" disable annoying banner\nlet g:netrw_browse_split=4  \" open in prior window\nlet g:netrw_altv=1          \" open splits to the right\nlet g:netrw_liststyle=3     \" tree view\nlet g:netrw_list_hide=netrw_gitignore#Hide()\nlet g:netrw_list_hide.=',\\(^\\|\\s\\s\\)\\zs\\.\\S\\+'\n\n\" :edit a folder to open a file browser\n\" <CR>/v/t to open in an h-split/v-split/tab\n\" check |netrw-browse-maps| for more mappings\n
"},{"location":"tools/vi/vim.html#snippets","title":"Snippets","text":"
\" read an empty HTML template and move cursor to title\nnnoremap ,html :-1read $HOME/.vim/.skeleton.html<CR>3jwf>a\n
"},{"location":"tools/vi/vim.html#help","title":"Help","text":"
:help ^n    \" help about ctrl-n in normal mode\n:help i_^n  \" help about ctrl-n in insert mode\n:help c_^n  \" help about ctrl-n in command mode\n\n\" grep in help pages\n:helpgrep xxx\n
"},{"location":"tools/vi/vim.html#colorcolumn","title":"ColorColumn","text":"
set textwidth=80\nset colorcolumn=81\nhighlight ColorColumn ctermbg=0 guibg=lightgrey\n\n\" alternativ\nau BufWinEnter * let w:m2=matchadd('ErrorMsg', '\\%>80v.\\+', -1)\n
"},{"location":"tools/vi/neovim/index.html","title":"Neovim / NvChad","text":"

Neovim is a fork of Vim with builtin support for Language Server Protocol (LSP) and Lua scripting.

For Neovim different advanced configurations exists: LazyVim, LunarVim, AstroNvim, NvChad, ... In the following NvChad is used as the bases for the custom configuration.

"},{"location":"tools/vi/neovim/index.html#installupdate","title":"Install/Update","text":"

Install (Linux):

$ rm -rf ~/.config/nvim\n$ rm -rf ~/.local/share/nvim\n$ git clone https://github.com/NvChad/NvChad ~/.config/nvim --depth 1\n

Install (Windows):

PS> rd -r ~\\AppData\\Local\\nvim\nPS> rd -r ~\\AppData\\Local\\nvim-data\nPS> git clone https://github.com/NvChad/NvChad $HOME\\AppData\\Local\\nvim --depth 1\n

Update:

:NvChadUpdate\n
"},{"location":"tools/vi/neovim/index.html#key-mappings-and-commands","title":"Key Mappings and Commands","text":"

Note

In NvChad the leader key is Space.

"},{"location":"tools/vi/neovim/index.html#custom-config","title":"Custom Config","text":"

dreknix/tools-nvchad-config

~/.config/nvim/lua/custom/\n\u251c\u2500\u2500 init.lua\n\u251c\u2500\u2500 chadrc.lua\n\u251c\u2500\u2500 mappings.lua\n\u251c\u2500\u2500 plugins.lua\n\u251c\u2500\u2500 configs/\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 lspconfig.lua\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 overrides.lua\n\u251c\u2500\u2500 after/\n\u2514\u2500\u2500 snippets/\n
"},{"location":"tools/vi/neovim/index.html#config-files","title":"Config Files","text":"

Custom configuration files:

"},{"location":"tools/vi/neovim/index.html#after-directory","title":"After Directory","text":"

Specific settings for each file type can be found in after/ftplugin/<filetype>.lua.

"},{"location":"tools/vi/neovim/index.html#snippets","title":"Snippets","text":"

NvChad uses the following plugins for snippets:

The predefined snippets are installed in ~/.local/share/nvim/lazy/friendly-snippets/snippets/. Custom snippets are loaded in init.lua.

"},{"location":"tools/vi/neovim/chadrc_lua.html","title":"chardrc.lua","text":"

Content of ~/.config/nvim/lua/custom/chadrc.lua:

---@type ChadrcConfig\n local M = {}\n M.ui = {theme = 'catppuccin'}\n M.plugins = 'custom.plugins'\n M.mappings = require 'custom.mappings'\n return M\n
"},{"location":"tools/vi/neovim/configs_lspconfig_lua.html","title":"configs/lspconfig.lua","text":"

Configuration of the LSP servers can be found here.

The LSP configuration for the current buffer can be shown with :LspInfo. Often the file type (:set ft) must be set to the correct value. See vim.filetype.add in init.lua.

Content of ~/.config/nvim/lua/custom/configs/lspconfig.lua:

local base = require('plugins.configs.lspconfig')\n\nlocal on_attach = base.on_attach\nlocal capabilities = base.capabilities\n\nlocal lspconfig = require('lspconfig')\n\nlspconfig.clangd.setup({\n  on_attach = function (client, bufnr)\n    client.server_capabilities.signatureHelpProvider = false\n    on_attach(client, bufnr)\n  end,\n  capabilities = capabilities,\n})\n\nlspconfig.ansiblels.setup({\n  on_attach = on_attach,\n  capabilities = capabilities,\n})\n\nlspconfig.docker_compose_language_service.setup({\n  on_attach = on_attach,\n  capabilities = capabilities,\n  filetypes = {'yaml.docker-compose'},\n})\n\nlspconfig.dockerls.setup({\n  on_attach = on_attach,\n  capabilities = capabilities,\n})\n\nlspconfig.jsonls.setup({\n  on_attach = on_attach,\n  capabilities = capabilities,\n})\n\nlspconfig.marksman.setup({\n  on_attach = on_attach,\n  capabilities = capabilities,\n})\n\nlspconfig.yamlls.setup({\n  on_attach = on_attach,\n  capabilities = capabilities,\n  filetypes = {'yaml', 'yaml.ansible', 'yaml.docker-compose'},\n})\n\nlspconfig.pyright.setup({\n  on_attach = on_attach,\n  capabilities = capabilities,\n  filetypes = {'python'},\n})\n
"},{"location":"tools/vi/neovim/configs_overrides_lua.html","title":"configs/overrides.lua","text":"

Content of ~/.config/nvim/lua/custom/configs/overrides.lua:

--\n-- configure: williamboman/mason.nvim\n--\n\nM.mason = {\n  ensure_installed = {\n    -- lua stuff\n    'lua-language-server',\n    'stylua',\n\n    -- web dev stuff\n    'css-lsp',\n    'html-lsp',\n    'prettier',\n\n    -- c/cpp stuff\n    'clangd',\n    'clang-format',\n\n    -- shell stuff\n    'ansible-language-server',\n    'bash-language-server',\n    'docker-compose-language-service',\n    'dockerfile-language-server',\n    'jsonlint',\n    'marksman',\n    'yaml-language-server',\n\n    -- python stuff\n    'pyright',\n    'flake8',\n    'black',\n    'pylint',\n    'mypy',\n    'ruff',\n    'debugpy',\n  },\n}\n
--\n-- configure: nvim-treesitter/nvim-treesitter\n--\nM.treesitter = {\n  ensure_installed = {\n    'bash',\n    'c',\n    'cpp',\n    'css',\n    'git_config',\n    'git_rebase',\n    'gitcommit',\n    'gitignore',\n    'go',\n    'html',\n    'ini',\n    'java',\n    'javascript',\n    'jq',\n    'json',\n    'latex',\n    'lua',\n    'make',\n    'markdown',\n    'markdown_inline',\n    'mermaid',\n    'perl',\n    'php',\n    'python',\n    'sql',\n    'xml',\n    'yaml',\n  },\n  indent = {\n    enable = true,\n    -- disable = {\n    --   'python'\n    -- },\n  },\n}\n
--\n-- configure: nvim-tree/nvim-tree.lua\n--\n\nM.nvimtree = {\n  git = {\n    enable = true,\n  },\n\n  renderer = {\n    highlight_git = true,\n    icons = {\n      show = {\n        git = true,\n      },\n    },\n  },\n}\n
"},{"location":"tools/vi/neovim/configs_overrides_lua.html#_1","title":"configs/overrides.lua","text":""},{"location":"tools/vi/neovim/configs_overrides_lua.html#lukas-reinekeindent-blanklinenvim","title":"lukas-reineke/indent-blankline.nvim","text":"

Define other symbols for visualizing different whitespaces in list mode. The list mode is disabled by default. F2 is used to toogle list view (see mappings.lua). With the plugin variable show_end_of_line the character set defined by listchars is used.

vim.opt.list = false\nvim.opt.listchars:append({ tab   = '\u2192 ' })  -- u2192\nvim.opt.listchars:append({ eol   = '\u21b2'  })  -- u21b2\nvim.opt.listchars:append({ space = '\u00b7'  })  -- u00b7\nvim.opt.listchars:append({ nbsp  = '\u2423'  })  -- u2423\nvim.opt.listchars:append({ trail = '\u2610'  })  -- u2610\n\nM.blankline = {\n  show_end_of_line = true,\n}\n
"},{"location":"tools/vi/neovim/init_lua.html","title":"init.lua","text":"

General initialization of Neovim that is not handled by a plugin or NvChad.

"},{"location":"tools/vi/neovim/init_lua.html#general-settings","title":"General settings","text":"

Highlight the columns textwidth+0 and textwidth+20. The default value of textwidth is 80.

vim.opt.colorcolumn = '+0,+20'\n

TODO move to overrides or configs

-- LuaSnip uses rafamadriz/friendly-snippets\n-- extend in snipmate format\nvim.g.snipmate_snippets_path = vim.fn.stdpath \"config\" .. \"/lua/custom/snippets\"\n
"},{"location":"tools/vi/neovim/init_lua.html#file-types","title":"File Types","text":"

Add file types to specific file name patterns ( see vim.filetype). The file type yaml.docker-compose and yaml.ansible is used for choosing a more specific LSP server.

vim.filetype.add({\n  pattern = {\n    -- SSH config\n    ['.*/.ssh/config.d/.*'] = 'sshconfig',\n    -- rofi config\n    ['.*/.*.rasi'] = 'css',\n    -- Docker compose\n    ['compose.ya?ml'] = 'yaml.docker-compose',\n    ['docker-compose.ya?ml'] = 'yaml.docker-compose',\n    -- Ansible\n    ['.*/playbooks/.*.ya?ml'] = 'yaml.ansible',\n    ['.*/playbooks/.*/.*.ya?ml'] = 'yaml.ansible',\n    ['.*/roles/.*/tasks/.*.ya?ml'] = 'yaml.ansible',\n    ['.*/roles/.*/handlers/.*.ya?ml'] = 'yaml.ansible',\n  },\n})\n
"},{"location":"tools/vi/neovim/init_lua.html#securing-gopass","title":"Securing gopass","text":"

The tool gopass might use Neovim for editing secrets. Therefore, backup files or other external information storage must be disabled.

vim.api.nvim_create_autocmd({\"BufNewFile\", \"BufRead\"}, {\n  pattern = {'/dev/shm/gopass*'},\n  callback = function(ev)\n    vim.opt_local.swapfile = false\n    vim.opt_local.backup = false\n    vim.opt_local.undofile = false\n    vim.opt_local.shadafile = \"NONE\"\n  end\n})\n
"},{"location":"tools/vi/neovim/mappings_lua.html","title":"mappings.lua","text":"

Content of ~/.config/nvim/lua/custom/mappings.lua:

local M = {}\n\nM.general = {\n  n = {\n    -- switch between windows\n    [\"<A-Left>\"] = { \"<cmd> TmuxNavigateLeft<CR>\", \"Window left\" },\n    [\"<A-Right>\"] = { \"<cmd> TmuxNavigateRight<CR>\", \"Window right\" },\n    [\"<A-Down>\"] = { \"<cmd> TmuxNavigateDown<CR>\", \"Window down\" },\n    [\"<A-Up>\"] = { \"<cmd> TmuxNavigateUp<CR>\", \"Window up\" },\n  }\n}\n\nreturn M\n
"},{"location":"tools/vi/neovim/plugins_lua.html","title":"plugins.md","text":"

Overrides already loaded NvChad plugins:

Add LSP servers in configs/lspconfig.lua.

Add additional plugins:

Content of ~/.config/nvim/lua/custom/plugins.lua:

local overrides = require 'custom.configs.overrides'\n\nlocal plugins = {\n  {\n    'williamboman/mason.nvim',\n    opts = overrides.mason,\n  },\n  {\n    'nvim-treesitter/nvim-treesitter',\n    opts = overrides.treesitter,\n  },\n  {\n    'nvim-tree/nvim-tree.lua',\n    opts = overrides.nvimtree,\n  },\n  {\n    'lukas-reineke/indent-blankline.nvim',\n    opts = overrides.blankline,\n  },\n  {\n    'neovim/nvim-lspconfig',\n    config = function()\n      require 'plugins.configs.lspconfig'\n      require 'custom.configs.lspconfig'\n    end\n  },\n  {\n    'mfussenegger/nvim-lint',\n    event = 'VeryLazy',\n    config = function()\n      require 'custom.configs.lint'\n    end\n  },\n  {\n    'mhartington/formatter.nvim',\n    event = 'VeryLazy',\n    opts = function()\n      return require 'custom.configs.formatter'\n    end\n  },\n  {\n    'mfussenegger/nvim-dap',\n    config = function(_, opts)\n      require('core.utils').load_mappings('dap')\n    end\n  },\n  {\n    'rcarriga/nvim-dap-ui',\n    dependencies = 'mfussenegger/nvim-dap',\n    config = function()\n      local dap = require('dap')\n      local dapui = require('dapui')\n      dapui.setup()\n      dap.listeners.after.event_initialized['dapui_config'] = function()\n        dapui.open()\n      end\n      dap.listeners.before.event_terminated['dapui_config'] = function()\n        dapui.close()\n      end\n      dap.listeners.before.event_exited['dapui_config'] = function()\n        dapui.close()\n      end\n    end\n  },\n  {\n    'mfussenegger/nvim-dap-python',\n    ft = 'python',\n    dependencies = {\n      'mfussenegger/nvim-dap',\n      'rcarriga/nvim-dap-ui',\n    },\n    config = function(_, opts)\n      local path = '~/.local/share/nvim/mason/packages/debugpy/venv/bin/python'\n      require('dap-python').setup(path)\n      require('core.utils').load_mappings('dap_python')\n    end,\n  },\n  {\n    'christoomey/vim-tmux-navigator',\n    lazy = false,\n  }\n}\n\nreturn plugins\n
"},{"location":"unix/index.html","title":"UNIX","text":""},{"location":"unix/bash/index.html","title":"bash","text":"","tags":["bash"]},{"location":"unix/bash/yaml.html","title":"YAML and bash","text":"

Example yaml file:

---\nglobal:\n  input:\n    - \"main.c\"\n    - \"main.h\"\n  flags: [ \"-O3\", \"-fpic\" ]\n  sample_input:\n    -  { property1: value1, property2: value2 }\n    -  { property1: \"value 3\", property2: 'value 4' }\n  licence: |\n    this is published under\n    open source license\n    in the hope that it would\n    be useful\n...\n

The following variables are created:

global_input_1=\"main.c\"\nglobal_input_2=\"main.h\"\nglobal_flags_1=\"-O3\"\nglobal_flags_2=\"-fpic\"\nglobal_sample_input_1_property1=\"value1\"\nglobal_sample_input_1_property2=\"value2\"\nglobal_sample_input_2_property1=\"value 3\"\nglobal_sample_input_2_property2=\"value 4\"\nglobal_licence=\"this is published under\\nopen source license\\nin the hope that it would \\nbe useful\\n\"\n__=\" global\"\nglobal_=\" global_input global_flags global_sample_input global_licence\"\nglobal_flags_=\" global_flags_1 global_flags_2\"\nglobal_input_=\" global_input_1 global_input_2\"\nglobal_sample_input_=\" global_sample_input_1 global_sample_input_2\"\nglobal_sample_input_1_=\" global_sample_input_1_property1 global_sample_input_1_property2\"\nglobal_sample_input_2_=\" global_sample_input_2_property1 global_sample_input_2_property2\"\n

A list of variables can iterated with:

$ for f in $global_flags_ ; do eval echo \\$f \\$${f} ; done\nglobal_flags_1 -O3\nglobal_flags_2 -fpic\n
","tags":["bash","YAML"]},{"location":"unix/debian/index.html","title":"Debian","text":""},{"location":"unix/debian/install.html","title":"Installing Debian","text":""},{"location":"unix/debian/install.html#debian-13-trixie-testing","title":"Debian 13 trixie (testing)","text":"

The target of this Debian installation is a 2TB NVME (/dev/nvme0n1). LUKS is enabled for the main Linux and the swap partition. Additionally btrfs with a flat subvolume layout is used.

The target partition layout is:

/dev/nvme0n1p1 2.0 GB EFI System\n/dev/nvme0n1p2 4.0 GB ext4 (/boot)\n/dev/nvme0n1p3 1.9 TB LUKS encrypted (/)\n/dev/nvme0n1p4 94 GB  LUKS encrypted (swap)\n

Get the network installer from Debian as daily build.

Continue with installation via SSH:

Continue configuring Debian installer:

Exit to shell in order to change the btrfs and /tmp configuration.

~ # df -h\nFilesystem                Size      Used Available Use% Mounted on\ntmpfs                     3.1G    532.0K      3.1G   0% /run\ndevtmpfs                 15.3G         0     15.3G   0% /dev\n/dev/sda1               547.0M    547.0M         0 100% /cdrom\nnone                    147.9K     67.0K     75.9K  47% /sys/firmware/efi/efivars\n/dev/mapper/nvme0n1p3_crypt\n                          1.7T      5.8M      1.7T   0% /target\n/dev/nvme0n1p2            3.6G     28.0K      3.4G   0% /target/boot\n/dev/nvme0n1p1            1.9G      4.0K      1.9G   0% /target/boot/efi\n

Unmount the /target partitions:

~ # umount /target/boot/efi\n~ # umount /target/boot\n~ # umount /target\n

Mount the btrfs encrypted partition to /mnt:

~ # mount /dev/mapper/nvme0n1p3_crypt /mnt\n~ # cd /mnt/\n/mnt # ls\n@rootfs\n

Change the name of the root subvolume:

/mnt # mv @rootfs @\n

Create other subvolumes:

/mnt # btrfs subvolume create @snapshots\nCreate subvolume './@snapshots'\n/mnt # btrfs subvolume create @home\nCreate subvolume './@home'\n/mnt # btrfs subvolume create @var_cache\nCreate subvolume './@var_cache'\n/mnt # btrfs subvolume create @var_crash\nCreate subvolume './@var_crash'\n/mnt # btrfs subvolume create @var_log\nCreate subvolume './@var_log'\n/mnt # btrfs subvolume create @var_lib_accountsservice\nCreate subvolume './@var_lib_accountsService'\n/mnt # btrfs subvolume create @var_lib_gdm3\nCreate subvolume './@var_lib_gdm3'\n

Create the new mount structure under /target:

/mnt # cd /\n~ # mount -o noatime,compress=zstd:3,subvol=@ /dev/mapper/nvme0n1p3_crypt /target\n~ # mount /dev/nvme0n1p2 /target/boot/\n~ # mount /dev/nvme0n1p1 /target/boot/efi/\n~ # mkdir /target/.btrfs\n~ # mkdir /target/.snapshots\n~ # mkdir /target/home\n~ # mkdir /target/var\n~ # mkdir /target/var/cache\n~ # mkdir /target/var/crash\n~ # mkdir /target/var/log\n~ # mkdir /target/var/lib\n~ # mkdir /target/var/lib/AccountsService\n~ # mkdir /target/var/lib/gdm3\n~ # mount -o noatime,compress=zstd:3,subvol=@snapshots /dev/mapper/nvme0n1p3_crypt /target/.snapshots\n~ # mount -o noatime,compress=zstd:3,subvol=@home /dev/mapper/nvme0n1p3_crypt /target/home\n~ # mount -o noatime,compress=zstd:3,subvol=@var_cache /dev/mapper/nvme0n1p3_crypt /target/var/cache\n~ # mount -o noatime,compress=zstd:3,subvol=@var_crash /dev/mapper/nvme0n1p3_crypt /target/var/crash\n~ # mount -o noatime,compress=zstd:3,subvol=@var_log /dev/mapper/nvme0n1p3_crypt /target/var/log\n~ # mount -o noatime,compress=zstd:3,subvol=@var_lib_accountsservice /dev/mapper/nvme0n1p3_crypt /target/var/lib/AccountsService\n~ # mount -o noatime,compress=zstd:3,subvol=@var_lib_gdm3 /dev/mapper/nvme0n1p3_crypt /target/var/lib/gdm3\n

Info

The flags ssd and space_cache=v2 are enabled by default.

The flag discard=async is also not needed anymore. TODO

Unmount the btrfs partition:

~ # unmount /mnt\n

Edit the /target/etc/fstab file:

/dev/mapper/nvme0n1p3_crypt  /                         btrfs  noatime,compress=zstd:3,subvol=@                         0   0\n/dev/mapper/nvme0n1p3_crypt  /.snapshots               btrfs  noatime,compress=zstd:3,subvol=@snapshots                0   0\n/dev/mapper/nvme0n1p3_crypt  /home                     btrfs  noatime,compress=zstd:3,subvol=@home                     0   0\n/dev/mapper/nvme0n1p3_crypt  /var/cache                btrfs  noatime,compress=zstd:3,subvol=@var_cache                0   0\n/dev/mapper/nvme0n1p3_crypt  /var/crash                btrfs  noatime,compress=zstd:3,subvol=@var_crash                0   0\n/dev/mapper/nvme0n1p3_crypt  /var/log                  btrfs  noatime,compress=zstd:3,subvol=@var_log                  0   0\n/dev/mapper/nvme0n1p3_crypt  /var/lib/AccountsService  btrfs  noatime,compress=zstd:3,subvol=@var_lib_accountsservice  0   0\n/dev/mapper/nvme0n1p3_crypt  /var/lib/gdm3             btrfs  noatime,compress=zstd:3,subvol=@var_lib_gdm3             0   0\n\n/dev/mapper/nvme0n1p3_crypt  /.btrfs                   btrfs  noatime,compress=zstd:3,subvolid=5                       0   0\n

Info

Instead of device names the UUID of the partitions should be used. The get corresponding UUIDs use the command blkid.

Info

Optional: the directory /tmp can be configured as tmpfs. TODO Why systemd tmp.mount should currently not be used in Debian

Append the following line to /target/etc/fstab:

tmpfs   /tmp   tmpfs   nosuid,nodev,strictatime,size=4g,nr_inodes=1m,mode=1777   0   0\n

Create the directory and mount it for installation:

~ # mkdir /target/tmp\n~ # mount -t tmpfs -o nosuid,nodev,strictatime,size=4g,nr_inodes=1m,mode=1777 tmpfs /target/tmp\n

Exit the shell and continue with the installation process.

Continue configuring Debian installer:

Finished

"},{"location":"unix/debian/tweak.html","title":"Tweak the Fresh Installation","text":"

After the first reboot tweak the fresh installation.

"},{"location":"unix/debian/tweak.html#btrfs","title":"btrfs","text":"

Fix permissions for /.btrfs and /.snapshots:

sudo chown root:sudo /.btrfs /.snapshots\nsudo chmod 0750 /.btrfs /.snapshots\n

Install missing tools:

sudo apt install btrbk btrfs-compsize\n
"},{"location":"unix/debian/tweak.html#use-uuid-in-etcfstab","title":"Use UUID in /etc/fstab","text":"

Get with sudo blkid the UUIDs of each partition and use the UUID instead of the partition device name.

"},{"location":"unix/debian/tweak.html#luks","title":"LUKS","text":"

TODO unlock swap partition with file

"},{"location":"unix/debian/tweak.html#plymouth","title":"Plymouth","text":"

Activate plymouth during boot for LUKS prompt.

Add splash to GRUB_CMDLINE_LINUX_DEFAULT:

/etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT=\"quiet splash\"\n

Update GRUB configuration:

sudo update-grub2\n
"},{"location":"unix/debian/tweak.html#configure-zram","title":"Configure zram","text":"

TODO

"},{"location":"unix/debian/tweak.html#install-additional-packages","title":"Install additional Packages","text":"
sudo apt install lshw\n

TODO merge this with Ansible

"},{"location":"unix/debian/tweak.html#finalize-with-ansible","title":"Finalize with Ansible","text":"

TODO describe the steps

"},{"location":"unix/filesystems/index.html","title":"Filesystems","text":""},{"location":"unix/filesystems/btrfs.html","title":"btrfs","text":"

btrfs combines a filesystem with copy-on-write principles with a logical volume manager. The btrfs file system is marked as stable in the Linux kernel since 2013.

https://btrfs.readthedocs.io/

"},{"location":"unix/filesystems/btrfs.html#layout","title":"Layout","text":"

With the following layout booting a read-only snapshot is possible since all directories that needs to be writable are not part of the root file system subvolume:

/etc/fstab
UUID=...   /                          btrfs   noatime,compress=zstd:3,subvol=@                          0   0\nUUID=...   /.snapshots                btrfs   noatime,compress=zstd:3,subvol=@snapshots                 0   0\nUUID=...   /home                      btrfs   noatime,compress=zstd:3,subvol=@home                      0   0\nUUID=...   /var/cache                 btrfs   noatime,compress=zstd:3,subvol=@var_cache                 0   0\nUUID=...   /var/crash                 btrfs   noatime,compress=zstd:3,subvol=@var_crash                 0   0\nUUID=...   /var/log                   btrfs   noatime,compress=zstd:3,subvol=@var_log                   0   0\nUUID=...   /var/lib/AccountsService   btrfs   noatime,compress=zstd:3,subvol=@var_lib_accountsservice   0   0\nUUID=...   /var/lib/gdm3              btrfs   noatime,compress=zstd:3,subvol=@var_lib_gdm3              0   0\n\nUUID=...   /.btrfs                    btrfs   noatime,compress=zstd:3,subvolid=5                        0   0\n

Info

The directories /.btrfs and /.snapshots must be only accessible by the root user and the group sudo (for tab completion).

sudo chown root:sudo /.btrfs /.snapshots\nsudo chmod 0750 /.btrfs /.snapshots\n

Warning

Due to LUKS disk encryption the /boot directory is not part of the root file system subvolume. Do not delete any kernels that are needed to boot an old snapshot.

Depending on the usage of the computer, other subvolumes are also needed:

/etc/fstab
UUID=...   /var/lib/docker            btrfs   noatime,compress=zstd:3,subvol=@var_lib_docker            0   0\nUUID=...   /var/lib/container         btrfs   noatime,compress=zstd:3,subvol=@var_lib_container         0   0\nUUID=...   /var/lib/libvirt           btrfs   noatime,compress=zstd:3,subvol=@var_lib_libvirt           0   0\n\nUUID=...   /srv                       btrfs   noatime,compress=zstd:3,subvol=@srv                       0   0\n
"},{"location":"unix/filesystems/btrfs.html#snapshots","title":"Snapshots","text":""},{"location":"unix/filesystems/btrfs.html#create-snapshots","title":"Create Snapshots","text":"

Create a snapshot from a subvolume:

sudo btrfs subvolume snapshot /path/to/volume /path/to/snapshot\n

The snapshot is writable by default. A read-only snapshot can be created with the additional -r option.

"},{"location":"unix/filesystems/btrfs.html#read-only-snapshots","title":"Read-only Snapshots","text":"
$ sudo btrfs property get -t subvol /path/to/snapshot\nro=true\n

Make snapshot writeable:

sudo btrfs property set -ts /path/to/snapshot ro false\n
"},{"location":"unix/filesystems/btrfs.html#rollback","title":"Rollback","text":"

First boot to the last working snapshot. If you have grub-btrfs installed, you can choose the snapshot from the boot menu. Or you can add the snapshot as a kernel option.

Normally btrfs adds the following option the kernel (during update-grub2):

rootflags=subvol=@\n

To select a different snapshot change the option during boot (press e in the GRUB menue) to:

rootflags=subvolid=<id>\n

Now the snapshot is used as rootfs. Due to the chosen layout even a read-only snapshot (i.e., create by btrbk) can be booted.

After the system was successfully booted, check if the right snapshot is mounted:

$ mount | grep \" / \"\n/dev/mapper/vda3_crypt on / type btrfs (rw,noatime,compress=zstd:3,discard=async,space_cache=v2,subvolid=277,subvol=/@snapshots/rootfs.20231214T1820)\n

Even if the mount option is rw the snapshot can be still read-only.

To make the current snapshot the default for the rootfs subvolume, the following steps must be performed.

Change into /.btrfs and create a read-only snapshot of the current system:

$ sudo btrfs subvolume snapshot -r @ @snapshots/broken-rootfs\nCreate a readonly snapshot of '@' in '@snapshots/broken-rootfs'\n

Delete the broken root file system:

$ sudo btrfs subvolume snapshot delete @\nDelete subvolume (no-commit): '/.btrfs/@'\n

Create a writable snapshot of the current booted snapshot as the new rootfs:

$ sudo btrfs subvolume snapshot @snapshots/rootfs.20231214T1820 @\nCreate a snapshot of '@snapshots/rootfs.20231214T1820' in './@'\n

Reboot the system and check the root file system:

$ mount | grep \" / \"\n/dev/mapper/vda3_crypt on / type btrfs (rw,noatime,compress=zstd:3,discard=async,space_cache=v2,subvolid=282,subvol=/@)\n
"},{"location":"unix/filesystems/btrfs.html#disable-cow","title":"Disable COW","text":"

Copy-on-write should be disabled when large files are frequently changed by random write (i.e., databases or VM images). In btrfs the copy-on-write mechanism can be disabled by mounting with the option nodatacow or with chattr +C for directories or files.

Most tools are aware of this problem and are disabling copy-on-write by default:

"},{"location":"unix/filesystems/btrfs.html#tools","title":"Tools","text":""},{"location":"unix/filesystems/btrfs.html#overview","title":"Overview","text":"

Used tools:

Other:

"},{"location":"unix/filesystems/btrfs.html#btrbk","title":"btrbk","text":"
sudo apt install btrbk\n
"},{"location":"unix/filesystems/btrfs.html#config","title":"Config","text":"

Example configuration for btrbk and the rootfs subvolume:

/etc/btrbk/btrbk.conf
# Enable transaction log\ntransaction_log            /var/log/btrbk.log\n\n# Preserve all snapshots for a minimum period of time.\nsnapshot_preserve_min      1d\n\n# Retention policy for the source snapshots.\nsnapshot_preserve          3h 5d 4w 6m 1y\n\nsnapshot_dir   /.snapshots\nsubvolume      /\nsnapshot_name  rootfs\nsubvolume      /home\nsnapshot_name  home\n
"},{"location":"unix/filesystems/btrfs.html#create-a-snapshot","title":"Create a snapshot","text":"
sudo btrbk run\n

To perform a try-run add the option -n.

"},{"location":"unix/filesystems/btrfs.html#show-diff-between-two-snapshots","title":"Show diff between two Snapshots","text":"

Create a snapshot and install the package htop and create a second snapshot. After that the differences between both snapshots can be shown:

$ sudo btrbk diff /.snapshots/rootfs.20231214T1820_1 /.snapshots/rootfs.20231214T1821\nFLAGS  COUNT  SIZE        FILE\n+c.        1   44.00 KiB  etc/mailcap\n+c.        1  312.00 KiB  usr/bin/htop\n+ci        1    2.49 KiB  usr/share/applications/htop.desktop\n+c.        1   28.00 KiB  usr/share/applications/mimeinfo.cache\n+ci        1    0.22 KiB  usr/share/doc/htop/AUTHORS\n+..        1    4.00 KiB  usr/share/doc/htop/README.gz\n+..        1    8.00 KiB  usr/share/doc/htop/changelog.Debian.gz\n+..        1   20.00 KiB  usr/share/doc/htop/changelog.gz\n+ci        1    1.29 KiB  usr/share/doc/htop/copyright\n+c.        1   28.00 KiB  usr/share/icons/hicolor/icon-theme.cache\n+c.        1   12.00 KiB  usr/share/icons/hicolor/scalable/apps/htop.svg\n+..        1    8.00 KiB  usr/share/man/man1/htop.1.gz\n+..        1    4.00 KiB  usr/share/pixmaps/htop.png\n+c.        1  140.00 KiB  var/lib/apt/extended_states\n+ci        1    0.56 KiB  var/lib/dpkg/info/htop.list\n+ci        1    0.63 KiB  var/lib/dpkg/info/htop.md5sums\n+c.        1    2.30 MiB  var/lib/dpkg/status\n+c.        1    2.30 MiB  var/lib/dpkg/status-old\n

The list of available snapshots can be shown with btrbk list snapshots.

"},{"location":"unix/filesystems/btrfs.html#grub-btrfs","title":"grub-btrfs","text":"

TODO

"},{"location":"unix/filesystems/btrfs.html#compsize","title":"compsize","text":"
sudo apt install btrfs-compsize\n

To see the impact of the used compression:

$ sudo compsize -x /\nProcessed 275808 files, 182511 regular extents (183978 refs), 91269 inline.\nType       Perc     Disk Usage   Uncompressed Referenced\nTOTAL       79%      7.0G         8.8G         9.5G\nnone       100%      6.0G         6.0G         6.5G\nzstd        33%      961M         2.7G         2.9G\n
"},{"location":"unix/filesystems/luks.html","title":"Linux Unified Key Setup (LUKS)","text":""},{"location":"unix/systemd/index.html","title":"systemd","text":""},{"location":"unix/systemd/index.html#add-a-service-timer","title":"Add a service, timer, ...","text":"

Create file in /usr/local/lib/systemd/system.

"},{"location":"unix/systemd/index.html#documentation","title":"Documentation","text":""},{"location":"unix/systemd/index.html#systemd-for-administrators","title":"systemd for Administrators","text":""},{"location":"unix/systemd/bootctl.html","title":"bootctl","text":""},{"location":"unix/systemd/journalctl.html","title":"journalctl","text":"

To see messages from other users and the system, add the current user to the group systemd-journal.

"},{"location":"unix/systemd/journalctl.html#display-logs","title":"Display Logs","text":""},{"location":"unix/systemd/journalctl.html#from-the-current-boot","title":"From the Current Boot","text":"
journalctl -b\n

Show the past boots

journalctl --list-boots\n
"},{"location":"unix/systemd/journalctl.html#time-window","title":"Time Window","text":"
journalctl --since \"2020-01-01\" --until \"2020-01-02 17:15:00\"\n

or

journalctl --since yesterday --until \"1 hour ago\"\n
"},{"location":"unix/systemd/journalctl.html#kernel-messages","title":"Kernel Messages","text":"
journalctl -k\n
"},{"location":"unix/systemd/journalctl.html#filter","title":"Filter","text":""},{"location":"unix/systemd/journalctl.html#by-priority","title":"By Priority","text":"

Priority: emerg, alert, crit, err, warning, notice, info, debug

journalctl -p err -b\n
"},{"location":"unix/systemd/journalctl.html#by-facility","title":"By Facility","text":"

Facility: kern, mail, syslog, local0, ...

journalctl --facility=auth\n

Get list of facilities: journalctl --facility=help

"},{"location":"unix/systemd/journalctl.html#by-unit","title":"By Unit","text":"

Get list of systemd units: systemctl list-units

journalctl -u ssh\njournalctl -u ssh.service\njournalctl --unit ssh\n
"},{"location":"unix/systemd/journalctl.html#by-identifier","title":"By Identifier","text":"
journalctl -t sshd\njournalctl --identifier=sshd\n
"},{"location":"unix/systemd/journalctl.html#by-field","title":"By Field","text":"

Get a description of available fields: man systemd.journal-fields

Query which entries exist for a speficic field:

journalctl -F _UID\njournalctl -F _PID\n

List all entries in the journal for a specific field:

journalctl _PID=9099\n
"},{"location":"unix/systemd/journalctl.html#by-pattern","title":"By Pattern","text":"

Grep a pattern in the message text.

Find case insensitive all entry with message containing error:

journal -g \"error\"\n
"},{"location":"unix/systemd/journalctl.html#disk-usage","title":"Disk Usage","text":"
journalctl --disk-usage\n

Clear the history

journalctl --vacuum-time=1week\n
"},{"location":"unix/systemd/localectl.html","title":"resolvectl","text":""},{"location":"unix/systemd/loginctl.html","title":"loginctl","text":""},{"location":"unix/systemd/loginctl.html#wayland-or-x11","title":"Wayland or X11","text":"
$ loginctl show-session 2 | grep Type\nType=x11\n
"},{"location":"unix/systemd/machinectl.html","title":"machinectl","text":""},{"location":"unix/systemd/networkctl.html","title":"networkctl","text":""},{"location":"unix/systemd/portablectl.html","title":"localectl","text":""},{"location":"unix/systemd/resolvectl.html","title":"protablectl","text":""},{"location":"unix/systemd/systemctl.html","title":"systemctl","text":""},{"location":"unix/systemd/systemctl.html#state-of-systemd-and-services","title":"State of systemd and services","text":"

Overview about all services:

systemctl\n

Get information about a service:

systemctl status cron.service\n
"},{"location":"unix/systemd/systemctl.html#content-of-service-timer-etc","title":"Content of service, timer, etc","text":"
systemctl cat cron.service\n
"},{"location":"unix/systemd/systemctl.html#boot-into-bios-setup","title":"Boot into BIOS Setup","text":"
sudo systemctl reboot --firmware-setup\n
"},{"location":"unix/systemd/systemd.html","title":"systemd Tools","text":""},{"location":"unix/systemd/systemd.html#systemd-cgls","title":"systemd-cgls","text":""},{"location":"unix/systemd/timedatectl.html","title":"timedatectl","text":""},{"location":"unix/tools/index.html","title":"Tools","text":""},{"location":"unix/tools/apt.html","title":"Advanced Package Tool (apt)","text":"","tags":["Ubuntu"]},{"location":"unix/tools/apt.html#keys","title":"Keys","text":"","tags":["Ubuntu"]},{"location":"unix/tools/apt.html#list-keys","title":"List Keys","text":"

Get a list of all keys configured for apt on your system:

sudo apt-key list\n
","tags":["Ubuntu"]},{"location":"unix/tools/apt.html#refresh-expired-keys","title":"Refresh Expired Keys","text":"

When you get an EXPKEYSIG error while apt update, you can update the expired key with the following command:

sudo apt-key adv --keyserver keys.gnupg.net --recv-keys AAAABBBBCCCCDDDD\n
","tags":["Ubuntu"]},{"location":"unix/tools/apt.html#packages-have-been-kept-back","title":"Packages have been kept back","text":"
$ sudo apt upgrade\nReading package lists... Done\nBuilding dependency tree... Done\nReading state information... Done\nCalculating upgrade... Done\nThe following packages have been kept back:\n  qemu-guest-agent snapd\n0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded.\n

If packages are kept back, there are three reasons for that:

","tags":["Ubuntu"]},{"location":"unix/tools/apt.html#packages-are-marked-as-hold-back","title":"Packages are marked as hold back","text":"

Individual packages can be marked as held back with apt-mark hold. This will prevent that the packages are automatically installed, upgraded or removed.

To check if a package is held back use the command apt-mark unhold:

$ apt-mark showhold\nqemu-guest-agent\n
","tags":["Ubuntu"]},{"location":"unix/tools/apt.html#packages-have-changed-dependencies","title":"Packages have changed dependencies","text":"

If the dependencies of a package has changed, and one of the new dependencies is not unmet, than the package will not be updated.

To see which package version is installed and which is upgradable use the command apt list -a:

$ apt list -a qemu-guest-agent\nListing... Done\nqemu-guest-agent/jammy-updates 1:6.2+dfsg-2ubuntu6.5 amd64 [upgradable from: 1:6.2+dfsg-2ubuntu6.4]\nqemu-guest-agent/now 1:6.2+dfsg-2ubuntu6.4 amd64 [installed,upgradable to: 1:6.2+dfsg-2ubuntu6.5]\nqemu-guest-agent/jammy-security 1:6.2+dfsg-2ubuntu6.2 amd64\nqemu-guest-agent/jammy 1:6.2+dfsg-2ubuntu6 amd64\n

Use apt-show for each version to check the dependencies:

apt show qemu-guest-agent=1:6.2+dfsg-2ubuntu6.4\napt show qemu-guest-agent=1:6.2+dfsg-2ubuntu6.5\n

If there are changed dependencies, install the update with the new depencies via:

sudo apt --with-new-pkgs upgrade\n

When you use apt install to resolve this issue the packages will be marked as manual installed.

","tags":["Ubuntu"]},{"location":"unix/tools/apt.html#packages-are-a-phased-update","title":"Packages are a phased update","text":"

Sometimes packages are not available to all users. Then only some users receive the update. This is a safety feature.

To check whether an update is a phased update, use the following command:

$ apt-cache policy qemu-guest-agent\nqemu-guest-agent:\n  Installed: 1:6.2+dfsg-2ubuntu6.4\n  Candidate: 1:6.2+dfsg-2ubuntu6.5\n  Version table:\n     1:6.2+dfsg-2ubuntu6.5 500 (phased 30%)\n        500 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages\n *** 1:6.2+dfsg-2ubuntu6.4 100\n        100 /var/lib/dpkg/status\n     1:6.2+dfsg-2ubuntu6.2 500\n        500 http://security.ubuntu.com/ubuntu jammy-security/universe amd64 Packages\n     1:6.2+dfsg-2ubuntu6 500\n        500 http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages\n

In this case the update is only available for 30% of all users.

","tags":["Ubuntu"]},{"location":"unix/tools/apt.html#netselect-apt","title":"netselect-apt","text":"

A tool that finds the nearest and fastest mirror and creates a source.list file for this mirror.

","tags":["Ubuntu"]},{"location":"unix/tools/fun.html","title":"Fun Tools","text":"

A list of \"fun\" tools for Linux.

"},{"location":"unix/tools/fun.html#cowsay","title":"CowSay","text":""},{"location":"unix/tools/fun.html#neofetch","title":"NeoFetch","text":""},{"location":"unix/tools/fun.html#misc","title":"Misc","text":""},{"location":"unix/tools/nvme.html","title":"NVME CLI","text":""},{"location":"unix/tools/nvme.html#general-usage","title":"General usage","text":"
$ sudo nvme list\n
$ sudo nvme smart-log /dev/nvme0n1\n

Device performance with htparm:

$ sudo hdparm -Tt --direct /dev/nvme0n1\n
"},{"location":"unix/tools/nvme.html#update-firmware","title":"Update Firmware","text":"

Display available slots and installed firmware versions:

$ sudo nvme fw-log /dev/nvme0n1\nFirmware Log for device:nvme0n1\nafi  : 0x1\nfrs1 : 5B2QGXA7\n

Check if firmware update is supported and which slots are available:

$ sudo nvme id-ctrl -H /dev/nvme0n1 | grep Firmware\n  [9:9] : 0x1   Firmware Activation Notices Supported\n  [4:4] : 0x1   Firmware Activate Without Reset Supported\n  [3:1] : 0x3   Number of Firmware Slots\n  [0:0] : 0     Firmware Slot 1 Read/Write\n

Download firmware:

$ sudo nvme fw-download -f firmware.enc /dev/nvme0n1\n

Commit firmware to slot 2 without activation (-a 0):

$ sudo nvme fw-commit -s 2 -a 0 /dev/nvme0n1\n

Check with nwme fw-log if firmware is stored in slot 2. Than activate (-a 2) the firmware in slot 2.

$ sudo nvme fw-commit -s 2 -a 2 /dev/nvme0n1\n
"},{"location":"unix/tools/nvme.html#samsung-firmware","title":"Samsung Firmware","text":"

https://semiconductor.samsung.com/consumer-storage/support/tools/

"},{"location":"unix/tools/smartmontools.html","title":"smartmontools","text":""},{"location":"unix/tools/smartmontools.html#get-information-about-device","title":"Get information about device","text":"

Scan for devices:

sudo smartctl --scan\n

In order to check if the device supports SMART and if SMART is enabled, use option --info or -i:

sudo smartctl --info /dev/sda\n

If the device is not in the smartctl database, update the database with:

sudo /usr/sbin/update-smart-drivedb\n
"},{"location":"unix/tools/smartmontools.html#enable-smart","title":"Enable SMART","text":"
sudo smartctl --smart=on --offlineauto=on --saveauto=on /dev/sda\n
"},{"location":"unix/tools/smartmontools.html#get-the-capabilities-of-the-device","title":"Get the capabilities of the device","text":"

Get the capabilities of the device with option --capabilities or -c:

sudo smartctl --capabilities /dev/sda\n
"},{"location":"unix/tools/smartmontools.html#print-the-health-status","title":"Print the health status","text":"

Get the health status of the device with option --health or -H:

sudo smartctl --health /dev/sda\n
"},{"location":"unix/tools/smartmontools.html#dump-all-information-about-the-device","title":"Dump all information about the device","text":"

To get all SMART information about the device with option --all or -a:

sudo smartctl --all /dev/sda\n

Get all the information above and all non-SMART information about the device with option --xall or -x:

sudo smartctl --xall /dev/sda\n
"},{"location":"unix/tools/smartmontools.html#print-error-log","title":"Print error log","text":"

Print device error log with option --log=error or -l error:

sudo smartctl --log=error /dev/sda\n
"},{"location":"unix/tools/smartmontools.html#performing-self-tests","title":"Performing self tests","text":"

Start self test with option --test or -t:

sudo smartctl --test=long /dev/sda\n

Get results of test:

sudo smartctl --log=selftest /dev/sda\n
"},{"location":"unix/tools/smartmontools.html#access-disks-in-raid-system","title":"Access disks in RAID system","text":""},{"location":"unix/tools/smartmontools.html#megaraid","title":"MegaRAID","text":"

Get list of disk in RAID:

sudo /opt/MegaRAID/storcli/storcli64 /c0 /eall /sall show\n

Use the DID as disk number in the smartctl command:

sudo smartctl --info --device=megaraid,40 /dev/sda\n
"},{"location":"unix/tools/tmux.html","title":"tmux","text":"

tmux is a terminal multiplexer.

","tags":["tmux"]},{"location":"unix/tools/tmux.html#scripting-with-tmux","title":"Scripting with tmux","text":"","tags":["tmux"]},{"location":"unix/tools/tmux.html#check-if-running-inside-a-tmux-session","title":"Check if running inside a tmux session","text":"

If tmux is version 3.2 or newer the environment variable TERM_PROGRAM is set:

if [ \"$TERM_PROGRAM\" = tmux ]\nthen\n  echo \"Inside a tmux session\"\nelse\n  echo \"Outside a tmux session\"\nfi\n
","tags":["tmux"]},{"location":"unix/tools/tmux.html#send-keys","title":"send-keys","text":"

The command send-keys has the following syntax:

tmux send-keys -t '{session}:{window}.{pane}' {command} ENTER\n

The target can be shorted as -t ':.!', which means:

Usage with new-window:

tmux new-window -c \"${dir}\" -n \"${name}\"\ntmux send-keys -t ':.' \"${EDITOR}\" ENTER\n

Usage with new-session:

tmux new-session -d\ntmux send-keys -t ':.' \"${EDITOR}\" ENTER\ntmux attach-session -t \":\"\n
","tags":["tmux"]},{"location":"unix/tools/tmux.html#current-special-key-bindings","title":"Current special key bindings","text":"","tags":["tmux"]},{"location":"unix/truenas/index.html","title":"TrueNAS","text":"","tags":["TrueNAS"]},{"location":"unix/ubuntu/index.html","title":"Ubuntu","text":"","tags":["Ubuntu"]},{"location":"unix/virtualization/index.html","title":"Virtualization","text":""},{"location":"unix/virtualization/proxmox/index.html","title":"Proxmox","text":"","tags":["Proxmox"]},{"location":"unix/virtualization/proxmox/terminal.html","title":"Terminal Access","text":"","tags":["Proxmox"]},{"location":"unix/virtualization/proxmox/terminal.html#connect-to-serial-console","title":"Connect to serial console","text":"

Check if terminal is available in guest:

$ qm monitor 1500\nEntering Qemu Monitor for VM 1500 - type 'help' for help\nqm> info chardev\n...\nserial0: filename=disconnected:unix:/var/run/qemu-server/1500.serial0,server=on\nqm>\n

Starting a connection to serial console:

$ qm terminal 1500\nstarting serial terminal on interface serial0 (press control-O to exit)\n

Stop the connection with ++Ctrl+o++.

","tags":["Proxmox"]},{"location":"unix/virtualization/proxmox/terminal.html#switch-to-console-terminal-via-qemu","title":"Switch to console terminal via QEMU","text":"

To switch to a virtual console, you can: * Go to Monitor of the virtual machine in the Web front-end and use the command sendkey ctrl-alt-fN. * Use qm sendkey vmid \"sendkey-ctrl-alt-fN\" in the shell.

","tags":["Proxmox"]},{"location":"unix/virtualization/proxmox/terminal.html#switch-to-console-terminal-via-chvt","title":"Switch to console terminal via chvt","text":"

The command chvt N switch to the virtual console N. For example:

$ sudu chvt 3\n
","tags":["Proxmox"]},{"location":"windows/index.html","title":"Windows","text":"","tags":["Windows"]},{"location":"windows/index.html#windows-updates","title":"Windows Updates","text":"

Get stand-alone update packages directly from Microsoft.

Get information about current running Windows:

PS> (Get-ComputerInfo).OSVersion\n10.0.19044\n

Explanation of the number can be found here.

Get the Window Update Build Revision (UBR):

PS> (Get-ComputerInfo).UBR\n2251\n

Get list of installed updates:

PS> Get-HotFix | Sort-Object InstalledOn -Descending\n
","tags":["Windows"]},{"location":"windows/index.html#check-windows-version","title":"Check Windows Version","text":"
if ((Get-CimInstance -ClassName Win32_OperatingSystem).Caption -like \"Microsoft Windows 10*\")\n{\n  Write-Host \"Windows 10\"\n}\nelse\n{\n  Write-Host \"Windows 11\"\n}\n
","tags":["Windows"]},{"location":"windows/tools/index.html","title":"Windows - Tools","text":" ","tags":["Windows"]},{"location":"windows/tools/bitlocker.html","title":"BitLocker","text":"

BitLocker is a proprietary volume encryption tool includes in Microsoft Windows. Without any configuration BitLocker using TPM. When using TPM on start of the computer no password needs to be entered.

The command line command manage-bde can be used to turn on BitLocker and monitor the current status.

"},{"location":"windows/tools/bitlocker.html#configure","title":"Configure","text":"

BitLocker can be configured through group policies or directly with registry keys.

Info

This configuration settings requires at least Windows 10, older versions of Windows use different options.

"},{"location":"windows/tools/bitlocker.html#group-policies","title":"Group Policies","text":"

The group policies are changed in the domain controller or locally via gpedit.msc.

"},{"location":"windows/tools/bitlocker.html#use-without-tpm","title":"Use without TPM","text":"

To enable password protected volume encryption the following group policy needs to be enabled (see admx.help):

"},{"location":"windows/tools/bitlocker.html#enable-better-encryption","title":"Enable better encryption","text":"

To use 256-bit AES encryption instead of the 128-bit default, the following group policies must be defined (see admx.help):

"},{"location":"windows/tools/bitlocker.html#registry-settings","title":"Registry Settings","text":""},{"location":"windows/tools/bitlocker.html#use-without-tpm_1","title":"Use without TPM","text":"

To enable password protected volume encryption the following registry entries need to be defined:

HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\FVE

"},{"location":"windows/tools/bitlocker.html#enable-better-encryption_1","title":"Enable better encryption","text":"

To use 256-bit AES encryption instead of the 128-bit default, the following registry entries must be defined:

HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\FVE

"},{"location":"windows/tools/bitlocker.html#enable-encryption","title":"Enable encryption","text":"

Enable BitLocker with a password (must be at least 8 characters):

PS> manage-bde.exe -on C: -password\n

Using abbreviations:

PS> manage-bde.exe -on C: -pw\n

To enable the encryption, the computer needs to be restarted: shutdown /r /t 0.

Warning

The keyboard layout can be different during password prompt of BitLocker. Therefore be prepared, if the password is misspelled that you used a key that has a different mapping.

Info

If the keyboard layout is different or you misspelled the password press ++ESC++ to boot without BitLocker enabled. The password needs to be set again.

"},{"location":"windows/tools/bitlocker.html#check-status","title":"Check status","text":"

After first successful restart, the encryption of the volume is starting. The current progress can be monitored with:

PS> manage-bde.exe -status C:\nBitLocker Drive Encryption: Configuration Tool version 10.0.22621\nCopyright (C) 2013 Microsoft Corporation. All rights reserved.\n\nVolume C: [Windows]\n[OS Volume]\n\n    Size:                 69,13 GB\n    BitLocker Version:    2.0\n    Conversion Status:    Used Space Only Encrypted\n    Percentage Encrypted: 100,0%\n    Encryption Method:    AES 256\n    Protection Status:    Protection On\n    Lock Status:          Unlocked\n    Identification Field: Unknown\n    Key Protectors:\n        Password\n
"},{"location":"windows/tools/bitlocker.html#add-numerical-password-as-fallback","title":"Add Numerical Password (as Fallback)","text":"

The numerical password is enabled with the following command:

PS> manage-pde -protectors -add C: -recoverypassword\n

or by using abbreviations:

PS> manage-bde.exe -protectors -add C: -rp\n

To get the protector methods:

PS> manage-bde.exe -protectors -get C:\nBitLocker Drive Encryption: Configuration Tool version 10.0.22621\nCopyright (C) 2013 Microsoft Corporation. All rights reserved.\n\nVolume C: [Windows]\nAll Key Protectors\n\n    Numerical Password:\n      ID: {89701158-94B4-42D2-87EB-82B8A03E45CD}\n      Password:\n        463881-116138-212971-219626-306295-227139-146784-038038\n\n    Password:\n      ID: {B1129007-8A8C-4398-BC67-0F608F771ABD}\n

The RecoveryPassword is called numerical password and the value is visible. Please store this recovery password in case you forget your password.

"},{"location":"windows/tools/bitlocker.html#change-password","title":"Change Password","text":"

The password can only be changed if a secondary protector is enabled (i.e., a numerical recovery password):

PS> manage-pde -changepassword C:\n
"},{"location":"windows/tools/bitlocker.html#script","title":"Script","text":"

The following PowerShell script enable BitLocker on C::

if ((Get-BitLockerVolume C:).EncryptionMethod -ne \"None\") {\n  Write-Host \"\"\n  Write-Host \"Volume C: is already encrypted\" -ForegroundColor red\n  Get-BitLockerVolume C: | Select-Object *\n  Write-Host \"Disable BitLocker: \" -NoNewLine\n  Write-Host \"Disable-BitLocker -MountPoint C:\" -ForegroundColor yellow\n  Exit 1\n}\n\nfunction Set-RegistryProperty {\n  Param (\n    [Parameter(Mandatory=$True, Position=0)]\n    [String] $Path,\n    [Parameter(Mandatory=$True, Position=1)]\n    [String] $Name,\n    [Parameter(Mandatory=$True, Position=2)]\n    [String] $Type,\n    [Parameter(Mandatory=$True, Position=3)]\n    [Object] $Value\n  )\n\n  if (-not (Test-Path $Path)) {\n    New-Item -Path $Path -Force > $null\n  }\n  if ((Get-Item $Path).Property -contains $Name) {\n    Set-ItemProperty -Path $Path -Name $Name `\n                     -Type $Type -Value $Value -Force > $null\n  } else {\n    New-ItemProperty -Path $Path -Name $Name `\n                     -PropertyType $Type -Value $Value -Force > $null\n  }\n}\n\nWrite-Host \"\"\nWrite-Host \"Configure Bitlocker without TPM and better encryption\"\n$properties = `\n  @{Name = 'UseAdvancedStartup';          Type = 'DWORD'; Value = 1}, `\n  @{Name = 'EnableBDEWithNoTPM';          Type = 'DWORD'; Value = 1}, `\n  @{Name = 'UseTPM';                      Type = 'DWORD'; Value = 0}, `\n  @{Name = 'UseTPMPIN';                   Type = 'DWORD'; Value = 0}, `\n  @{Name = 'UseTPMKey';                   Type = 'DWORD'; Value = 0}, `\n  @{Name = 'UseTPMKeyPIN';                Type = 'DWORD'; Value = 0}, `\n  @{Name = 'EncryptionMethodWithXtsOs';   Type = 'DWORD'; Value = 7}, `\n  @{Name = 'EncryptionMethodWithXtsFdv';  Type = 'DWORD'; Value = 7}, `\n  @{Name = 'EncryptionMethodWithXtsRdv';  Type = 'DWORD'; Value = 4}\n\nForEach ($property in $properties) {\n  Set-RegistryProperty -Path 'HKLM:\\SOFTWARE\\Policies\\Microsoft\\FVE' `\n                       -Name $property.Name `\n                       -Type $property.Type -Value $property.Value\n}\n\nWrite-Host \"\"\nWrite-Host \"Activate Bitlocker\"\nEnable-BitLocker -MountPoint C: -PasswordProtector\nEnable-BitLocker -MountPoint C: -RecoveryPasswordProtector `\n                                -ErrorAction SilentlyContinue\n\nWrite-Host \"\"\nWrite-Host \"Reboot: \" -NoNewLine\nWrite-Host \"shutdown /r /t 0\" -ForegroundColor yellow\nWrite-Host \"\"\n
"},{"location":"windows/tools/winget.html","title":"winget","text":"

Windows Package Manager CLI (aka winget) can be used to install/upgrade software on Windows via the command line.

","tags":["Windows"]},{"location":"windows/tools/winget.html#install","title":"Install","text":"

Download latest version from GitHub release page.

Info

The download a package with all dependencies you can use https://store.rg-adguard.net/.

Now you will see all packages inside this application.

Install winget as a provisioned package:

PS> Add-AppxProvisionedPackage\n        -PackagePath 'Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle'\n        -LicensePath '7bcb1a0ab33340daa57fa5b81faec616_License1.xml'\n        -DependencyPackagePath\n            'Microsoft.VCLibs.x64.14.00.Desktop.appx',\n            'Microsoft.UI.Xaml.2.7_7.2208.15002.0_x64__8wekyb3d8bbwe.appx'\n        -Online\n

Enable provisioned package for the current user:

(Get-AppxProvisionedPackage -Online |\n   Where-Object -Property DisplayName -EQ Microsoft.DesktopAppInstaller\n).InstallLocation | Add-AppxPackage -Register -DisableDevelopmentMode\n

The executable winget.exe is than found in $env:USERPROFILE\\AppData\\Local\\Microsoft\\WindowsApps\\.

Warning

If there are policies that does not allow Microsoft applications, the application Microsoft.DesktopAppInstaller must be whitelisted.

","tags":["Windows"]},{"location":"windows/tools/winget.html#searching-for-packages","title":"Searching for Packages","text":"

List all available packages:

PS> winget search\n

Can also be seen at microsoft/winget-pkgs.

List all packages that contains note:

PS> winget search note\n

Display information about a package:

PS> winget show notepad++\n
","tags":["Windows"]},{"location":"windows/tools/winget.html#installing-a-package","title":"Installing a Package","text":"

Try to install all packages in machine scope (for all users):

PS> winget install --scope machine --exact --id gerardog.gsudo\n

Therefore, the default scope should be machine. Change the default scope in the settings

Some package can not be installed in machine scope:

PS> winget install --scope user --exact --id Microsoft.WindowsTerminal\n
","tags":["Windows"]},{"location":"windows/tools/winget.html#listing-package-repositories","title":"Listing Package Repositories","text":"
PS> winget source list\n
","tags":["Windows"]},{"location":"windows/tools/winget.html#upgrading-packages","title":"Upgrading Packages","text":"

To get a list of upgradeable packages:

PS> winget upgrade\n

To upgrade a package:

PS> winget upgrade Notepad++.Notepad++\n
","tags":["Windows"]},{"location":"windows/tools/winget.html#configuration-settings","title":"Configuration Settings","text":"

To open the settings in an editor:

PS> winget settings\n

The settings (documentation on these settings):

{\n    \"$schema\": \"https://aka.ms/winget-settings.schema.json\",\n\n    \"visual\": {\n        \"progressBar\": \"rainbow\"\n    },\n    \"installBehavior\": {\n        \"preferences\": {\n            \"scope\": \"machine\"\n        }\n    },\n    \"source\": {\n        \"autoUpdateIntervalInMinutes\": 5\n    }\n}\n
","tags":["Windows"]},{"location":"windows/tools/wt.html","title":"Windows Terminal","text":"","tags":["Windows"]},{"location":"windows/tools/wt.html#install","title":"Install","text":"

microsoft/terminal

Download the latest release from https://github.com/microsoft/terminal/releases/latest

Install the MSIXBundle by starting a PowerShell with administratior rights:

PS> Add-AppxPackage Microsoft.WindowsTerminal_1.2.2381.0_8wekyb3d8bbwe.msixbundle\n

Or install via winget:

PS> winget install \"Windows Terminal\"\n
","tags":["Windows"]},{"location":"windows/tools/wt.html#configure","title":"Configure","text":"

Global configurations (copyOnSelect must be changed):

{\n\u00a0 \u00a0 \"disabledProfileSources\": [ \"Windows.Terminal.Azure\" ],\n\u00a0 \u00a0 \"theme\": \"dark\",\n\u00a0 \u00a0 \"launchMode\": \"maximized\",\n\n    // If enabled, selections are automatically copied to your clipboard.\n    \"copyOnSelect\": true\n}\n

Default settings for all profiles:

{\n    \"profiles\":\n    {\n\u00a0 \u00a0 \u00a0 \u00a0 \"defaults\":\n\u00a0 \u00a0 \u00a0 \u00a0 {\n            \"fontFace\": \"Hack NF\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"fontSize\" : 14,\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"cursorShape\": \"filledBox\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"colorScheme\": \"Tomorrow Night\"\n\u00a0 \u00a0 \u00a0 \u00a0 },\n        \"list\":\n        [\n        ]\n    }\n}\n

Add Cygwin bash:

            {\n                \"guid\": \"{a1f2ceb2-795d-4f2a-81cc-723cceec49c0}\",\n                \"name\": \"Cygwin bash\",\n                \"commandline\": \"C:/cygwin/bin/bash.exe -i -l\",\n                \"icon\": \"C:/cygwin/Cygwin-Terminal.ico\",\n                \"hidden\": false\n            },\n

Add startingDirectory for all WSL entries:

      {\n                \"startingDirectory\": \"//wsl$/Ubuntu-20.04/home/ti5cw\"\n      }\n

Define the Tomorrow Night color theme:

{\n\u00a0 \u00a0 \"schemes\": [\n\u00a0 \u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"name\": \"Tomorrow Night\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"black\": \"#000000\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"red\": \"#cc6666\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"green\": \"#b5bd68\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"yellow\": \"#f0c674\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"blue\": \"#81a2be\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"purple\": \"#b294bb\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"cyan\": \"#8abeb7\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"white\": \"#ffffff\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"brightBlack\": \"#000000\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"brightRed\": \"#cc6666\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"brightGreen\": \"#b5bd68\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"brightYellow\": \"#f0c674\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"brightBlue\": \"#81a2be\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"brightPurple\": \"#b294bb\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"brightCyan\": \"#8abeb7\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"brightWhite\": \"#ffffff\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"background\": \"#1d1f21\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"foreground\": \"#c5c8c6\"\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 ]\n}\n

Change keyboard shortcuts:

{\n    \"actions\":\n    [\n        // Change binding from Ctrl+= to Ctrl+\u00df\n        { \"command\": { \"action\": \"adjustFontSize\", \"delta\": 1 }, \"keys\": \"ctrl+\u00df\" }\n    ]\n}\n
","tags":["Windows"]},{"location":"windows/tools/wt.html#shortcuts","title":"Shortcuts","text":" ","tags":["Windows"]},{"location":"writing/index.html","title":"Writing","text":""},{"location":"writing/latex/truetype-fonts.html","title":"TrueType Fonts","text":"

http://tug.ctan.org/tex-archive/info/german/MiKTeX-WinEdt-TrueType-Anleitung/ttf.htm

"},{"location":"writing/mkdocs/index.html","title":"Material for MkDocs","text":""},{"location":"writing/mkdocs/admontion.html","title":"Admonition","text":""},{"location":"writing/mkdocs/admontion.html#setup","title":"Setup","text":"
markdown_extensions:\n  - admonition\n  - pymdownx.details\n
"},{"location":"writing/mkdocs/admontion.html#examples","title":"Examples","text":"Note

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

Note

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

With title

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

abstract summary tldr

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

info todo

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

tip hint important

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

success check done

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

question help faq

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

warning caution attention

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

failure fail missing

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

danger error

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

Bug

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

example snippet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

quote site

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

"},{"location":"writing/mkdocs/definition.html","title":"Definition List","text":""},{"location":"writing/mkdocs/definition.html#setup","title":"Setup","text":"
markdown_extensions:\n  - def_list\n
"},{"location":"writing/mkdocs/definition.html#examples","title":"Examples","text":"Lorem ipsum dolor sit amet Sed sagittis eleifend rutrum. Donec vitae suscipit est. Nullam tempus tellus non sem sollicitudin, quis rutrum leo facilisis. Cras arcu libero Aliquam metus eros, pretium sed nulla venenatis, faucibus auctor ex. Proin ut eros sed sapien ullamcorper consequat. Nunc ligula ante.

Duis mollis est eget nibh volutpat, fermentum aliquet dui mollis. Nam vulputate tincidunt fringilla. Nullam dignissim ultrices urna non auctor.

"},{"location":"writing/mkdocs/formatting.html","title":"Formatting","text":""},{"location":"writing/mkdocs/formatting.html#critic","title":"Critic","text":""},{"location":"writing/mkdocs/formatting.html#setup","title":"Setup","text":"
markdown_extensions:\n  - pymdownx.critic:\n      mode: view\n
"},{"location":"writing/mkdocs/formatting.html#examples","title":"Examples","text":"

Highlight a complete paragraph

"},{"location":"writing/mkdocs/formatting.html#caret-mark-tilde","title":"Caret, Mark & Tilde","text":""},{"location":"writing/mkdocs/formatting.html#setup_1","title":"Setup","text":"
markdown_extensions:\n  - pymdownx.caret\n  - pymdownx.mark\n  - pymdownx.tilde\n
"},{"location":"writing/mkdocs/formatting.html#example","title":"Example","text":""},{"location":"writing/mkdocs/formatting.html#keyboard","title":"Keyboard","text":""},{"location":"writing/mkdocs/formatting.html#setup_2","title":"Setup","text":"
markdown_extensions:\n  - pymdownx.keys\n
"},{"location":"writing/mkdocs/formatting.html#examples_1","title":"Examples","text":""},{"location":"writing/mkdocs/icons.html","title":"Icons & Emojis","text":""},{"location":"writing/mkdocs/icons.html#setup","title":"Setup","text":"
markdown_extensions:\n  - attr_list\n  - pymdownx.emoji:\n      emoji_index: !!python/name:material.extensions.emoji.twemoji\n      emoji_generator: !!python/name:material.extensions.emoji.to_svg\n
"},{"location":"writing/mkdocs/icons.html#examples","title":"Examples","text":"

There is a search in all available icons under https://squidfunk.github.io/mkdocs-material/reference/icons-emojis/.

Available Icons/Emojis:

"},{"location":"writing/mkdocs/images.html","title":"Images / Badges","text":""},{"location":"writing/mkdocs/images.html#examples","title":"Examples","text":"

Foobar Foobar

"},{"location":"writing/mkdocs/magiclink.html","title":"Magic Link","text":""},{"location":"writing/mkdocs/magiclink.html#setup","title":"Setup","text":"
extra_css:\n  - assets/css/extra-5ee9fa49a5.css\n\nmarkdown_extension:\n  - pymdownx.magiclink:\n      repo_url_shortener: true\n      repo_url_shorthand: true\n
"},{"location":"writing/mkdocs/markdown.html","title":"Markdown","text":""},{"location":"writing/mkdocs/markdown.html#emphasis","title":"Emphasis","text":"

is*bold*is is_bold_is is**bold**is is__bold__is is***bold***is is___bold___is

"},{"location":"writing/mkdocs/markdown.html#table","title":"Table","text":"A B C A B C AA BB CC AAA BBB CCC"},{"location":"writing/mkdocs/markdown.html#nested-lists","title":"Nested Lists","text":""},{"location":"writing/mkdocs/markdown.html#setup","title":"Setup","text":"

Using Mdx Truly Sane Lists.

Needs to be added into requirements.txt: mdx_truly_sane_lists

markdown_extensions:\n  - mdx_truly_sane_lists:\n      nested_indent: 2\n      truly_sane: true\n
"},{"location":"writing/mkdocs/markdown.html#example","title":"Example","text":"

GitHub indention

LayoutMarkdown
* Level 1 (GitHub)\n  * Level 2\n    * Level 3\n  * Level 2\n

Standard indention

LayoutMarkdown

Standanrd indention is not valid any more.

* Level 1 (Standard)\n    * Level 2\n        * Level 3\n    * Level 2\n
"},{"location":"writing/mkdocs/mermaid.html","title":"Mermaid","text":""},{"location":"writing/mkdocs/mermaid.html#setup","title":"Setup","text":"
markdown_extension:\n  - pymdownx.superfences:\n      custom_fences:\n        - name: mermaid\n          class: mermaid\n          format: !!python/name:pymdownx.superfences.fence_code_format\n
"},{"location":"writing/mkdocs/mermaid.html#examples","title":"Examples","text":"
graph TD;\nA --> B;\nA --> C;\nB --> D;\nC --> D;
graph TD\nA[Hard] -->|Text| B(Round)\nB --> C{Decision}\nC -->|One| D[Result 1]\nC -->|Two| E[Result 2]
"},{"location":"writing/mkdocs/source.html","title":"Source","text":""},{"location":"writing/mkdocs/source.html#setup","title":"Setup","text":"
theme:\n  features:\n    - content.code.annotate # (1)!\n    - content.code.copy # (2)!\n\nmarkdown_extensions:\n  - pymdownx.highlight:\n      anchor_linenums: true\n      line_spans: __span\n      pygments_lang_class: true\n  - pymdownx.inlinehilite\n  - pymdownx.snippets\n  - pymdownx.superfences\n
  1. Important for code annotations
  2. Enable code copy button
"},{"location":"writing/mkdocs/source.html#examples","title":"Examples","text":"

Code with highlighting:

def example(param):\n    print(f'param = {param}')\n

Using snippets:

LayoutMarkdown hello_world.c
#include<stdio.h>\n#include<stdlib.h>\n\n/*\n * Hello World\n */\nint main(int argc, char *argv[]) {\n  int a = 5;\n  int b = 4.3;\n\n  printf(\"Hello World!\\n\");\n\n  return EXIT_SUCCESS;\n}\n
``` c title=\"hello_world.c\"\n--8<-- \"writing/mkdocs/hello_world.c\"\n```\n

The filename is under the directory base_path configured in mkdocs.yaml:

markdown_extensions:\n  - pymdownx.snippets:\n      base_path: snippets/\n

The directory should be outside of docs/.

More examples can be found in the documentation.

Using annotations:

LayoutMarkdown
// Simple example\nint main(int argc, char* argv[])\n{\n  int a = 42; // The answer (1)\n  return EXIT_SUCCESS; // (2)!\n}\n
  1. to everything.
  2. Annotation with stripping comments
``` c\n// Simple example\nint main(int argc, char *argv[])\n{\n  int a = 42;          // The answer (1)\n  return EXIT_SUCCESS; // (2)!\n```\n\n1.  to everthing\n2.  Annotation with stripping comments\n

For each code annotation a link can be set (example).

"},{"location":"writing/mkdocs/task.html","title":"Task List","text":""},{"location":"writing/mkdocs/task.html#setup","title":"Setup","text":"
markdown_extensions:\n  - pymdownx.tasklist:\n      custom_checkbox: true\n
"},{"location":"writing/mkdocs/task.html#examples","title":"Examples","text":""},{"location":"blog/archive/2023.html","title":"2023","text":""},{"location":"blog/category/tools.html","title":"Tools","text":""},{"location":"blog/category/unix.html","title":"UNIX","text":""},{"location":"blog/category/windows.html","title":"Windows","text":""},{"location":"blog/category/neovim.html","title":"Neovim","text":""},{"location":"blog/category/latex.html","title":"LaTeX","text":""},{"location":"tags.html","title":"Tags","text":"

Following is a list of relevant tags:

"},{"location":"tags.html#homeassistant","title":"HomeAssistant","text":""},{"location":"tags.html#proxmox","title":"Proxmox","text":""},{"location":"tags.html#truenas","title":"TrueNAS","text":""},{"location":"tags.html#ubuntu","title":"Ubuntu","text":""},{"location":"tags.html#windows","title":"Windows","text":""},{"location":"tags.html#yaml","title":"YAML","text":""},{"location":"tags.html#bash","title":"bash","text":""},{"location":"tags.html#tmux","title":"tmux","text":""}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"index.html","title":"Overview","text":"

This Wiki is stored in the GitHub repository dreknix/wiki and can be found on GitHub pages.

"},{"location":"tags.html","title":"Tags","text":"

Following is a list of relevant tags:

"},{"location":"tags.html#homeassistant","title":"HomeAssistant","text":""},{"location":"tags.html#proxmox","title":"Proxmox","text":""},{"location":"tags.html#truenas","title":"TrueNAS","text":""},{"location":"tags.html#ubuntu","title":"Ubuntu","text":""},{"location":"tags.html#windows","title":"Windows","text":""},{"location":"tags.html#yaml","title":"YAML","text":""},{"location":"tags.html#bash","title":"bash","text":""},{"location":"tags.html#tmux","title":"tmux","text":""},{"location":"blog/index.html","title":"Blog","text":"

The RSS feed of the blog is created by the MkDocs RSS plugin.

"},{"location":"blog/index.html#articles","title":"Articles","text":""},{"location":"blog/2023/11/21/enable-gx-in-nvchad.html","title":"Enable gx in NvChad","text":"

The command gx opens the filename under the the cursor with vim.ui.open() (see :help netrw-gx). Then handling is provided by the internal netrw plugin. This plugin is disabled when using NvChad.

NvChad is using nvim-tree/nvim-tree.lua. In the configuration of this plugin, NvChad disables netrw, but allows the usage of netrw by the hijacking setup option (see lua/plugins/configs/nvimtree.lua).

This options will allow the usage of gx. But NvChad also disables the plugin in the configuration of the plugin manager folke/lazy.nvim. The netrw plugin is disabled with the option performance.rtp.disabled_plugins in the file plugins/configs/lazy_nvim.lua.

To enable the gx command the entry netrwPlugin must be removed from this option. But the configuration mechanism in NvChad allows only to overwrite an option. Therefore the most straightforward way is to overwrite the option with the complete list without netrwPlugin in custom/chadrc.lua:

chadrc.lua
local M = {}\nM.lazy_vim = {\n  performance = {\n    rtp = {\n      disabled_plugins = {\n        \"2html_plugin\",\n        ...\n        \"ftplugin\",\n      }\n    }\n  }\n}\nreturn M\n

The drawback of this method is, that whenever the NvChad configuration is changed, this list must be updated.

The better solution is to load the list and remove the favored plugins:

chadrc.lua
local M = {}\n-- load default list of disabled plugins in NvChad\nlocal default = require('plugins.configs.lazy_nvim')\nlocal default_disabled_plugins = default.performance.rtp.disabled_plugins\n\n-- specify which plugins should be removed from default disabled list\nlocal enabled = {\n  netrwPlugin = true,\n}\n-- enable those plugins\nlocal i=1\nwhile i <= #default_disabled_plugins do\n    if enabled[default_disabled_plugins[i]] then\n        table.remove(default_disabled_plugins, i)\n    else\n        i = i + 1\n    end\nend\n\nM.lazy_nvim = {\n  performance = {\n    rtp = {\n      disabled_plugins = default_disabled_plugins,\n    },\n  },\n}\nreturn M\n

Info

When you only want to use the gx command, there are other solutions like using a separate plugin, e.g., chrishrb/gx.nvim. This is also an example, how to overwrite configuration settings by removing an option in NvChad.

Tip

A table can be printed with the following commands:

print(vim.inspect(require('plugins.configs.lazy_nvim')))\nprint(vim.inspect(default_disabled_plugins))\n
"},{"location":"blog/2023/11/20/finding-glyph-in-fonts.html","title":"Finding Glyph in Fonts","text":"

Sometimes it is necessary to find fonts that contain a specific glyph. The tool albatross can be used for that task.

Finding a font by providing the glyph Snowman Emoji:

albatross \u2603\n

Finding a font by providing the code of the glyph in multiset union notation:

albatross U+2603\n

A detailed description of all options can be found in the CTAN package documentation or albatross(1).

Possible Unicode characters and their code point can be searched on symbl.cc.

Info

On Debian or Ubuntu the tool is part of the package texlive-font-utils. The command is not available. Instead the following command can be used:

java -jar /usr/share/texlive/texmf-dist/scripts/albatross/albatross.jar 0x2603\n
"},{"location":"blog/2023/11/20/imap-based-authentication-in-php.html","title":"IMAP-based Authentication in PHP","text":"

When using IMAP-based user authentication in applications written in PHP (i.e. Nextcloud, DokuWiki, etc.), debugging with a test script is essential. The idea of using curl for authentication, is based on the external user authentication plugin (see: nextcloud/user_external) of Nextcloud.

imap-test.php
#!/usr/bin/env php\n<?php\n$version = phpversion();\nprint(\"Current PHP version: {$version}\\n\");\n\n$url = 'imaps://imap.example.org:993';\n$email = 'user@example.org';\n$password = 'password'; # password must be in '...'\n\n$ch = curl_init();\n\n# see: https://www.php.net/manual/en/function.curl-setopt.php\ncurl_setopt($ch, CURLOPT_URL, $url);\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_USERPWD, \"{$email}:{$password}\");\ncurl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);\n\n# equal to: curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'CAPABILITY');\ncurl_setopt($ch, CURLOPT_CONNECT_ONLY, true);\n\n# get more debug information\ncurl_setopt($ch, CURLOPT_CERTINFO, true);\ncurl_setopt($ch, CURLOPT_VERBOSE, true);\n\nprint(\"Connecting to: {$url}\\n\");\ncurl_exec($ch);\n\n$errorcode = curl_errno($ch);\n\nif ($errorcode === 0) {\n  print(\"OK\\n\");\n} else if ($errorcode === 67) {\n  print(\"ERROR(\" . $errorcode . \"): Login denied! Wrong credentials?\\n\");\n} else {\n  print(\"ERROR(\" . $errorcode . \"): \" . curl_error($ch) . \"\\n\");\n}\n?>\n

Tip

It is important to use the same PHP version for testing, as used for the application. To ensure the correct version Docker/Podman can be used.

docker run -it --rm \\\n           --name php-test \\\n           -v \"./imap-test.php:/work/imap-test.php\" \\\n           -w /work php:8.2-cli \\\n           php imap-test.php\n
"},{"location":"blog/2023/12/04/qemu-and-windows-keys.html","title":"QEMU and Windows Keys","text":"

OEM Windows keys are often stored in the software licensing (SLIC) or Microsoft data management (MSDM) table. When a key is stored the unattended installation can use a generic key and the stored key is than used and activated. The usage of such a key can be tested with QEMU/libvirt.

The SLIC or MSDM table can be read via the Advanced Configuration and Power Interface (ACPI) in Linux. To read the Windows license key the following command can be used:

egrep -ao '[[:alnum:]-]{29}' /sys/firmware/acpi/tables/MSDM\n

Under Windows the following PowerShell snippet can be used to extract the license key:

Get-CimInstance -query 'select * from SoftwareLicensingService'\n

The key is stored in the OA3xOriginalProductKey attribute.

The table file needs to be stored in /usr/share/seabios/ due to AppArmor. If the file is not stored in this directory, a permission denied error is thrown. The MSDM (or SLIC) table is included by using additional QEMU parameters:

<qemu:commandline>\n  <qemu:arg value='-acpitable'/>\n  <qemu:arg value='file=/usr/share/seabios/MSDM'/>\n</qemu:commandline>\n

In order to \"simulate\" the OEM hardware the system management BIOS (SMBIOS) can be used:

<qemu:commandline>\n<qemu:arg value='-smbios'/>\n<qemu:arg value='type=0,version=??,date=??'/>\n<qemu:arg value='-smbios'/>\n<qemu:arg value='type=1,manufacturer=??,product=??,version=??,serial=??,uuid=??,sku=??,family=??'/>\n

The concrete values can be extracted with the dmidecode tool:

dmidecode -t 0\ndmidecode -t 1\n

The embedded license key can be activated with the following commands. First the key is read from the SLIC or MSDM table and than stored in Windows. The last command activates the license key:

$key = (Get-CimInstance -query 'select * from SoftwareLicensingService').OA3xOriginalProductKey\ncscript.exe \"$env:SystemRoot\\System32\\slmgr.vbs\" /ipk \"$key\"\ncscript.exe \"$env:SystemRoot\\System32\\slmgr.vbs\" /ato\n
"},{"location":"blog/2023/11/22/using-spice-with-truenas-scale-cobia-2310.html","title":"Using SPICE with TrueNAS Scale Cobia (23.10)","text":"

TrueNAS Scale Cobia (23.10) disabled the option to access VM displays via VNC. The connection method is changed to SPICE.

There are many different clients, which support Spice. Under Debian the tool Remmina is available that is a GTK-based remote desktop client. This tool supports many different protocols: RDP, VNC, SPICE, X2Go, SSH, etc. Some of the protocols, i.e. SPICE, are only available via additional plugins.

To install Remina with the SPICE plugin (the RDP and VNC plugins are installed by default):

sudo apt install remmina remmina-plugin-spice\n

When Remina is installed, you can connect to the server via the SPICE protocol:

remmina spice://server.example.org\n

If multiple VMs are running the different ports can be found in the details of the display device.

Tip

If a VM was created before version 23.10 the display of the VM must be deleted and newly created. Since version 23.10 only the SPICE protocol is available and password, which protects the connection, must be set.

Sometimes the VM must use UEFI in order to work properly with the SPICE protocol.

"},{"location":"blog/2023/11/20/using-tex-files-in-vi.html","title":"Using TeX files in Vi","text":"

In Vim/Neovim the filetype plugin uses three different type for different TeX flavors (see :help ft-tex-plugin).

Which filetype the current buffer was assigned, can be shown with :set filetype? (or :LspInfo if LSP is enabled).

All files with the extension *.tex are of type plaintex. When the file type plugin finds specific keywords the file type is than changed to tex or context.

The automatic guessing can be disabled with the following two mechanisms.

Add the TeX flavor in the first line of a *.tex file:

%&latex\n

Or set the global variable tex_flavor:

VimNeovim
let g:tex_flavour = \"latex\"\n
vim.g.tex_flavor = 'latex'\n

See :help lua-guide-variables for more information about the Lua wrappers for different variable scopes.

"},{"location":"blog/2023/12/11/zram-and-swap.html","title":"zram and Swap","text":"

The zram kernel module creates compressed RAM-based block devices named /dev/zramX. These zram devices allow fast I/O and the compression provides RAM space savings.

"},{"location":"blog/2023/12/11/zram-and-swap.html#install-zram","title":"Install zram","text":"

Install zram in Debian:

sudo apt install zram-tools\n

In order to enable zram, the computer needs to be rebooted.

"},{"location":"blog/2023/12/11/zram-and-swap.html#configure-zram","title":"Configure zram","text":"

The status of the zram module can be queried with systemctl status zramswap.service. The configuration and usage can be shown with zramctl:

$ zramctl\nNAME       ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT\n/dev/zram0 lz4           256M   4K   63B   20K       8 [SWAP]\n

Change the configuration parameters by editing the file /etc/default/zramswap:

ALGO=zstd\nPERCENT=25\n

The will change the default compression algorithm from lz4 to zstd and the default size from 256 MiB to 25 % of the total RAM.

$ zramctl\nNAME       ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT\n/dev/zram0 zstd          7.8G   4K   59B   20K       8 [SWAP]\n

If the computer has a configured swap file or swap partition, the zram swap gets a higher priority (100) instead of the default of -2:

$ swapon\nNAME       TYPE      SIZE USED PRIO\n/dev/dm-2  partition   4G   0B   -2\n/dev/zram0 partition 7.8G   0B  100\n

When the computer uses suspend to disk, a swap file or swap partition is needed besides zram.

"},{"location":"ha/index.html","title":"Home Assistent","text":"","tags":["HomeAssistant"]},{"location":"ha/index.html#first-steps","title":"First Steps","text":"

TODO: see video

","tags":["HomeAssistant"]},{"location":"ha/devices.html","title":"Devices","text":"","tags":["HomeAssistant"]},{"location":"ha/devices.html#shelly-plug-s","title":"Shelly Plug S","text":"

Shelly Plug S can be used with the Tasmota firmware.

Connect to Wifi SSID of Shelly Plug S and connect to web interface http://192.168.33.1/ and configure local wifi network.

Install the firmware:

http://shellyip/ota?url=http://ota.tasmota.com/tasmota/shelly/mg2tasmota-ShellyPlugS.zip\n

Connect to Tasmota Wifi SSID and configure the plug. After that open the URL http://shellyip/.

Configure template (Configure > Configure Other):

{\"NAME\":\"Shelly Plug S\",\"GPIO\":[57,255,56,255,0,134,0,0,131,17,132,21,0],\"FLAG\":2,\"BASE\":45}\n

Configure device (Configure > Configure Module):

BlitzWolf SHP (45)\n

Configure MQTT (Configure > Configure MQTT:

Calibrate the device (with readings of 235V and 35W):

savedata 1\nVoltageSet 235\nPowerSet 35.0\nsavedata 0\n

The information can be found in this video.

","tags":["HomeAssistant"]},{"location":"ha/videos.html","title":"Videos","text":"","tags":["HomeAssistant"]},{"location":"ha/videos.html#first-steps","title":"First Steps","text":"","tags":["HomeAssistant"]},{"location":"ha/videos.html#templates","title":"Templates","text":"","tags":["HomeAssistant"]},{"location":"hardware/index.html","title":"Hardware","text":""},{"location":"hardware/framework.html","title":"Framework 13 AMD","text":"

Framework 13 AMD

"},{"location":"hardware/framework.html#debian-13-trixie-testing","title":"Debian 13 trixie (testing)","text":"

Basic installation from network installer (netisnt) ISO image with disk encryption and btrfs flat volume layout.

After the first reboot tweak the fresh installation.

"},{"location":"hardware/framework.html#install-missing-firmware","title":"Install Missing Firmware","text":""},{"location":"hardware/framework.html#mediatek-mt7922","title":"MEDIATEK MT7922","text":"

Install mt7921e for MEDIATEK MT7922 802.11ax Wireless Network Adapter:

sudo apt install firmware-misc-nonfree\n
"},{"location":"hardware/framework.html#amd-radeon-780m","title":"AMD Radeon 780M","text":"

The package firmware-amd-graphics must not be installed:

sudo apt purge firmware-amd-graphics\n

Downloading specific firmware is described in the Debian Wiki.

` console mkdir firmware cd firmware/ wget -r \\ -nd \\ -e robots=no \\ -A '*.bin' \\ --accept-regex '/plain/' \\ https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/amdgpu/ sudo mkdir /lib/firmware/amdgpu/ sudo mv *.bin /lib/firmware/amdgpu/ sudo update-initramfs -c -k all

"},{"location":"hardware/lenovo.html","title":"Lenovo ThinkPad","text":""},{"location":"hardware/lenovo.html#firmware-update","title":"Firmware Update","text":"

Download boot ISO image from Lenovo support.

Extract image from ISO:

$ geteltorito -o e480.img ~/Downloads/r0puj37wd.iso\n

Get the device of the USB stick with lsblk. And write the image to the USB stick.

$ sudo dd if=e480.img of=/dev/sdb bs=64K\n
"},{"location":"hardware/nuc11atkc4.html","title":"NUC 11 Essential Kit","text":""},{"location":"hardware/nuc11atkc4.html#boot","title":"Boot","text":""},{"location":"hardware/nuc11atkc4.html#debian-11-bullseye","title":"Debian 11 - bullseye","text":""},{"location":"hardware/nuc11atkc4.html#firmware","title":"Firmware","text":"

The following package must be installed:

$ sudo apt install firmware-linux-nonfree firmware-realtek firmware-iwlwifi\n
"},{"location":"hardware/nuc11atkc4.html#luks-dropbear","title":"LUKS - Dropbear","text":"
$ sudo apt install dropbear-initramfs\n

Create /etc/dropbear-initramfs/authorized_keys and update the initramfs.

$ sudo update-initramfs -u\n

Unlock the LUKS encryption: cryptroot-unlook

"},{"location":"hardware/nuc11atkc4.html#dmidecode","title":"dmidecode","text":"
$ sudo dmidecode -s system-product-name\nNUC11ATKC4\n$ sudo dmidecode -s system-serial-number\nXXXXXXXXXXXX\n$ sudo dmidecode -s bios-version\nATJSLCPX.0037.2022.0715.1547\n
"},{"location":"tools/container/debugging.html","title":"Debugging Slim Containers","text":"

In order to debug a slim or distroless container the Nixery can be used.

Start a simple slim container:

$ docker run --rm -p 8080:80 --name slim-container traefik/whoami\n

Attach a debug container based on Nixery (with the packages ps, tree, and vim) to the slim container namespaces pid and network.

$ docker run \\\n           -it --rm \\\n           --name debugger \\\n           --pid container:slim-container \\\n           --network container:slim-container \\\n           nixery.dev/shell/ps/tree/vim \\\n           bash\n

Now the processes of the slim container are visible.

# ps -e\nUID          PID    PPID  C STIME TTY          TIME CMD\n0              1       0  0 18:28 ?        00:00:00 /whoami\n0             18       0  0 18:29 pts/0    00:00:00 bash\n0             24      18  0 18:30 pts/0    00:00:00 ps -ef\n#\n

The filesystem of the slim container is visible under /proc/1/root.

# ls /proc/1/root\ndev  etc  proc  sys  usr  whoami\n#\n

To work directly on the filesystem of the slim container you need to chroot into /proc/1/root. In order to use the tools from the Nixery image the directories /bin and /nix must be accessible from the filesystem of the slim container. This can only be achieved via the /proc filesystem.

# ln -s /proc/$$/root/bin /proc/1/root/nix-bin\n# ln -s /proc/$$/root/nix /proc/1/root/nix\n# export PATH=${PATH}:/nix-bin\n# chroot /proc/1/root /nix-bin/bash\n

Now you can debug a running slim container from within and use every tool you like.

Note

iximiuz/cdbug

A tool for container debugging. Based on the ideas descripted in the blog post \"Docker: How To Debug Distroless And Slim Containers\" from Ivan Velichko

Note

At DockerCon 2023 docker debug was announced.

"},{"location":"tools/container/baseimages/nixery.html","title":"Nixery","text":"

Nixery is acontainer image registry that provides small base images with only the packages specified in the URL, separated by slashes.

When the first element is shell than the bash and coreutils are part of the image. After that packages from the Nix package manager can be added. Any package available at https://search.nixos.org/packages can be installed.

The following command starts a shell in a container based on a Nixery image that contains the coreutils with bash and the packages git and python312.

$ docker run -it --rm nixery.dev/shell/git/python312 bash\n

Nixery can be used to debug slim containers.

"},{"location":"tools/vi/index.html","title":"Vi / Vim / Neovim","text":""},{"location":"tools/vi/index.html#general-informations","title":"General Informations","text":"

There are several starting point for informations:

"},{"location":"tools/vi/index.html#motions","title":"Motions","text":"

See: :help motion

"},{"location":"tools/vi/index.html#left-right-motions","title":"Left-Right Motions","text":"

See: :help left-right-motions

"},{"location":"tools/vi/index.html#up-down-motions","title":"Up-Down Motions","text":"

See: :help up-down-motions

"},{"location":"tools/vi/index.html#word-motions","title":"Word Motions","text":"

See: :help word-motions

"},{"location":"tools/vi/index.html#text-object-motions","title":"Text Object Motions","text":"

See: :help object-motions

"},{"location":"tools/vi/index.html#text-object-selection","title":"Text Object Selection","text":"

See: :help text-objects

"},{"location":"tools/vi/index.html#quickfix","title":"Quickfix","text":"

See: :help quickfix

The quickfix commands are used to work with a list of positions in files. A location list is a window-local quickfix list.

:vim word ** or :vim /pattern/ ** searches the word or pattern in all files recursively beneath the current directory. And opens the first location. After that the following commands are working on this quickfix list.

"},{"location":"tools/vi/index.html#commands-starting-with-g","title":"Commands starting with g","text":"

See: :help *g*

Jump through or work with changes:

"},{"location":"tools/vi/index.html#misc","title":"Misc","text":""},{"location":"tools/vi/index.html#search-in-key-mappings","title":"Search in Key Mappings","text":"

Besides the plugin Telescope the command :filter allows to search through all available key mappings.

Search for key mappings in insert mode:

:filter pattern imap\n

Search for key mappings in normal mode:

:filter pattern imap\n

To print the content of a mapping:

:verbose map <Leader>x\n
"},{"location":"tools/vi/index.html#clear-search-highlight","title":"Clear Search Highlight","text":"

With the option :hlsearch all matches of the last search are highlighted. To clear all highlights the command :nohlsearch can be used. Often this command is mapped to C-L. In NeoVim the following default mapping exists:

nnoremap <C-L> <Cmd>nohlsearch<Bar>diffupdate<Bar>normal! <C-L><CR>\n
"},{"location":"tools/vi/index.html#indenting-code","title":"Indenting Code","text":"

With == or = code can be formatted.

"},{"location":"tools/vi/index.html#avoid-wrong-formatting-during-paste","title":"Avoid Wrong Formatting During Paste","text":"

Set the configuration :set paste before pasting into Vi. Disable this option afterwards with :set nopaste.

"},{"location":"tools/vi/index.html#remove-lines-matching-a-pattern","title":"Remove Lines Matching a Pattern","text":""},{"location":"tools/vi/index.html#non-greedy-regular-expression","title":"Non-Greedy Regular Expression","text":"

See: :help non-greedy

{\n  \"key1\": \"valueA\",\n  \"key2\": \"valueB\"\n}\n

The regular expression \".*\" will select \"key1\": \"valueA\" because it is greedy. It tries to match as many as possible characters.

The regular expression \".\\{-\\}\" will select only \"key1\". It will match the fewest number of characters as possible. The last \\ is optional, so the expression \".\\{-}\" is also possible.

"},{"location":"tools/vi/vim.html","title":"Vim","text":"

mhinz/vim-galore

"},{"location":"tools/vi/vim.html#general","title":"General","text":"
\" enter current millenium\nset nocompatible\n\n\" enable syntax and plugins (for netrw)\nsyntax enable\nfiletype plugin on\n
"},{"location":"tools/vi/vim.html#finding-files","title":"Finding Files","text":"
\" search down into subfolders\n\" provides tab-completion for all file-related tasks\nset path+=**\n\n\" ignore different file types\nset wildignore+=*.aux,*.log,*.out,*.pdf,*.o\n\n\" ignore a specific folder\nset wildignore+=**/node_modules/**\n\n\" give suffixes a low priority (list at end)\nset suffixes+=.pdf\n\n\" display all matching files when we tab complete\nset wildmenu\n\n\" Hit tab to :find by partial match\n\" Use * to make it fuzzy\n\n\" :b lets you autocomplete any open buffer\n
"},{"location":"tools/vi/vim.html#autocomplete","title":"Autocomplete","text":"

More shortcuts can be found in |ins-completion|

\" ^x^n - for just this file\n\" ^x^f - for filenames\n\" ^x^] - for tags only\n\" ^n   - for anything by the 'complete' option\n\n\" move than with ^n and ^p in the suggestion list\n
"},{"location":"tools/vi/vim.html#spell-checking-and-word-completion","title":"Spell Checking and Word Completion","text":"
\" Spell-check language\nset spelllang=en_us\n\n\" Automatically set by plugin vim-markdown\n\"\" Define new filetype markdown\n\"autocmd BufRead,BufNewFile *.md set filetype=markdown\n\n\" Spell-check Markdown files\nautocmd FileType markdown setlocal spell\n\n\" Spell-check Git messages\nautocmd FileType gitcommit setlocal spell\n\n\" Set spellfile to location that is guaranteed to exist,\n\" can be symlinked to Dropbox or kept in Git\n\" and managed outside of thoughtbot/dotfiles using rcm.\nset spellfile=$HOME/.vim/spell-en.utf-8.add\n\n\" Autocomplete with dictionary words when spell check is on\nset complete+=kspell\n
"},{"location":"tools/vi/vim.html#file-browsing","title":"File Browsing","text":"
\" tweaks for browsing\nlet g:netrw_banner=0        \" disable annoying banner\nlet g:netrw_browse_split=4  \" open in prior window\nlet g:netrw_altv=1          \" open splits to the right\nlet g:netrw_liststyle=3     \" tree view\nlet g:netrw_list_hide=netrw_gitignore#Hide()\nlet g:netrw_list_hide.=',\\(^\\|\\s\\s\\)\\zs\\.\\S\\+'\n\n\" :edit a folder to open a file browser\n\" <CR>/v/t to open in an h-split/v-split/tab\n\" check |netrw-browse-maps| for more mappings\n
"},{"location":"tools/vi/vim.html#snippets","title":"Snippets","text":"
\" read an empty HTML template and move cursor to title\nnnoremap ,html :-1read $HOME/.vim/.skeleton.html<CR>3jwf>a\n
"},{"location":"tools/vi/vim.html#help","title":"Help","text":"
:help ^n    \" help about ctrl-n in normal mode\n:help i_^n  \" help about ctrl-n in insert mode\n:help c_^n  \" help about ctrl-n in command mode\n\n\" grep in help pages\n:helpgrep xxx\n
"},{"location":"tools/vi/vim.html#colorcolumn","title":"ColorColumn","text":"
set textwidth=80\nset colorcolumn=81\nhighlight ColorColumn ctermbg=0 guibg=lightgrey\n\n\" alternativ\nau BufWinEnter * let w:m2=matchadd('ErrorMsg', '\\%>80v.\\+', -1)\n
"},{"location":"tools/vi/neovim/index.html","title":"Neovim / NvChad","text":"

Neovim is a fork of Vim with builtin support for Language Server Protocol (LSP) and Lua scripting.

For Neovim different advanced configurations exists: LazyVim, LunarVim, AstroNvim, NvChad, ... In the following NvChad is used as the bases for the custom configuration.

"},{"location":"tools/vi/neovim/index.html#installupdate","title":"Install/Update","text":"

Install (Linux):

$ rm -rf ~/.config/nvim\n$ rm -rf ~/.local/share/nvim\n$ git clone https://github.com/NvChad/NvChad ~/.config/nvim --depth 1\n

Install (Windows):

PS> rd -r ~\\AppData\\Local\\nvim\nPS> rd -r ~\\AppData\\Local\\nvim-data\nPS> git clone https://github.com/NvChad/NvChad $HOME\\AppData\\Local\\nvim --depth 1\n

Update:

:NvChadUpdate\n
"},{"location":"tools/vi/neovim/index.html#key-mappings-and-commands","title":"Key Mappings and Commands","text":"

Note

In NvChad the leader key is Space.

"},{"location":"tools/vi/neovim/index.html#custom-config","title":"Custom Config","text":"

dreknix/tools-nvchad-config

~/.config/nvim/lua/custom/\n\u251c\u2500\u2500 init.lua\n\u251c\u2500\u2500 chadrc.lua\n\u251c\u2500\u2500 mappings.lua\n\u251c\u2500\u2500 plugins.lua\n\u251c\u2500\u2500 configs/\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 lspconfig.lua\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 overrides.lua\n\u251c\u2500\u2500 after/\n\u2514\u2500\u2500 snippets/\n
"},{"location":"tools/vi/neovim/index.html#config-files","title":"Config Files","text":"

Custom configuration files:

"},{"location":"tools/vi/neovim/index.html#after-directory","title":"After Directory","text":"

Specific settings for each file type can be found in after/ftplugin/<filetype>.lua.

"},{"location":"tools/vi/neovim/index.html#snippets","title":"Snippets","text":"

NvChad uses the following plugins for snippets:

The predefined snippets are installed in ~/.local/share/nvim/lazy/friendly-snippets/snippets/. Custom snippets are loaded in init.lua.

"},{"location":"tools/vi/neovim/chadrc_lua.html","title":"chardrc.lua","text":"

Content of ~/.config/nvim/lua/custom/chadrc.lua:

---@type ChadrcConfig\n local M = {}\n M.ui = {theme = 'catppuccin'}\n M.plugins = 'custom.plugins'\n M.mappings = require 'custom.mappings'\n return M\n
"},{"location":"tools/vi/neovim/configs_lspconfig_lua.html","title":"configs/lspconfig.lua","text":"

Configuration of the LSP servers can be found here.

The LSP configuration for the current buffer can be shown with :LspInfo. Often the file type (:set ft) must be set to the correct value. See vim.filetype.add in init.lua.

Content of ~/.config/nvim/lua/custom/configs/lspconfig.lua:

local base = require('plugins.configs.lspconfig')\n\nlocal on_attach = base.on_attach\nlocal capabilities = base.capabilities\n\nlocal lspconfig = require('lspconfig')\n\nlspconfig.clangd.setup({\n  on_attach = function (client, bufnr)\n    client.server_capabilities.signatureHelpProvider = false\n    on_attach(client, bufnr)\n  end,\n  capabilities = capabilities,\n})\n\nlspconfig.ansiblels.setup({\n  on_attach = on_attach,\n  capabilities = capabilities,\n})\n\nlspconfig.docker_compose_language_service.setup({\n  on_attach = on_attach,\n  capabilities = capabilities,\n  filetypes = {'yaml.docker-compose'},\n})\n\nlspconfig.dockerls.setup({\n  on_attach = on_attach,\n  capabilities = capabilities,\n})\n\nlspconfig.jsonls.setup({\n  on_attach = on_attach,\n  capabilities = capabilities,\n})\n\nlspconfig.marksman.setup({\n  on_attach = on_attach,\n  capabilities = capabilities,\n})\n\nlspconfig.yamlls.setup({\n  on_attach = on_attach,\n  capabilities = capabilities,\n  filetypes = {'yaml', 'yaml.ansible', 'yaml.docker-compose'},\n})\n\nlspconfig.pyright.setup({\n  on_attach = on_attach,\n  capabilities = capabilities,\n  filetypes = {'python'},\n})\n
"},{"location":"tools/vi/neovim/configs_overrides_lua.html","title":"configs/overrides.lua","text":"

Content of ~/.config/nvim/lua/custom/configs/overrides.lua:

--\n-- configure: williamboman/mason.nvim\n--\n\nM.mason = {\n  ensure_installed = {\n    -- lua stuff\n    'lua-language-server',\n    'stylua',\n\n    -- web dev stuff\n    'css-lsp',\n    'html-lsp',\n    'prettier',\n\n    -- c/cpp stuff\n    'clangd',\n    'clang-format',\n\n    -- shell stuff\n    'ansible-language-server',\n    'bash-language-server',\n    'docker-compose-language-service',\n    'dockerfile-language-server',\n    'jsonlint',\n    'marksman',\n    'yaml-language-server',\n\n    -- python stuff\n    'pyright',\n    'flake8',\n    'black',\n    'pylint',\n    'mypy',\n    'ruff',\n    'debugpy',\n  },\n}\n
--\n-- configure: nvim-treesitter/nvim-treesitter\n--\nM.treesitter = {\n  ensure_installed = {\n    'bash',\n    'c',\n    'cpp',\n    'css',\n    'git_config',\n    'git_rebase',\n    'gitcommit',\n    'gitignore',\n    'go',\n    'html',\n    'ini',\n    'java',\n    'javascript',\n    'jq',\n    'json',\n    'latex',\n    'lua',\n    'make',\n    'markdown',\n    'markdown_inline',\n    'mermaid',\n    'perl',\n    'php',\n    'python',\n    'sql',\n    'xml',\n    'yaml',\n  },\n  indent = {\n    enable = true,\n    -- disable = {\n    --   'python'\n    -- },\n  },\n}\n
--\n-- configure: nvim-tree/nvim-tree.lua\n--\n\nM.nvimtree = {\n  git = {\n    enable = true,\n  },\n\n  renderer = {\n    highlight_git = true,\n    icons = {\n      show = {\n        git = true,\n      },\n    },\n  },\n}\n
"},{"location":"tools/vi/neovim/configs_overrides_lua.html#_1","title":"configs/overrides.lua","text":""},{"location":"tools/vi/neovim/configs_overrides_lua.html#lukas-reinekeindent-blanklinenvim","title":"lukas-reineke/indent-blankline.nvim","text":"

Define other symbols for visualizing different whitespaces in list mode. The list mode is disabled by default. F2 is used to toogle list view (see mappings.lua). With the plugin variable show_end_of_line the character set defined by listchars is used.

vim.opt.list = false\nvim.opt.listchars:append({ tab   = '\u2192 ' })  -- u2192\nvim.opt.listchars:append({ eol   = '\u21b2'  })  -- u21b2\nvim.opt.listchars:append({ space = '\u00b7'  })  -- u00b7\nvim.opt.listchars:append({ nbsp  = '\u2423'  })  -- u2423\nvim.opt.listchars:append({ trail = '\u2610'  })  -- u2610\n\nM.blankline = {\n  show_end_of_line = true,\n}\n
"},{"location":"tools/vi/neovim/init_lua.html","title":"init.lua","text":"

General initialization of Neovim that is not handled by a plugin or NvChad.

"},{"location":"tools/vi/neovim/init_lua.html#general-settings","title":"General settings","text":"

Highlight the columns textwidth+0 and textwidth+20. The default value of textwidth is 80.

vim.opt.colorcolumn = '+0,+20'\n

TODO move to overrides or configs

-- LuaSnip uses rafamadriz/friendly-snippets\n-- extend in snipmate format\nvim.g.snipmate_snippets_path = vim.fn.stdpath \"config\" .. \"/lua/custom/snippets\"\n
"},{"location":"tools/vi/neovim/init_lua.html#file-types","title":"File Types","text":"

Add file types to specific file name patterns ( see vim.filetype). The file type yaml.docker-compose and yaml.ansible is used for choosing a more specific LSP server.

vim.filetype.add({\n  pattern = {\n    -- SSH config\n    ['.*/.ssh/config.d/.*'] = 'sshconfig',\n    -- rofi config\n    ['.*/.*.rasi'] = 'css',\n    -- Docker compose\n    ['compose.ya?ml'] = 'yaml.docker-compose',\n    ['docker-compose.ya?ml'] = 'yaml.docker-compose',\n    -- Ansible\n    ['.*/playbooks/.*.ya?ml'] = 'yaml.ansible',\n    ['.*/playbooks/.*/.*.ya?ml'] = 'yaml.ansible',\n    ['.*/roles/.*/tasks/.*.ya?ml'] = 'yaml.ansible',\n    ['.*/roles/.*/handlers/.*.ya?ml'] = 'yaml.ansible',\n  },\n})\n
"},{"location":"tools/vi/neovim/init_lua.html#securing-gopass","title":"Securing gopass","text":"

The tool gopass might use Neovim for editing secrets. Therefore, backup files or other external information storage must be disabled.

vim.api.nvim_create_autocmd({\"BufNewFile\", \"BufRead\"}, {\n  pattern = {'/dev/shm/gopass*'},\n  callback = function(ev)\n    vim.opt_local.swapfile = false\n    vim.opt_local.backup = false\n    vim.opt_local.undofile = false\n    vim.opt_local.shadafile = \"NONE\"\n  end\n})\n
"},{"location":"tools/vi/neovim/mappings_lua.html","title":"mappings.lua","text":"

Content of ~/.config/nvim/lua/custom/mappings.lua:

local M = {}\n\nM.general = {\n  n = {\n    -- switch between windows\n    [\"<A-Left>\"] = { \"<cmd> TmuxNavigateLeft<CR>\", \"Window left\" },\n    [\"<A-Right>\"] = { \"<cmd> TmuxNavigateRight<CR>\", \"Window right\" },\n    [\"<A-Down>\"] = { \"<cmd> TmuxNavigateDown<CR>\", \"Window down\" },\n    [\"<A-Up>\"] = { \"<cmd> TmuxNavigateUp<CR>\", \"Window up\" },\n  }\n}\n\nreturn M\n
"},{"location":"tools/vi/neovim/plugins_lua.html","title":"plugins.md","text":"

Overrides already loaded NvChad plugins:

Add LSP servers in configs/lspconfig.lua.

Add additional plugins:

Content of ~/.config/nvim/lua/custom/plugins.lua:

local overrides = require 'custom.configs.overrides'\n\nlocal plugins = {\n  {\n    'williamboman/mason.nvim',\n    opts = overrides.mason,\n  },\n  {\n    'nvim-treesitter/nvim-treesitter',\n    opts = overrides.treesitter,\n  },\n  {\n    'nvim-tree/nvim-tree.lua',\n    opts = overrides.nvimtree,\n  },\n  {\n    'lukas-reineke/indent-blankline.nvim',\n    opts = overrides.blankline,\n  },\n  {\n    'neovim/nvim-lspconfig',\n    config = function()\n      require 'plugins.configs.lspconfig'\n      require 'custom.configs.lspconfig'\n    end\n  },\n  {\n    'mfussenegger/nvim-lint',\n    event = 'VeryLazy',\n    config = function()\n      require 'custom.configs.lint'\n    end\n  },\n  {\n    'mhartington/formatter.nvim',\n    event = 'VeryLazy',\n    opts = function()\n      return require 'custom.configs.formatter'\n    end\n  },\n  {\n    'mfussenegger/nvim-dap',\n    config = function(_, opts)\n      require('core.utils').load_mappings('dap')\n    end\n  },\n  {\n    'rcarriga/nvim-dap-ui',\n    dependencies = 'mfussenegger/nvim-dap',\n    config = function()\n      local dap = require('dap')\n      local dapui = require('dapui')\n      dapui.setup()\n      dap.listeners.after.event_initialized['dapui_config'] = function()\n        dapui.open()\n      end\n      dap.listeners.before.event_terminated['dapui_config'] = function()\n        dapui.close()\n      end\n      dap.listeners.before.event_exited['dapui_config'] = function()\n        dapui.close()\n      end\n    end\n  },\n  {\n    'mfussenegger/nvim-dap-python',\n    ft = 'python',\n    dependencies = {\n      'mfussenegger/nvim-dap',\n      'rcarriga/nvim-dap-ui',\n    },\n    config = function(_, opts)\n      local path = '~/.local/share/nvim/mason/packages/debugpy/venv/bin/python'\n      require('dap-python').setup(path)\n      require('core.utils').load_mappings('dap_python')\n    end,\n  },\n  {\n    'christoomey/vim-tmux-navigator',\n    lazy = false,\n  }\n}\n\nreturn plugins\n
"},{"location":"unix/index.html","title":"UNIX","text":""},{"location":"unix/bash/index.html","title":"bash","text":"","tags":["bash"]},{"location":"unix/bash/yaml.html","title":"YAML and bash","text":"

Example yaml file:

---\nglobal:\n  input:\n    - \"main.c\"\n    - \"main.h\"\n  flags: [ \"-O3\", \"-fpic\" ]\n  sample_input:\n    -  { property1: value1, property2: value2 }\n    -  { property1: \"value 3\", property2: 'value 4' }\n  licence: |\n    this is published under\n    open source license\n    in the hope that it would\n    be useful\n...\n

The following variables are created:

global_input_1=\"main.c\"\nglobal_input_2=\"main.h\"\nglobal_flags_1=\"-O3\"\nglobal_flags_2=\"-fpic\"\nglobal_sample_input_1_property1=\"value1\"\nglobal_sample_input_1_property2=\"value2\"\nglobal_sample_input_2_property1=\"value 3\"\nglobal_sample_input_2_property2=\"value 4\"\nglobal_licence=\"this is published under\\nopen source license\\nin the hope that it would \\nbe useful\\n\"\n__=\" global\"\nglobal_=\" global_input global_flags global_sample_input global_licence\"\nglobal_flags_=\" global_flags_1 global_flags_2\"\nglobal_input_=\" global_input_1 global_input_2\"\nglobal_sample_input_=\" global_sample_input_1 global_sample_input_2\"\nglobal_sample_input_1_=\" global_sample_input_1_property1 global_sample_input_1_property2\"\nglobal_sample_input_2_=\" global_sample_input_2_property1 global_sample_input_2_property2\"\n

A list of variables can iterated with:

$ for f in $global_flags_ ; do eval echo \\$f \\$${f} ; done\nglobal_flags_1 -O3\nglobal_flags_2 -fpic\n
","tags":["bash","YAML"]},{"location":"unix/debian/index.html","title":"Debian","text":""},{"location":"unix/debian/install.html","title":"Installing Debian","text":""},{"location":"unix/debian/install.html#debian-13-trixie-testing","title":"Debian 13 trixie (testing)","text":"

The target of this Debian installation is a 2TB NVME (/dev/nvme0n1). LUKS is enabled for the main Linux and the swap partition. Additionally btrfs with a flat subvolume layout is used.

The target partition layout is:

/dev/nvme0n1p1 2.0 GB EFI System\n/dev/nvme0n1p2 4.0 GB ext4 (/boot)\n/dev/nvme0n1p3 1.9 TB LUKS encrypted (/)\n/dev/nvme0n1p4 94 GB  LUKS encrypted (swap)\n

Get the network installer from Debian as daily build.

Continue with installation via SSH:

Continue configuring Debian installer:

Exit to shell in order to change the btrfs and /tmp configuration.

~ # df -h\nFilesystem                Size      Used Available Use% Mounted on\ntmpfs                     3.1G    532.0K      3.1G   0% /run\ndevtmpfs                 15.3G         0     15.3G   0% /dev\n/dev/sda1               547.0M    547.0M         0 100% /cdrom\nnone                    147.9K     67.0K     75.9K  47% /sys/firmware/efi/efivars\n/dev/mapper/nvme0n1p3_crypt\n                          1.7T      5.8M      1.7T   0% /target\n/dev/nvme0n1p2            3.6G     28.0K      3.4G   0% /target/boot\n/dev/nvme0n1p1            1.9G      4.0K      1.9G   0% /target/boot/efi\n

Unmount the /target partitions:

~ # umount /target/boot/efi\n~ # umount /target/boot\n~ # umount /target\n

Mount the btrfs encrypted partition to /mnt:

~ # mount /dev/mapper/nvme0n1p3_crypt /mnt\n~ # cd /mnt/\n/mnt # ls\n@rootfs\n

Change the name of the root subvolume:

/mnt # mv @rootfs @\n

Create other subvolumes:

/mnt # btrfs subvolume create @snapshots\nCreate subvolume './@snapshots'\n/mnt # btrfs subvolume create @home\nCreate subvolume './@home'\n/mnt # btrfs subvolume create @var_cache\nCreate subvolume './@var_cache'\n/mnt # btrfs subvolume create @var_crash\nCreate subvolume './@var_crash'\n/mnt # btrfs subvolume create @var_log\nCreate subvolume './@var_log'\n/mnt # btrfs subvolume create @var_lib_accountsservice\nCreate subvolume './@var_lib_accountsService'\n/mnt # btrfs subvolume create @var_lib_gdm3\nCreate subvolume './@var_lib_gdm3'\n

Create the new mount structure under /target:

/mnt # cd /\n~ # mount -o noatime,compress=zstd:3,subvol=@ /dev/mapper/nvme0n1p3_crypt /target\n~ # mount /dev/nvme0n1p2 /target/boot/\n~ # mount /dev/nvme0n1p1 /target/boot/efi/\n~ # mkdir /target/.btrfs\n~ # mkdir /target/.snapshots\n~ # mkdir /target/home\n~ # mkdir /target/var\n~ # mkdir /target/var/cache\n~ # mkdir /target/var/crash\n~ # mkdir /target/var/log\n~ # mkdir /target/var/lib\n~ # mkdir /target/var/lib/AccountsService\n~ # mkdir /target/var/lib/gdm3\n~ # mount -o noatime,compress=zstd:3,subvol=@snapshots /dev/mapper/nvme0n1p3_crypt /target/.snapshots\n~ # mount -o noatime,compress=zstd:3,subvol=@home /dev/mapper/nvme0n1p3_crypt /target/home\n~ # mount -o noatime,compress=zstd:3,subvol=@var_cache /dev/mapper/nvme0n1p3_crypt /target/var/cache\n~ # mount -o noatime,compress=zstd:3,subvol=@var_crash /dev/mapper/nvme0n1p3_crypt /target/var/crash\n~ # mount -o noatime,compress=zstd:3,subvol=@var_log /dev/mapper/nvme0n1p3_crypt /target/var/log\n~ # mount -o noatime,compress=zstd:3,subvol=@var_lib_accountsservice /dev/mapper/nvme0n1p3_crypt /target/var/lib/AccountsService\n~ # mount -o noatime,compress=zstd:3,subvol=@var_lib_gdm3 /dev/mapper/nvme0n1p3_crypt /target/var/lib/gdm3\n

Info

The flags ssd and space_cache=v2 are enabled by default.

The flag discard=async is also not needed anymore. TODO

Unmount the btrfs partition:

~ # unmount /mnt\n

Edit the /target/etc/fstab file:

/dev/mapper/nvme0n1p3_crypt  /                         btrfs  noatime,compress=zstd:3,subvol=@                         0   0\n/dev/mapper/nvme0n1p3_crypt  /.snapshots               btrfs  noatime,compress=zstd:3,subvol=@snapshots                0   0\n/dev/mapper/nvme0n1p3_crypt  /home                     btrfs  noatime,compress=zstd:3,subvol=@home                     0   0\n/dev/mapper/nvme0n1p3_crypt  /var/cache                btrfs  noatime,compress=zstd:3,subvol=@var_cache                0   0\n/dev/mapper/nvme0n1p3_crypt  /var/crash                btrfs  noatime,compress=zstd:3,subvol=@var_crash                0   0\n/dev/mapper/nvme0n1p3_crypt  /var/log                  btrfs  noatime,compress=zstd:3,subvol=@var_log                  0   0\n/dev/mapper/nvme0n1p3_crypt  /var/lib/AccountsService  btrfs  noatime,compress=zstd:3,subvol=@var_lib_accountsservice  0   0\n/dev/mapper/nvme0n1p3_crypt  /var/lib/gdm3             btrfs  noatime,compress=zstd:3,subvol=@var_lib_gdm3             0   0\n\n/dev/mapper/nvme0n1p3_crypt  /.btrfs                   btrfs  noatime,compress=zstd:3,subvolid=5                       0   0\n

Info

Instead of device names the UUID of the partitions should be used. The get corresponding UUIDs use the command blkid.

Info

Optional: the directory /tmp can be configured as tmpfs. TODO Why systemd tmp.mount should currently not be used in Debian

Append the following line to /target/etc/fstab:

tmpfs   /tmp   tmpfs   nosuid,nodev,strictatime,size=4g,nr_inodes=1m,mode=1777   0   0\n

Create the directory and mount it for installation:

~ # mkdir /target/tmp\n~ # mount -t tmpfs -o nosuid,nodev,strictatime,size=4g,nr_inodes=1m,mode=1777 tmpfs /target/tmp\n

Exit the shell and continue with the installation process.

Continue configuring Debian installer:

Finished

"},{"location":"unix/debian/tweak.html","title":"Tweak the Fresh Installation","text":"

After the first reboot tweak the fresh installation.

"},{"location":"unix/debian/tweak.html#btrfs","title":"btrfs","text":"

Fix permissions for /.btrfs and /.snapshots:

sudo chown root:sudo /.btrfs /.snapshots\nsudo chmod 0750 /.btrfs /.snapshots\n

Install missing tools:

sudo apt install btrbk btrfs-compsize\n
"},{"location":"unix/debian/tweak.html#use-uuid-in-etcfstab","title":"Use UUID in /etc/fstab","text":"

Get with sudo blkid the UUIDs of each partition and use the UUID instead of the partition device name.

"},{"location":"unix/debian/tweak.html#luks","title":"LUKS","text":"

TODO unlock swap partition with file

"},{"location":"unix/debian/tweak.html#plymouth","title":"Plymouth","text":"

Activate plymouth during boot for LUKS prompt.

Add splash to GRUB_CMDLINE_LINUX_DEFAULT:

/etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT=\"quiet splash\"\n

Update GRUB configuration:

sudo update-grub2\n
"},{"location":"unix/debian/tweak.html#configure-zram","title":"Configure zram","text":"

TODO

"},{"location":"unix/debian/tweak.html#install-additional-packages","title":"Install additional Packages","text":"
sudo apt install lshw\n

TODO merge this with Ansible

"},{"location":"unix/debian/tweak.html#finalize-with-ansible","title":"Finalize with Ansible","text":"

TODO describe the steps

"},{"location":"unix/filesystems/index.html","title":"Filesystems","text":""},{"location":"unix/filesystems/btrfs.html","title":"btrfs","text":"

btrfs combines a filesystem with copy-on-write principles with a logical volume manager. The btrfs file system is marked as stable in the Linux kernel since 2013.

https://btrfs.readthedocs.io/

"},{"location":"unix/filesystems/btrfs.html#layout","title":"Layout","text":"

With the following layout booting a read-only snapshot is possible since all directories that needs to be writable are not part of the root file system subvolume:

/etc/fstab
UUID=...   /                          btrfs   noatime,compress=zstd:3,subvol=@                          0   0\nUUID=...   /.snapshots                btrfs   noatime,compress=zstd:3,subvol=@snapshots                 0   0\nUUID=...   /home                      btrfs   noatime,compress=zstd:3,subvol=@home                      0   0\nUUID=...   /var/cache                 btrfs   noatime,compress=zstd:3,subvol=@var_cache                 0   0\nUUID=...   /var/crash                 btrfs   noatime,compress=zstd:3,subvol=@var_crash                 0   0\nUUID=...   /var/log                   btrfs   noatime,compress=zstd:3,subvol=@var_log                   0   0\nUUID=...   /var/lib/AccountsService   btrfs   noatime,compress=zstd:3,subvol=@var_lib_accountsservice   0   0\nUUID=...   /var/lib/gdm3              btrfs   noatime,compress=zstd:3,subvol=@var_lib_gdm3              0   0\n\nUUID=...   /.btrfs                    btrfs   noatime,compress=zstd:3,subvolid=5                        0   0\n

Info

The directories /.btrfs and /.snapshots must be only accessible by the root user and the group sudo (for tab completion).

sudo chown root:sudo /.btrfs /.snapshots\nsudo chmod 0750 /.btrfs /.snapshots\n

Warning

Due to LUKS disk encryption the /boot directory is not part of the root file system subvolume. Do not delete any kernels that are needed to boot an old snapshot.

Depending on the usage of the computer, other subvolumes are also needed:

/etc/fstab
UUID=...   /var/lib/docker            btrfs   noatime,compress=zstd:3,subvol=@var_lib_docker            0   0\nUUID=...   /var/lib/container         btrfs   noatime,compress=zstd:3,subvol=@var_lib_container         0   0\nUUID=...   /var/lib/libvirt           btrfs   noatime,compress=zstd:3,subvol=@var_lib_libvirt           0   0\n\nUUID=...   /srv                       btrfs   noatime,compress=zstd:3,subvol=@srv                       0   0\n
"},{"location":"unix/filesystems/btrfs.html#snapshots","title":"Snapshots","text":""},{"location":"unix/filesystems/btrfs.html#create-snapshots","title":"Create Snapshots","text":"

Create a snapshot from a subvolume:

sudo btrfs subvolume snapshot /path/to/volume /path/to/snapshot\n

The snapshot is writable by default. A read-only snapshot can be created with the additional -r option.

"},{"location":"unix/filesystems/btrfs.html#read-only-snapshots","title":"Read-only Snapshots","text":"
$ sudo btrfs property get -t subvol /path/to/snapshot\nro=true\n

Make snapshot writeable:

sudo btrfs property set -ts /path/to/snapshot ro false\n
"},{"location":"unix/filesystems/btrfs.html#rollback","title":"Rollback","text":"

First boot to the last working snapshot. If you have grub-btrfs installed, you can choose the snapshot from the boot menu. Or you can add the snapshot as a kernel option.

Normally btrfs adds the following option the kernel (during update-grub2):

rootflags=subvol=@\n

To select a different snapshot change the option during boot (press e in the GRUB menue) to:

rootflags=subvolid=<id>\n

Now the snapshot is used as rootfs. Due to the chosen layout even a read-only snapshot (i.e., create by btrbk) can be booted.

After the system was successfully booted, check if the right snapshot is mounted:

$ mount | grep \" / \"\n/dev/mapper/vda3_crypt on / type btrfs (rw,noatime,compress=zstd:3,discard=async,space_cache=v2,subvolid=277,subvol=/@snapshots/rootfs.20231214T1820)\n

Even if the mount option is rw the snapshot can be still read-only.

To make the current snapshot the default for the rootfs subvolume, the following steps must be performed.

Change into /.btrfs and create a read-only snapshot of the current system:

$ sudo btrfs subvolume snapshot -r @ @snapshots/broken-rootfs\nCreate a readonly snapshot of '@' in '@snapshots/broken-rootfs'\n

Delete the broken root file system:

$ sudo btrfs subvolume snapshot delete @\nDelete subvolume (no-commit): '/.btrfs/@'\n

Create a writable snapshot of the current booted snapshot as the new rootfs:

$ sudo btrfs subvolume snapshot @snapshots/rootfs.20231214T1820 @\nCreate a snapshot of '@snapshots/rootfs.20231214T1820' in './@'\n

Reboot the system and check the root file system:

$ mount | grep \" / \"\n/dev/mapper/vda3_crypt on / type btrfs (rw,noatime,compress=zstd:3,discard=async,space_cache=v2,subvolid=282,subvol=/@)\n
"},{"location":"unix/filesystems/btrfs.html#disable-cow","title":"Disable COW","text":"

Copy-on-write should be disabled when large files are frequently changed by random write (i.e., databases or VM images). In btrfs the copy-on-write mechanism can be disabled by mounting with the option nodatacow or with chattr +C for directories or files.

Most tools are aware of this problem and are disabling copy-on-write by default:

"},{"location":"unix/filesystems/btrfs.html#tools","title":"Tools","text":""},{"location":"unix/filesystems/btrfs.html#overview","title":"Overview","text":"

Used tools:

Other:

"},{"location":"unix/filesystems/btrfs.html#btrbk","title":"btrbk","text":"
sudo apt install btrbk\n
"},{"location":"unix/filesystems/btrfs.html#config","title":"Config","text":"

Example configuration for btrbk and the rootfs subvolume:

/etc/btrbk/btrbk.conf
# Enable transaction log\ntransaction_log            /var/log/btrbk.log\n\n# Preserve all snapshots for a minimum period of time.\nsnapshot_preserve_min      1d\n\n# Retention policy for the source snapshots.\nsnapshot_preserve          3h 5d 4w 6m 1y\n\nsnapshot_dir   /.snapshots\nsubvolume      /\nsnapshot_name  rootfs\nsubvolume      /home\nsnapshot_name  home\n
"},{"location":"unix/filesystems/btrfs.html#create-a-snapshot","title":"Create a snapshot","text":"
sudo btrbk run\n

To perform a try-run add the option -n.

"},{"location":"unix/filesystems/btrfs.html#show-diff-between-two-snapshots","title":"Show diff between two Snapshots","text":"

Create a snapshot and install the package htop and create a second snapshot. After that the differences between both snapshots can be shown:

$ sudo btrbk diff /.snapshots/rootfs.20231214T1820_1 /.snapshots/rootfs.20231214T1821\nFLAGS  COUNT  SIZE        FILE\n+c.        1   44.00 KiB  etc/mailcap\n+c.        1  312.00 KiB  usr/bin/htop\n+ci        1    2.49 KiB  usr/share/applications/htop.desktop\n+c.        1   28.00 KiB  usr/share/applications/mimeinfo.cache\n+ci        1    0.22 KiB  usr/share/doc/htop/AUTHORS\n+..        1    4.00 KiB  usr/share/doc/htop/README.gz\n+..        1    8.00 KiB  usr/share/doc/htop/changelog.Debian.gz\n+..        1   20.00 KiB  usr/share/doc/htop/changelog.gz\n+ci        1    1.29 KiB  usr/share/doc/htop/copyright\n+c.        1   28.00 KiB  usr/share/icons/hicolor/icon-theme.cache\n+c.        1   12.00 KiB  usr/share/icons/hicolor/scalable/apps/htop.svg\n+..        1    8.00 KiB  usr/share/man/man1/htop.1.gz\n+..        1    4.00 KiB  usr/share/pixmaps/htop.png\n+c.        1  140.00 KiB  var/lib/apt/extended_states\n+ci        1    0.56 KiB  var/lib/dpkg/info/htop.list\n+ci        1    0.63 KiB  var/lib/dpkg/info/htop.md5sums\n+c.        1    2.30 MiB  var/lib/dpkg/status\n+c.        1    2.30 MiB  var/lib/dpkg/status-old\n

The list of available snapshots can be shown with btrbk list snapshots.

"},{"location":"unix/filesystems/btrfs.html#grub-btrfs","title":"grub-btrfs","text":"

TODO

"},{"location":"unix/filesystems/btrfs.html#compsize","title":"compsize","text":"
sudo apt install btrfs-compsize\n

To see the impact of the used compression:

$ sudo compsize -x /\nProcessed 275808 files, 182511 regular extents (183978 refs), 91269 inline.\nType       Perc     Disk Usage   Uncompressed Referenced\nTOTAL       79%      7.0G         8.8G         9.5G\nnone       100%      6.0G         6.0G         6.5G\nzstd        33%      961M         2.7G         2.9G\n
"},{"location":"unix/filesystems/luks.html","title":"Linux Unified Key Setup (LUKS)","text":""},{"location":"unix/systemd/index.html","title":"systemd","text":""},{"location":"unix/systemd/index.html#add-a-service-timer","title":"Add a service, timer, ...","text":"

Create file in /usr/local/lib/systemd/system.

"},{"location":"unix/systemd/index.html#documentation","title":"Documentation","text":""},{"location":"unix/systemd/index.html#systemd-for-administrators","title":"systemd for Administrators","text":""},{"location":"unix/systemd/bootctl.html","title":"bootctl","text":""},{"location":"unix/systemd/journalctl.html","title":"journalctl","text":"

To see messages from other users and the system, add the current user to the group systemd-journal.

"},{"location":"unix/systemd/journalctl.html#display-logs","title":"Display Logs","text":""},{"location":"unix/systemd/journalctl.html#from-the-current-boot","title":"From the Current Boot","text":"
journalctl -b\n

Show the past boots

journalctl --list-boots\n
"},{"location":"unix/systemd/journalctl.html#time-window","title":"Time Window","text":"
journalctl --since \"2020-01-01\" --until \"2020-01-02 17:15:00\"\n

or

journalctl --since yesterday --until \"1 hour ago\"\n
"},{"location":"unix/systemd/journalctl.html#kernel-messages","title":"Kernel Messages","text":"
journalctl -k\n
"},{"location":"unix/systemd/journalctl.html#filter","title":"Filter","text":""},{"location":"unix/systemd/journalctl.html#by-priority","title":"By Priority","text":"

Priority: emerg, alert, crit, err, warning, notice, info, debug

journalctl -p err -b\n
"},{"location":"unix/systemd/journalctl.html#by-facility","title":"By Facility","text":"

Facility: kern, mail, syslog, local0, ...

journalctl --facility=auth\n

Get list of facilities: journalctl --facility=help

"},{"location":"unix/systemd/journalctl.html#by-unit","title":"By Unit","text":"

Get list of systemd units: systemctl list-units

journalctl -u ssh\njournalctl -u ssh.service\njournalctl --unit ssh\n
"},{"location":"unix/systemd/journalctl.html#by-identifier","title":"By Identifier","text":"
journalctl -t sshd\njournalctl --identifier=sshd\n
"},{"location":"unix/systemd/journalctl.html#by-field","title":"By Field","text":"

Get a description of available fields: man systemd.journal-fields

Query which entries exist for a speficic field:

journalctl -F _UID\njournalctl -F _PID\n

List all entries in the journal for a specific field:

journalctl _PID=9099\n
"},{"location":"unix/systemd/journalctl.html#by-pattern","title":"By Pattern","text":"

Grep a pattern in the message text.

Find case insensitive all entry with message containing error:

journal -g \"error\"\n
"},{"location":"unix/systemd/journalctl.html#disk-usage","title":"Disk Usage","text":"
journalctl --disk-usage\n

Clear the history

journalctl --vacuum-time=1week\n
"},{"location":"unix/systemd/localectl.html","title":"resolvectl","text":""},{"location":"unix/systemd/loginctl.html","title":"loginctl","text":""},{"location":"unix/systemd/loginctl.html#wayland-or-x11","title":"Wayland or X11","text":"
$ loginctl show-session 2 | grep Type\nType=x11\n
"},{"location":"unix/systemd/machinectl.html","title":"machinectl","text":""},{"location":"unix/systemd/networkctl.html","title":"networkctl","text":""},{"location":"unix/systemd/portablectl.html","title":"localectl","text":""},{"location":"unix/systemd/resolvectl.html","title":"protablectl","text":""},{"location":"unix/systemd/systemctl.html","title":"systemctl","text":""},{"location":"unix/systemd/systemctl.html#state-of-systemd-and-services","title":"State of systemd and services","text":"

Overview about all services:

systemctl\n

Get information about a service:

systemctl status cron.service\n
"},{"location":"unix/systemd/systemctl.html#content-of-service-timer-etc","title":"Content of service, timer, etc","text":"
systemctl cat cron.service\n
"},{"location":"unix/systemd/systemctl.html#boot-into-bios-setup","title":"Boot into BIOS Setup","text":"
sudo systemctl reboot --firmware-setup\n
"},{"location":"unix/systemd/systemd.html","title":"systemd Tools","text":""},{"location":"unix/systemd/systemd.html#systemd-cgls","title":"systemd-cgls","text":""},{"location":"unix/systemd/timedatectl.html","title":"timedatectl","text":""},{"location":"unix/tools/index.html","title":"Tools","text":""},{"location":"unix/tools/apt.html","title":"Advanced Package Tool (apt)","text":"","tags":["Ubuntu"]},{"location":"unix/tools/apt.html#keys","title":"Keys","text":"","tags":["Ubuntu"]},{"location":"unix/tools/apt.html#list-keys","title":"List Keys","text":"

Get a list of all keys configured for apt on your system:

sudo apt-key list\n
","tags":["Ubuntu"]},{"location":"unix/tools/apt.html#refresh-expired-keys","title":"Refresh Expired Keys","text":"

When you get an EXPKEYSIG error while apt update, you can update the expired key with the following command:

sudo apt-key adv --keyserver keys.gnupg.net --recv-keys AAAABBBBCCCCDDDD\n
","tags":["Ubuntu"]},{"location":"unix/tools/apt.html#packages-have-been-kept-back","title":"Packages have been kept back","text":"
$ sudo apt upgrade\nReading package lists... Done\nBuilding dependency tree... Done\nReading state information... Done\nCalculating upgrade... Done\nThe following packages have been kept back:\n  qemu-guest-agent snapd\n0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded.\n

If packages are kept back, there are three reasons for that:

","tags":["Ubuntu"]},{"location":"unix/tools/apt.html#packages-are-marked-as-hold-back","title":"Packages are marked as hold back","text":"

Individual packages can be marked as held back with apt-mark hold. This will prevent that the packages are automatically installed, upgraded or removed.

To check if a package is held back use the command apt-mark unhold:

$ apt-mark showhold\nqemu-guest-agent\n
","tags":["Ubuntu"]},{"location":"unix/tools/apt.html#packages-have-changed-dependencies","title":"Packages have changed dependencies","text":"

If the dependencies of a package has changed, and one of the new dependencies is not unmet, than the package will not be updated.

To see which package version is installed and which is upgradable use the command apt list -a:

$ apt list -a qemu-guest-agent\nListing... Done\nqemu-guest-agent/jammy-updates 1:6.2+dfsg-2ubuntu6.5 amd64 [upgradable from: 1:6.2+dfsg-2ubuntu6.4]\nqemu-guest-agent/now 1:6.2+dfsg-2ubuntu6.4 amd64 [installed,upgradable to: 1:6.2+dfsg-2ubuntu6.5]\nqemu-guest-agent/jammy-security 1:6.2+dfsg-2ubuntu6.2 amd64\nqemu-guest-agent/jammy 1:6.2+dfsg-2ubuntu6 amd64\n

Use apt-show for each version to check the dependencies:

apt show qemu-guest-agent=1:6.2+dfsg-2ubuntu6.4\napt show qemu-guest-agent=1:6.2+dfsg-2ubuntu6.5\n

If there are changed dependencies, install the update with the new depencies via:

sudo apt --with-new-pkgs upgrade\n

When you use apt install to resolve this issue the packages will be marked as manual installed.

","tags":["Ubuntu"]},{"location":"unix/tools/apt.html#packages-are-a-phased-update","title":"Packages are a phased update","text":"

Sometimes packages are not available to all users. Then only some users receive the update. This is a safety feature.

To check whether an update is a phased update, use the following command:

$ apt-cache policy qemu-guest-agent\nqemu-guest-agent:\n  Installed: 1:6.2+dfsg-2ubuntu6.4\n  Candidate: 1:6.2+dfsg-2ubuntu6.5\n  Version table:\n     1:6.2+dfsg-2ubuntu6.5 500 (phased 30%)\n        500 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages\n *** 1:6.2+dfsg-2ubuntu6.4 100\n        100 /var/lib/dpkg/status\n     1:6.2+dfsg-2ubuntu6.2 500\n        500 http://security.ubuntu.com/ubuntu jammy-security/universe amd64 Packages\n     1:6.2+dfsg-2ubuntu6 500\n        500 http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages\n

In this case the update is only available for 30% of all users.

","tags":["Ubuntu"]},{"location":"unix/tools/apt.html#netselect-apt","title":"netselect-apt","text":"

A tool that finds the nearest and fastest mirror and creates a source.list file for this mirror.

","tags":["Ubuntu"]},{"location":"unix/tools/fun.html","title":"Fun Tools","text":"

A list of \"fun\" tools for Linux.

"},{"location":"unix/tools/fun.html#cowsay","title":"CowSay","text":""},{"location":"unix/tools/fun.html#neofetch","title":"NeoFetch","text":""},{"location":"unix/tools/fun.html#misc","title":"Misc","text":""},{"location":"unix/tools/nvme.html","title":"NVME CLI","text":""},{"location":"unix/tools/nvme.html#general-usage","title":"General usage","text":"
$ sudo nvme list\n
$ sudo nvme smart-log /dev/nvme0n1\n

Device performance with htparm:

$ sudo hdparm -Tt --direct /dev/nvme0n1\n
"},{"location":"unix/tools/nvme.html#update-firmware","title":"Update Firmware","text":"

Display available slots and installed firmware versions:

$ sudo nvme fw-log /dev/nvme0n1\nFirmware Log for device:nvme0n1\nafi  : 0x1\nfrs1 : 5B2QGXA7\n

Check if firmware update is supported and which slots are available:

$ sudo nvme id-ctrl -H /dev/nvme0n1 | grep Firmware\n  [9:9] : 0x1   Firmware Activation Notices Supported\n  [4:4] : 0x1   Firmware Activate Without Reset Supported\n  [3:1] : 0x3   Number of Firmware Slots\n  [0:0] : 0     Firmware Slot 1 Read/Write\n

Download firmware:

$ sudo nvme fw-download -f firmware.enc /dev/nvme0n1\n

Commit firmware to slot 2 without activation (-a 0):

$ sudo nvme fw-commit -s 2 -a 0 /dev/nvme0n1\n

Check with nwme fw-log if firmware is stored in slot 2. Than activate (-a 2) the firmware in slot 2.

$ sudo nvme fw-commit -s 2 -a 2 /dev/nvme0n1\n
"},{"location":"unix/tools/nvme.html#samsung-firmware","title":"Samsung Firmware","text":"

https://semiconductor.samsung.com/consumer-storage/support/tools/

"},{"location":"unix/tools/smartmontools.html","title":"smartmontools","text":""},{"location":"unix/tools/smartmontools.html#get-information-about-device","title":"Get information about device","text":"

Scan for devices:

sudo smartctl --scan\n

In order to check if the device supports SMART and if SMART is enabled, use option --info or -i:

sudo smartctl --info /dev/sda\n

If the device is not in the smartctl database, update the database with:

sudo /usr/sbin/update-smart-drivedb\n
"},{"location":"unix/tools/smartmontools.html#enable-smart","title":"Enable SMART","text":"
sudo smartctl --smart=on --offlineauto=on --saveauto=on /dev/sda\n
"},{"location":"unix/tools/smartmontools.html#get-the-capabilities-of-the-device","title":"Get the capabilities of the device","text":"

Get the capabilities of the device with option --capabilities or -c:

sudo smartctl --capabilities /dev/sda\n
"},{"location":"unix/tools/smartmontools.html#print-the-health-status","title":"Print the health status","text":"

Get the health status of the device with option --health or -H:

sudo smartctl --health /dev/sda\n
"},{"location":"unix/tools/smartmontools.html#dump-all-information-about-the-device","title":"Dump all information about the device","text":"

To get all SMART information about the device with option --all or -a:

sudo smartctl --all /dev/sda\n

Get all the information above and all non-SMART information about the device with option --xall or -x:

sudo smartctl --xall /dev/sda\n
"},{"location":"unix/tools/smartmontools.html#print-error-log","title":"Print error log","text":"

Print device error log with option --log=error or -l error:

sudo smartctl --log=error /dev/sda\n
"},{"location":"unix/tools/smartmontools.html#performing-self-tests","title":"Performing self tests","text":"

Start self test with option --test or -t:

sudo smartctl --test=long /dev/sda\n

Get results of test:

sudo smartctl --log=selftest /dev/sda\n
"},{"location":"unix/tools/smartmontools.html#access-disks-in-raid-system","title":"Access disks in RAID system","text":""},{"location":"unix/tools/smartmontools.html#megaraid","title":"MegaRAID","text":"

Get list of disk in RAID:

sudo /opt/MegaRAID/storcli/storcli64 /c0 /eall /sall show\n

Use the DID as disk number in the smartctl command:

sudo smartctl --info --device=megaraid,40 /dev/sda\n
"},{"location":"unix/tools/tmux.html","title":"tmux","text":"

tmux is a terminal multiplexer.

","tags":["tmux"]},{"location":"unix/tools/tmux.html#scripting-with-tmux","title":"Scripting with tmux","text":"","tags":["tmux"]},{"location":"unix/tools/tmux.html#check-if-running-inside-a-tmux-session","title":"Check if running inside a tmux session","text":"

If tmux is version 3.2 or newer the environment variable TERM_PROGRAM is set:

if [ \"$TERM_PROGRAM\" = tmux ]\nthen\n  echo \"Inside a tmux session\"\nelse\n  echo \"Outside a tmux session\"\nfi\n
","tags":["tmux"]},{"location":"unix/tools/tmux.html#send-keys","title":"send-keys","text":"

The command send-keys has the following syntax:

tmux send-keys -t '{session}:{window}.{pane}' {command} ENTER\n

The target can be shorted as -t ':.!', which means:

Usage with new-window:

tmux new-window -c \"${dir}\" -n \"${name}\"\ntmux send-keys -t ':.' \"${EDITOR}\" ENTER\n

Usage with new-session:

tmux new-session -d\ntmux send-keys -t ':.' \"${EDITOR}\" ENTER\ntmux attach-session -t \":\"\n
","tags":["tmux"]},{"location":"unix/tools/tmux.html#current-special-key-bindings","title":"Current special key bindings","text":"","tags":["tmux"]},{"location":"unix/truenas/index.html","title":"TrueNAS","text":"","tags":["TrueNAS"]},{"location":"unix/ubuntu/index.html","title":"Ubuntu","text":"","tags":["Ubuntu"]},{"location":"unix/virtualization/index.html","title":"Virtualization","text":""},{"location":"unix/virtualization/proxmox/index.html","title":"Proxmox","text":"","tags":["Proxmox"]},{"location":"unix/virtualization/proxmox/terminal.html","title":"Terminal Access","text":"","tags":["Proxmox"]},{"location":"unix/virtualization/proxmox/terminal.html#connect-to-serial-console","title":"Connect to serial console","text":"

Check if terminal is available in guest:

$ qm monitor 1500\nEntering Qemu Monitor for VM 1500 - type 'help' for help\nqm> info chardev\n...\nserial0: filename=disconnected:unix:/var/run/qemu-server/1500.serial0,server=on\nqm>\n

Starting a connection to serial console:

$ qm terminal 1500\nstarting serial terminal on interface serial0 (press control-O to exit)\n

Stop the connection with ++Ctrl+o++.

","tags":["Proxmox"]},{"location":"unix/virtualization/proxmox/terminal.html#switch-to-console-terminal-via-qemu","title":"Switch to console terminal via QEMU","text":"

To switch to a virtual console, you can: * Go to Monitor of the virtual machine in the Web front-end and use the command sendkey ctrl-alt-fN. * Use qm sendkey vmid \"sendkey-ctrl-alt-fN\" in the shell.

","tags":["Proxmox"]},{"location":"unix/virtualization/proxmox/terminal.html#switch-to-console-terminal-via-chvt","title":"Switch to console terminal via chvt","text":"

The command chvt N switch to the virtual console N. For example:

$ sudu chvt 3\n
","tags":["Proxmox"]},{"location":"windows/index.html","title":"Windows","text":"","tags":["Windows"]},{"location":"windows/index.html#windows-updates","title":"Windows Updates","text":"

Get stand-alone update packages directly from Microsoft.

Get information about current running Windows:

PS> (Get-ComputerInfo).OSVersion\n10.0.19044\n

Explanation of the number can be found here.

Get the Window Update Build Revision (UBR):

PS> (Get-ComputerInfo).UBR\n2251\n

Get list of installed updates:

PS> Get-HotFix | Sort-Object InstalledOn -Descending\n
","tags":["Windows"]},{"location":"windows/index.html#check-windows-version","title":"Check Windows Version","text":"
if ((Get-CimInstance -ClassName Win32_OperatingSystem).Caption -like \"Microsoft Windows 10*\")\n{\n  Write-Host \"Windows 10\"\n}\nelse\n{\n  Write-Host \"Windows 11\"\n}\n
","tags":["Windows"]},{"location":"windows/tools/index.html","title":"Windows - Tools","text":" ","tags":["Windows"]},{"location":"windows/tools/bitlocker.html","title":"BitLocker","text":"

BitLocker is a proprietary volume encryption tool includes in Microsoft Windows. Without any configuration BitLocker using TPM. When using TPM on start of the computer no password needs to be entered.

The command line command manage-bde can be used to turn on BitLocker and monitor the current status.

"},{"location":"windows/tools/bitlocker.html#configure","title":"Configure","text":"

BitLocker can be configured through group policies or directly with registry keys.

Info

This configuration settings requires at least Windows 10, older versions of Windows use different options.

"},{"location":"windows/tools/bitlocker.html#group-policies","title":"Group Policies","text":"

The group policies are changed in the domain controller or locally via gpedit.msc.

"},{"location":"windows/tools/bitlocker.html#use-without-tpm","title":"Use without TPM","text":"

To enable password protected volume encryption the following group policy needs to be enabled (see admx.help):

"},{"location":"windows/tools/bitlocker.html#enable-better-encryption","title":"Enable better encryption","text":"

To use 256-bit AES encryption instead of the 128-bit default, the following group policies must be defined (see admx.help):

"},{"location":"windows/tools/bitlocker.html#registry-settings","title":"Registry Settings","text":""},{"location":"windows/tools/bitlocker.html#use-without-tpm_1","title":"Use without TPM","text":"

To enable password protected volume encryption the following registry entries need to be defined:

HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\FVE

"},{"location":"windows/tools/bitlocker.html#enable-better-encryption_1","title":"Enable better encryption","text":"

To use 256-bit AES encryption instead of the 128-bit default, the following registry entries must be defined:

HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\FVE

"},{"location":"windows/tools/bitlocker.html#enable-encryption","title":"Enable encryption","text":"

Enable BitLocker with a password (must be at least 8 characters):

PS> manage-bde.exe -on C: -password\n

Using abbreviations:

PS> manage-bde.exe -on C: -pw\n

To enable the encryption, the computer needs to be restarted: shutdown /r /t 0.

Warning

The keyboard layout can be different during password prompt of BitLocker. Therefore be prepared, if the password is misspelled that you used a key that has a different mapping.

Info

If the keyboard layout is different or you misspelled the password press ++ESC++ to boot without BitLocker enabled. The password needs to be set again.

"},{"location":"windows/tools/bitlocker.html#check-status","title":"Check status","text":"

After first successful restart, the encryption of the volume is starting. The current progress can be monitored with:

PS> manage-bde.exe -status C:\nBitLocker Drive Encryption: Configuration Tool version 10.0.22621\nCopyright (C) 2013 Microsoft Corporation. All rights reserved.\n\nVolume C: [Windows]\n[OS Volume]\n\n    Size:                 69,13 GB\n    BitLocker Version:    2.0\n    Conversion Status:    Used Space Only Encrypted\n    Percentage Encrypted: 100,0%\n    Encryption Method:    AES 256\n    Protection Status:    Protection On\n    Lock Status:          Unlocked\n    Identification Field: Unknown\n    Key Protectors:\n        Password\n
"},{"location":"windows/tools/bitlocker.html#add-numerical-password-as-fallback","title":"Add Numerical Password (as Fallback)","text":"

The numerical password is enabled with the following command:

PS> manage-pde -protectors -add C: -recoverypassword\n

or by using abbreviations:

PS> manage-bde.exe -protectors -add C: -rp\n

To get the protector methods:

PS> manage-bde.exe -protectors -get C:\nBitLocker Drive Encryption: Configuration Tool version 10.0.22621\nCopyright (C) 2013 Microsoft Corporation. All rights reserved.\n\nVolume C: [Windows]\nAll Key Protectors\n\n    Numerical Password:\n      ID: {89701158-94B4-42D2-87EB-82B8A03E45CD}\n      Password:\n        463881-116138-212971-219626-306295-227139-146784-038038\n\n    Password:\n      ID: {B1129007-8A8C-4398-BC67-0F608F771ABD}\n

The RecoveryPassword is called numerical password and the value is visible. Please store this recovery password in case you forget your password.

"},{"location":"windows/tools/bitlocker.html#change-password","title":"Change Password","text":"

The password can only be changed if a secondary protector is enabled (i.e., a numerical recovery password):

PS> manage-pde -changepassword C:\n
"},{"location":"windows/tools/bitlocker.html#script","title":"Script","text":"

The following PowerShell script enable BitLocker on C::

if ((Get-BitLockerVolume C:).EncryptionMethod -ne \"None\") {\n  Write-Host \"\"\n  Write-Host \"Volume C: is already encrypted\" -ForegroundColor red\n  Get-BitLockerVolume C: | Select-Object *\n  Write-Host \"Disable BitLocker: \" -NoNewLine\n  Write-Host \"Disable-BitLocker -MountPoint C:\" -ForegroundColor yellow\n  Exit 1\n}\n\nfunction Set-RegistryProperty {\n  Param (\n    [Parameter(Mandatory=$True, Position=0)]\n    [String] $Path,\n    [Parameter(Mandatory=$True, Position=1)]\n    [String] $Name,\n    [Parameter(Mandatory=$True, Position=2)]\n    [String] $Type,\n    [Parameter(Mandatory=$True, Position=3)]\n    [Object] $Value\n  )\n\n  if (-not (Test-Path $Path)) {\n    New-Item -Path $Path -Force > $null\n  }\n  if ((Get-Item $Path).Property -contains $Name) {\n    Set-ItemProperty -Path $Path -Name $Name `\n                     -Type $Type -Value $Value -Force > $null\n  } else {\n    New-ItemProperty -Path $Path -Name $Name `\n                     -PropertyType $Type -Value $Value -Force > $null\n  }\n}\n\nWrite-Host \"\"\nWrite-Host \"Configure Bitlocker without TPM and better encryption\"\n$properties = `\n  @{Name = 'UseAdvancedStartup';          Type = 'DWORD'; Value = 1}, `\n  @{Name = 'EnableBDEWithNoTPM';          Type = 'DWORD'; Value = 1}, `\n  @{Name = 'UseTPM';                      Type = 'DWORD'; Value = 0}, `\n  @{Name = 'UseTPMPIN';                   Type = 'DWORD'; Value = 0}, `\n  @{Name = 'UseTPMKey';                   Type = 'DWORD'; Value = 0}, `\n  @{Name = 'UseTPMKeyPIN';                Type = 'DWORD'; Value = 0}, `\n  @{Name = 'EncryptionMethodWithXtsOs';   Type = 'DWORD'; Value = 7}, `\n  @{Name = 'EncryptionMethodWithXtsFdv';  Type = 'DWORD'; Value = 7}, `\n  @{Name = 'EncryptionMethodWithXtsRdv';  Type = 'DWORD'; Value = 4}\n\nForEach ($property in $properties) {\n  Set-RegistryProperty -Path 'HKLM:\\SOFTWARE\\Policies\\Microsoft\\FVE' `\n                       -Name $property.Name `\n                       -Type $property.Type -Value $property.Value\n}\n\nWrite-Host \"\"\nWrite-Host \"Activate Bitlocker\"\nEnable-BitLocker -MountPoint C: -PasswordProtector\nEnable-BitLocker -MountPoint C: -RecoveryPasswordProtector `\n                                -ErrorAction SilentlyContinue\n\nWrite-Host \"\"\nWrite-Host \"Reboot: \" -NoNewLine\nWrite-Host \"shutdown /r /t 0\" -ForegroundColor yellow\nWrite-Host \"\"\n
"},{"location":"windows/tools/winget.html","title":"winget","text":"

Windows Package Manager CLI (aka winget) can be used to install/upgrade software on Windows via the command line.

","tags":["Windows"]},{"location":"windows/tools/winget.html#install","title":"Install","text":"

Download latest version from GitHub release page.

Info

The download a package with all dependencies you can use https://store.rg-adguard.net/.

Now you will see all packages inside this application.

Install winget as a provisioned package:

PS> Add-AppxProvisionedPackage\n        -PackagePath 'Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle'\n        -LicensePath '7bcb1a0ab33340daa57fa5b81faec616_License1.xml'\n        -DependencyPackagePath\n            'Microsoft.VCLibs.x64.14.00.Desktop.appx',\n            'Microsoft.UI.Xaml.2.7_7.2208.15002.0_x64__8wekyb3d8bbwe.appx'\n        -Online\n

Enable provisioned package for the current user:

(Get-AppxProvisionedPackage -Online |\n   Where-Object -Property DisplayName -EQ Microsoft.DesktopAppInstaller\n).InstallLocation | Add-AppxPackage -Register -DisableDevelopmentMode\n

The executable winget.exe is than found in $env:USERPROFILE\\AppData\\Local\\Microsoft\\WindowsApps\\.

Warning

If there are policies that does not allow Microsoft applications, the application Microsoft.DesktopAppInstaller must be whitelisted.

","tags":["Windows"]},{"location":"windows/tools/winget.html#searching-for-packages","title":"Searching for Packages","text":"

List all available packages:

PS> winget search\n

Can also be seen at microsoft/winget-pkgs.

List all packages that contains note:

PS> winget search note\n

Display information about a package:

PS> winget show notepad++\n
","tags":["Windows"]},{"location":"windows/tools/winget.html#installing-a-package","title":"Installing a Package","text":"

Try to install all packages in machine scope (for all users):

PS> winget install --scope machine --exact --id gerardog.gsudo\n

Therefore, the default scope should be machine. Change the default scope in the settings

Some package can not be installed in machine scope:

PS> winget install --scope user --exact --id Microsoft.WindowsTerminal\n
","tags":["Windows"]},{"location":"windows/tools/winget.html#listing-package-repositories","title":"Listing Package Repositories","text":"
PS> winget source list\n
","tags":["Windows"]},{"location":"windows/tools/winget.html#upgrading-packages","title":"Upgrading Packages","text":"

To get a list of upgradeable packages:

PS> winget upgrade\n

To upgrade a package:

PS> winget upgrade Notepad++.Notepad++\n
","tags":["Windows"]},{"location":"windows/tools/winget.html#configuration-settings","title":"Configuration Settings","text":"

To open the settings in an editor:

PS> winget settings\n

The settings (documentation on these settings):

{\n    \"$schema\": \"https://aka.ms/winget-settings.schema.json\",\n\n    \"visual\": {\n        \"progressBar\": \"rainbow\"\n    },\n    \"installBehavior\": {\n        \"preferences\": {\n            \"scope\": \"machine\"\n        }\n    },\n    \"source\": {\n        \"autoUpdateIntervalInMinutes\": 5\n    }\n}\n
","tags":["Windows"]},{"location":"windows/tools/wt.html","title":"Windows Terminal","text":"","tags":["Windows"]},{"location":"windows/tools/wt.html#install","title":"Install","text":"

microsoft/terminal

Download the latest release from https://github.com/microsoft/terminal/releases/latest

Install the MSIXBundle by starting a PowerShell with administratior rights:

PS> Add-AppxPackage Microsoft.WindowsTerminal_1.2.2381.0_8wekyb3d8bbwe.msixbundle\n

Or install via winget:

PS> winget install \"Windows Terminal\"\n
","tags":["Windows"]},{"location":"windows/tools/wt.html#configure","title":"Configure","text":"

Global configurations (copyOnSelect must be changed):

{\n\u00a0 \u00a0 \"disabledProfileSources\": [ \"Windows.Terminal.Azure\" ],\n\u00a0 \u00a0 \"theme\": \"dark\",\n\u00a0 \u00a0 \"launchMode\": \"maximized\",\n\n    // If enabled, selections are automatically copied to your clipboard.\n    \"copyOnSelect\": true\n}\n

Default settings for all profiles:

{\n    \"profiles\":\n    {\n\u00a0 \u00a0 \u00a0 \u00a0 \"defaults\":\n\u00a0 \u00a0 \u00a0 \u00a0 {\n            \"fontFace\": \"Hack NF\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"fontSize\" : 14,\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"cursorShape\": \"filledBox\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"colorScheme\": \"Tomorrow Night\"\n\u00a0 \u00a0 \u00a0 \u00a0 },\n        \"list\":\n        [\n        ]\n    }\n}\n

Add Cygwin bash:

            {\n                \"guid\": \"{a1f2ceb2-795d-4f2a-81cc-723cceec49c0}\",\n                \"name\": \"Cygwin bash\",\n                \"commandline\": \"C:/cygwin/bin/bash.exe -i -l\",\n                \"icon\": \"C:/cygwin/Cygwin-Terminal.ico\",\n                \"hidden\": false\n            },\n

Add startingDirectory for all WSL entries:

      {\n                \"startingDirectory\": \"//wsl$/Ubuntu-20.04/home/ti5cw\"\n      }\n

Define the Tomorrow Night color theme:

{\n\u00a0 \u00a0 \"schemes\": [\n\u00a0 \u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"name\": \"Tomorrow Night\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"black\": \"#000000\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"red\": \"#cc6666\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"green\": \"#b5bd68\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"yellow\": \"#f0c674\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"blue\": \"#81a2be\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"purple\": \"#b294bb\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"cyan\": \"#8abeb7\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"white\": \"#ffffff\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"brightBlack\": \"#000000\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"brightRed\": \"#cc6666\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"brightGreen\": \"#b5bd68\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"brightYellow\": \"#f0c674\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"brightBlue\": \"#81a2be\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"brightPurple\": \"#b294bb\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"brightCyan\": \"#8abeb7\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"brightWhite\": \"#ffffff\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"background\": \"#1d1f21\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"foreground\": \"#c5c8c6\"\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 ]\n}\n

Change keyboard shortcuts:

{\n    \"actions\":\n    [\n        // Change binding from Ctrl+= to Ctrl+\u00df\n        { \"command\": { \"action\": \"adjustFontSize\", \"delta\": 1 }, \"keys\": \"ctrl+\u00df\" }\n    ]\n}\n
","tags":["Windows"]},{"location":"windows/tools/wt.html#shortcuts","title":"Shortcuts","text":" ","tags":["Windows"]},{"location":"writing/index.html","title":"Writing","text":""},{"location":"writing/latex/truetype-fonts.html","title":"TrueType Fonts","text":"

http://tug.ctan.org/tex-archive/info/german/MiKTeX-WinEdt-TrueType-Anleitung/ttf.htm

"},{"location":"writing/mkdocs/index.html","title":"Material for MkDocs","text":""},{"location":"writing/mkdocs/admontion.html","title":"Admonition","text":""},{"location":"writing/mkdocs/admontion.html#setup","title":"Setup","text":"
markdown_extensions:\n  - admonition\n  - pymdownx.details\n
"},{"location":"writing/mkdocs/admontion.html#examples","title":"Examples","text":"Note

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

Note

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

With title

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

abstract summary tldr

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

info todo

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

tip hint important

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

success check done

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

question help faq

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

warning caution attention

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

failure fail missing

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

danger error

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

Bug

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

example snippet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

quote site

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

"},{"location":"writing/mkdocs/definition.html","title":"Definition List","text":""},{"location":"writing/mkdocs/definition.html#setup","title":"Setup","text":"
markdown_extensions:\n  - def_list\n
"},{"location":"writing/mkdocs/definition.html#examples","title":"Examples","text":"Lorem ipsum dolor sit amet Sed sagittis eleifend rutrum. Donec vitae suscipit est. Nullam tempus tellus non sem sollicitudin, quis rutrum leo facilisis. Cras arcu libero Aliquam metus eros, pretium sed nulla venenatis, faucibus auctor ex. Proin ut eros sed sapien ullamcorper consequat. Nunc ligula ante.

Duis mollis est eget nibh volutpat, fermentum aliquet dui mollis. Nam vulputate tincidunt fringilla. Nullam dignissim ultrices urna non auctor.

"},{"location":"writing/mkdocs/formatting.html","title":"Formatting","text":""},{"location":"writing/mkdocs/formatting.html#critic","title":"Critic","text":""},{"location":"writing/mkdocs/formatting.html#setup","title":"Setup","text":"
markdown_extensions:\n  - pymdownx.critic:\n      mode: view\n
"},{"location":"writing/mkdocs/formatting.html#examples","title":"Examples","text":"

Highlight a complete paragraph

"},{"location":"writing/mkdocs/formatting.html#caret-mark-tilde","title":"Caret, Mark & Tilde","text":""},{"location":"writing/mkdocs/formatting.html#setup_1","title":"Setup","text":"
markdown_extensions:\n  - pymdownx.caret\n  - pymdownx.mark\n  - pymdownx.tilde\n
"},{"location":"writing/mkdocs/formatting.html#example","title":"Example","text":""},{"location":"writing/mkdocs/formatting.html#keyboard","title":"Keyboard","text":""},{"location":"writing/mkdocs/formatting.html#setup_2","title":"Setup","text":"
markdown_extensions:\n  - pymdownx.keys\n
"},{"location":"writing/mkdocs/formatting.html#examples_1","title":"Examples","text":""},{"location":"writing/mkdocs/icons.html","title":"Icons & Emojis","text":""},{"location":"writing/mkdocs/icons.html#setup","title":"Setup","text":"
markdown_extensions:\n  - attr_list\n  - pymdownx.emoji:\n      emoji_index: !!python/name:material.extensions.emoji.twemoji\n      emoji_generator: !!python/name:material.extensions.emoji.to_svg\n
"},{"location":"writing/mkdocs/icons.html#examples","title":"Examples","text":"

There is a search in all available icons under https://squidfunk.github.io/mkdocs-material/reference/icons-emojis/.

Available Icons/Emojis:

"},{"location":"writing/mkdocs/images.html","title":"Images / Badges","text":""},{"location":"writing/mkdocs/images.html#examples","title":"Examples","text":"

Foobar Foobar

"},{"location":"writing/mkdocs/magiclink.html","title":"Magic Link","text":""},{"location":"writing/mkdocs/magiclink.html#setup","title":"Setup","text":"
extra_css:\n  - assets/css/extra-5ee9fa49a5.css\n\nmarkdown_extension:\n  - pymdownx.magiclink:\n      repo_url_shortener: true\n      repo_url_shorthand: true\n
"},{"location":"writing/mkdocs/markdown.html","title":"Markdown","text":""},{"location":"writing/mkdocs/markdown.html#emphasis","title":"Emphasis","text":"

is*bold*is is_bold_is is**bold**is is__bold__is is***bold***is is___bold___is

"},{"location":"writing/mkdocs/markdown.html#table","title":"Table","text":"A B C A B C AA BB CC AAA BBB CCC"},{"location":"writing/mkdocs/markdown.html#nested-lists","title":"Nested Lists","text":""},{"location":"writing/mkdocs/markdown.html#setup","title":"Setup","text":"

Using Mdx Truly Sane Lists.

Needs to be added into requirements.txt: mdx_truly_sane_lists

markdown_extensions:\n  - mdx_truly_sane_lists:\n      nested_indent: 2\n      truly_sane: true\n
"},{"location":"writing/mkdocs/markdown.html#example","title":"Example","text":"

GitHub indention

LayoutMarkdown
* Level 1 (GitHub)\n  * Level 2\n    * Level 3\n  * Level 2\n

Standard indention

LayoutMarkdown

Standanrd indention is not valid any more.

* Level 1 (Standard)\n    * Level 2\n        * Level 3\n    * Level 2\n
"},{"location":"writing/mkdocs/mermaid.html","title":"Mermaid","text":""},{"location":"writing/mkdocs/mermaid.html#setup","title":"Setup","text":"
markdown_extension:\n  - pymdownx.superfences:\n      custom_fences:\n        - name: mermaid\n          class: mermaid\n          format: !!python/name:pymdownx.superfences.fence_code_format\n
"},{"location":"writing/mkdocs/mermaid.html#examples","title":"Examples","text":"
graph TD;\nA --> B;\nA --> C;\nB --> D;\nC --> D;
graph TD\nA[Hard] -->|Text| B(Round)\nB --> C{Decision}\nC -->|One| D[Result 1]\nC -->|Two| E[Result 2]
"},{"location":"writing/mkdocs/source.html","title":"Source","text":""},{"location":"writing/mkdocs/source.html#setup","title":"Setup","text":"
theme:\n  features:\n    - content.code.annotate # (1)!\n    - content.code.copy # (2)!\n\nmarkdown_extensions:\n  - pymdownx.highlight:\n      anchor_linenums: true\n      line_spans: __span\n      pygments_lang_class: true\n  - pymdownx.inlinehilite\n  - pymdownx.snippets\n  - pymdownx.superfences\n
  1. Important for code annotations
  2. Enable code copy button
"},{"location":"writing/mkdocs/source.html#examples","title":"Examples","text":"

Code with highlighting:

def example(param):\n    print(f'param = {param}')\n

Using snippets:

LayoutMarkdown hello_world.c
#include<stdio.h>\n#include<stdlib.h>\n\n/*\n * Hello World\n */\nint main(int argc, char *argv[]) {\n  int a = 5;\n  int b = 4.3;\n\n  printf(\"Hello World!\\n\");\n\n  return EXIT_SUCCESS;\n}\n
``` c title=\"hello_world.c\"\n--8<-- \"writing/mkdocs/hello_world.c\"\n```\n

The filename is under the directory base_path configured in mkdocs.yaml:

markdown_extensions:\n  - pymdownx.snippets:\n      base_path: snippets/\n

The directory should be outside of docs/.

More examples can be found in the documentation.

Using annotations:

LayoutMarkdown
// Simple example\nint main(int argc, char* argv[])\n{\n  int a = 42; // The answer (1)\n  return EXIT_SUCCESS; // (2)!\n}\n
  1. to everything.
  2. Annotation with stripping comments
``` c\n// Simple example\nint main(int argc, char *argv[])\n{\n  int a = 42;          // The answer (1)\n  return EXIT_SUCCESS; // (2)!\n```\n\n1.  to everthing\n2.  Annotation with stripping comments\n

For each code annotation a link can be set (example).

"},{"location":"writing/mkdocs/task.html","title":"Task List","text":""},{"location":"writing/mkdocs/task.html#setup","title":"Setup","text":"
markdown_extensions:\n  - pymdownx.tasklist:\n      custom_checkbox: true\n
"},{"location":"writing/mkdocs/task.html#examples","title":"Examples","text":""},{"location":"blog/archive/2023.html","title":"2023","text":""},{"location":"blog/category/tools.html","title":"Tools","text":""},{"location":"blog/category/unix.html","title":"UNIX","text":""},{"location":"blog/category/windows.html","title":"Windows","text":""},{"location":"blog/category/neovim.html","title":"Neovim","text":""},{"location":"blog/category/latex.html","title":"LaTeX","text":""},{"location":"tags.html","title":"Tags","text":"

Following is a list of relevant tags:

"},{"location":"tags.html#homeassistant","title":"HomeAssistant","text":""},{"location":"tags.html#proxmox","title":"Proxmox","text":""},{"location":"tags.html#truenas","title":"TrueNAS","text":""},{"location":"tags.html#ubuntu","title":"Ubuntu","text":""},{"location":"tags.html#windows","title":"Windows","text":""},{"location":"tags.html#yaml","title":"YAML","text":""},{"location":"tags.html#bash","title":"bash","text":""},{"location":"tags.html#tmux","title":"tmux","text":""}]} \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz index c12ca2f..a86354e 100644 Binary files a/sitemap.xml.gz and b/sitemap.xml.gz differ diff --git a/tags.html b/tags.html index 9afc83e..8e061ed 100644 --- a/tags.html +++ b/tags.html @@ -3594,28 +3594,28 @@

Tags

Following is a list of relevant tags:

HomeAssistant🔗

Proxmox🔗

TrueNAS🔗

Ubuntu🔗

Windows🔗

diff --git a/tools/vi/index.html b/tools/vi/index.html index 7e5c58c..a537ea1 100644 --- a/tools/vi/index.html +++ b/tools/vi/index.html @@ -27,7 +27,7 @@ - Overview - dreknix - Documentation + Vi / Vim / Neovim - dreknix - Documentation @@ -287,7 +287,7 @@
- Overview + Vi / Vim / Neovim
diff --git a/tools/vi/neovim/index.html b/tools/vi/neovim/index.html index e0a307e..934c2d0 100644 --- a/tools/vi/neovim/index.html +++ b/tools/vi/neovim/index.html @@ -27,7 +27,7 @@ - Overview - dreknix - Documentation + Neovim / NvChad - dreknix - Documentation @@ -287,7 +287,7 @@
- Overview + Neovim / NvChad
diff --git a/unix/debian/index.html b/unix/debian/index.html index e2ad2ca..0108c42 100644 --- a/unix/debian/index.html +++ b/unix/debian/index.html @@ -27,7 +27,7 @@ - Overview - dreknix - Documentation + Debian - dreknix - Documentation @@ -287,7 +287,7 @@
- Overview + Debian
diff --git a/unix/filesystems/index.html b/unix/filesystems/index.html index 99cabac..070a386 100644 --- a/unix/filesystems/index.html +++ b/unix/filesystems/index.html @@ -27,7 +27,7 @@ - Overview - dreknix - Documentation + Filesystems - dreknix - Documentation @@ -287,7 +287,7 @@
- Overview + Filesystems
diff --git a/unix/index.html b/unix/index.html index f432d1a..6357966 100644 --- a/unix/index.html +++ b/unix/index.html @@ -27,7 +27,7 @@ - Overview - dreknix - Documentation + UNIX - dreknix - Documentation @@ -287,7 +287,7 @@
- Overview + UNIX
diff --git a/unix/systemd/index.html b/unix/systemd/index.html index d6005a9..d10e507 100644 --- a/unix/systemd/index.html +++ b/unix/systemd/index.html @@ -27,7 +27,7 @@ - Overview - dreknix - Documentation + systemd - dreknix - Documentation @@ -287,7 +287,7 @@
- Overview + systemd
diff --git a/unix/tools/index.html b/unix/tools/index.html index 3691b27..af280c3 100644 --- a/unix/tools/index.html +++ b/unix/tools/index.html @@ -27,7 +27,7 @@ - Overview - dreknix - Documentation + Tools - dreknix - Documentation @@ -287,7 +287,7 @@
- Overview + Tools
diff --git a/unix/truenas/index.html b/unix/truenas/index.html index 31d0b3b..7c2c03f 100644 --- a/unix/truenas/index.html +++ b/unix/truenas/index.html @@ -27,7 +27,7 @@ - Overview - dreknix - Documentation + TrueNAS - dreknix - Documentation @@ -287,7 +287,7 @@
- Overview + TrueNAS
diff --git a/unix/ubuntu/index.html b/unix/ubuntu/index.html index f1bd331..bc6062e 100644 --- a/unix/ubuntu/index.html +++ b/unix/ubuntu/index.html @@ -27,7 +27,7 @@ - Overview - dreknix - Documentation + Ubuntu - dreknix - Documentation @@ -287,7 +287,7 @@
- Overview + Ubuntu
diff --git a/unix/virtualization/proxmox/index.html b/unix/virtualization/proxmox/index.html index ffde7f6..25d4d1a 100644 --- a/unix/virtualization/proxmox/index.html +++ b/unix/virtualization/proxmox/index.html @@ -27,7 +27,7 @@ - Overview - dreknix - Documentation + Proxmox - dreknix - Documentation @@ -287,7 +287,7 @@
- Overview + Proxmox
diff --git a/windows/index.html b/windows/index.html index e59c3c7..3869e82 100644 --- a/windows/index.html +++ b/windows/index.html @@ -27,7 +27,7 @@ - Overview - dreknix - Documentation + Windows - dreknix - Documentation @@ -287,7 +287,7 @@
- Overview + Windows
diff --git a/windows/tools/index.html b/windows/tools/index.html index 00d54fb..dd740b0 100644 --- a/windows/tools/index.html +++ b/windows/tools/index.html @@ -27,7 +27,7 @@ - Overview - dreknix - Documentation + Windows - Tools - dreknix - Documentation @@ -287,7 +287,7 @@
- Overview + Windows - Tools
diff --git a/writing/index.html b/writing/index.html index df86c59..798fa58 100644 --- a/writing/index.html +++ b/writing/index.html @@ -27,7 +27,7 @@ - Overview - dreknix - Documentation + Writing - dreknix - Documentation @@ -287,7 +287,7 @@
- Overview + Writing
diff --git a/writing/mkdocs/index.html b/writing/mkdocs/index.html index c7c3ff5..e5d2db0 100644 --- a/writing/mkdocs/index.html +++ b/writing/mkdocs/index.html @@ -27,7 +27,7 @@ - Overview - dreknix - Documentation + Material for MkDocs - dreknix - Documentation @@ -287,7 +287,7 @@
- Overview + Material for MkDocs