Compare commits
18 Commits
af52292ef8
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
7f9de785df
|
|||
|
723024db0b
|
|||
|
8ec1d53ea4
|
|||
|
8ef34f8a1f
|
|||
|
1dbc97209e
|
|||
|
594107c252
|
|||
|
89238fa9eb
|
|||
|
57a1b027ed
|
|||
|
e1fee5d4c2
|
|||
| 2cff9f47ea | |||
| 0a41f6b65a | |||
|
5feb513b38
|
|||
|
3063b65d34
|
|||
|
35f2663330
|
|||
|
26ee7243e3
|
|||
|
afcd5699a7
|
|||
|
399358d810
|
|||
|
596a4a9746
|
9
Makefile
9
Makefile
@@ -4,6 +4,12 @@ EDITOR ?= vi
|
|||||||
FZF != command -v sk || command -v fzy || command -v fzf || \
|
FZF != command -v sk || command -v fzy || command -v fzf || \
|
||||||
{ echo install a fuzzy finder && exit 1 ;}
|
{ echo install a fuzzy finder && exit 1 ;}
|
||||||
|
|
||||||
|
ifeq "$(FZF)" "/usr/bin/fzy"
|
||||||
|
FZF += -i
|
||||||
|
else
|
||||||
|
FZF += --print-query | cat
|
||||||
|
endif
|
||||||
|
|
||||||
spill_contents = sed -e '1,/---/d'
|
spill_contents = sed -e '1,/---/d'
|
||||||
|
|
||||||
help: .git/info/exclude ## Print the help message
|
help: .git/info/exclude ## Print the help message
|
||||||
@@ -41,7 +47,7 @@ $(databases): .dbs/%.rec: %/ | .dbs/
|
|||||||
|
|
||||||
# This two-variable read can only happen because of the quotes in the titles.
|
# This two-variable read can only happen because of the quotes in the titles.
|
||||||
db.rec: $(databases)
|
db.rec: $(databases)
|
||||||
$(warning rebuilding from $? )
|
$(info rebuilding from $? )
|
||||||
printf '%s\n' '%rec: guide' > $@
|
printf '%s\n' '%rec: guide' > $@
|
||||||
printf '%s\n' '%key: title' >> $@
|
printf '%s\n' '%key: title' >> $@
|
||||||
printf '%s\n' '%type: requires rec guide' >> $@
|
printf '%s\n' '%type: requires rec guide' >> $@
|
||||||
@@ -72,6 +78,7 @@ article: ## Write an article
|
|||||||
@path=$$(find $(categories) -type d | sort | uniq | $(FZF)) ;\
|
@path=$$(find $(categories) -type d | sort | uniq | $(FZF)) ;\
|
||||||
read -p "Title: " title ;\
|
read -p "Title: " title ;\
|
||||||
filename="$$(echo "$$title" | tr '[:upper:]' '[:lower:]' | tr ' ' '_')" ;\
|
filename="$$(echo "$$title" | tr '[:upper:]' '[:lower:]' | tr ' ' '_')" ;\
|
||||||
|
mkdir -p $$path ;\
|
||||||
printf '%s\n' '---' >> $$path/$$filename.md ;\
|
printf '%s\n' '---' >> $$path/$$filename.md ;\
|
||||||
printf 'title: "%s"\n' "$$title" >> $$path/$$filename.md ;\
|
printf 'title: "%s"\n' "$$title" >> $$path/$$filename.md ;\
|
||||||
printf 'tags: [ "%s" ]\n' "$$path" | tr '[:upper:]' '[:lower:]' | sed 's#\/#", "#g' >> $$path/$$filename.md ;\
|
printf 'tags: [ "%s" ]\n' "$$path" | tr '[:upper:]' '[:lower:]' | sed 's#\/#", "#g' >> $$path/$$filename.md ;\
|
||||||
|
|||||||
@@ -100,7 +100,13 @@ Try:
|
|||||||
- `<Esc>kcw`
|
- `<Esc>kcw`
|
||||||
- ls -a<Esc>xxxx
|
- ls -a<Esc>xxxx
|
||||||
|
|
||||||
Works with `python` too:
|
Readline can work with python one you set `PYTHON_BASIC_REPL` to `true`.
|
||||||
|
|
||||||
|
|
||||||
|
```sh
|
||||||
|
echo 'export PYTHON_BASIC_REPL=true' >> ~/.bashrc
|
||||||
|
exec bash
|
||||||
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
im<C-n>os<Return>
|
im<C-n>os<Return>
|
||||||
|
|||||||
54
data/newsraft.md
Normal file
54
data/newsraft.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
---
|
||||||
|
title: "Newsraft"
|
||||||
|
tags: [ "data", "RSS" ]
|
||||||
|
requires: [ "Shell Scripts" ]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Setup
|
||||||
|
|
||||||
|
Install newsraft, then:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
mkdir ~/.config/newsraft
|
||||||
|
echo 'https://codeberg.org/newsraft/newsraft.atom "Newsraft git"' >> ~/.config/newsraft/feeds
|
||||||
|
newsraft
|
||||||
|
```
|
||||||
|
|
||||||
|
# Commands
|
||||||
|
|
||||||
|
Copy the default config file:
|
||||||
|
|
||||||
|
```
|
||||||
|
cp /usr/share/doc/newsraft/example/config ~/.config/newsraft/config
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Add a line to check the man page while inside the program:
|
||||||
|
|
||||||
|
```
|
||||||
|
bind M exec man newsraft
|
||||||
|
```
|
||||||
|
|
||||||
|
This will fail, because the letter 'M' is taken by `mpv`.
|
||||||
|
|
||||||
|
Add this line to take the default link, and place it in a list of videos.
|
||||||
|
|
||||||
|
```
|
||||||
|
bind V mark-read; exec echo "%l" >> ~/.cache/vidlist.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
# Videos
|
||||||
|
|
||||||
|
You can get an RSS feed from any YouTube video with this script:
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
CHANNEL_ID="$(curl -s "$1" | tr ',' '\n' | grep -Po 'channelId":"\K[\w+-]+' | tail -1)"
|
||||||
|
FEED_URL="https://www.youtube.com/feeds/videos.xml?channel_id=$CHANNEL_ID"
|
||||||
|
CHANNEL_NAME="$(curl -s "$FEED_URL" | grep -m 1 -Po 'title\>\K[\w\s]+')"
|
||||||
|
|
||||||
|
printf '%s "%s"\n' "$FEED_URL" "$CHANNEL_NAME"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -14,7 +14,6 @@ sudo systemctl edit getty@tty1
|
|||||||
The put in the following, changing `[ USER ]` to your username.
|
The put in the following, changing `[ USER ]` to your username.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ExecStart=
|
ExecStart=
|
||||||
ExecStart=-/usr/bin/agetty --autologin [ USER ] -s %I 115200,38400,9600 vt102
|
ExecStart=-/usr/bin/agetty --autologin [ USER ] -s %I 115200,38400,9600 vt102
|
||||||
@@ -25,9 +24,22 @@ ExecStart=-/usr/bin/agetty --autologin [ USER ] -s %I 115200,38400,9600 vt102
|
|||||||
|
|
||||||
In `.bashrc`.
|
In `.bashrc`.
|
||||||
|
|
||||||
```
|
```sh
|
||||||
if [ -z "$DISPLAY" ] && [ "$(fgconsole)" -eq 1 ]; then
|
if [ -z "$DISPLAY" ] && [ "$(fgconsole)" -eq 1 ]; then
|
||||||
exec startx
|
exec startx
|
||||||
fi
|
fi
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# Faillock reset
|
||||||
|
|
||||||
|
After failing 3 times to enter the password, archlinux would ussualy lock entering the password for 10 minutes, not all apps and guis display this message, so sometimes it can be a bit confusing. To reset this lockdown, you can login as root and restart it manually with command
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
failock --reset
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: "basic-install"
|
title: "Install Arch"
|
||||||
tags: [ "arch" ]
|
tags: [ "arch" ]
|
||||||
requires: [ "partitions", "time" ]
|
requires: [ "partitions", "time" ]
|
||||||
---
|
---
|
||||||
|
|||||||
27
distros/arch/install_yay.md
Normal file
27
distros/arch/install_yay.md
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
title: "Install yay"
|
||||||
|
tags: [ "distros", "arch" ]
|
||||||
|
requirements: [ "pacman" ]
|
||||||
|
---
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pacman --sync --noconfirm --needed base-devel gcc git
|
||||||
|
git clone https://aur.archlinux.org/yay.git /tmp/yay
|
||||||
|
makepkg -C !$ -si
|
||||||
|
```
|
||||||
|
|
||||||
|
The flags are mostly the same as in `pacman`.
|
||||||
|
But running `yay` without flags will do the update like `yay -Syu` and with package name it will search packages in the AUR and `pacman` repos, and let you choose which to install.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
yay <search_term>
|
||||||
|
```
|
||||||
|
|
||||||
|
Building the package can usually take some time, and after the build it will ask for the `sudo` password.
|
||||||
|
If you leave, the installation will fail.
|
||||||
|
To avoid this, you can use the flag `--sudoloop` and enter the sudo password initially and it will loop it until the installation is finished.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
yay -S --noconfirm --sudoloop <package_name>
|
||||||
|
```
|
||||||
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
title: "Maintenance"
|
title: "Arch Maintenance"
|
||||||
tags: [ "arch" ]
|
tags: [ "arch" ]
|
||||||
|
requirements: [ "pacman" ]
|
||||||
---
|
---
|
||||||
|
|
||||||
# Package Cache
|
# Package Cache
|
||||||
@@ -12,15 +13,6 @@ ls /var/cache/pacman/pkg/ | wc -l
|
|||||||
sudo pacman -Sc
|
sudo pacman -Sc
|
||||||
ls /var/cache/pacman/pkg/ | wc -l
|
ls /var/cache/pacman/pkg/ | wc -l
|
||||||
```
|
```
|
||||||
And the same for `yay` (with `-Yc` to remove old dependencies):
|
|
||||||
|
|
||||||
```sh
|
|
||||||
ls ~/.cache/yay/ | wc -l
|
|
||||||
yay -Sc
|
|
||||||
yay -Yc
|
|
||||||
ls ~/.cache/yay/ | wc -l
|
|
||||||
```
|
|
||||||
|
|
||||||
# New Configs
|
# New Configs
|
||||||
|
|
||||||
If you chance a configuration file, such as `/etc/environment`, and `pacman` wants to update the file, it will place `/etc/environment.pacnew`.
|
If you chance a configuration file, such as `/etc/environment`, and `pacman` wants to update the file, it will place `/etc/environment.pacnew`.
|
||||||
@@ -41,10 +33,7 @@ sudo -e /etc/pacman.d/mirrorlist
|
|||||||
sudo rm /etc/pacman.d/mirrorlist.pacnew
|
sudo rm /etc/pacman.d/mirrorlist.pacnew
|
||||||
```
|
```
|
||||||
|
|
||||||
Or,
|
Or use a tool like `pacdiff` to view the changes next to each other, and select them with `vim`.
|
||||||
|
|
||||||
- use a tool like `pacdiff` to view the changes next to each other, and select them with `vim`.
|
|
||||||
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo pacman -S pacman-contrib
|
sudo pacman -S pacman-contrib
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
title: "pacman"
|
title: "pacman"
|
||||||
tags: [ "distros" ]
|
tags: [ "distros" ]
|
||||||
|
requirements: [ "Install Arch" ]
|
||||||
---
|
---
|
||||||
|
|
||||||
Packages are kept in /var/cache/pacman/pkg.
|
Packages are kept in /var/cache/pacman/pkg.
|
||||||
@@ -19,7 +20,9 @@ sudo pacman-key --populate archlinux
|
|||||||
|
|
||||||
And refreshed with:
|
And refreshed with:
|
||||||
|
|
||||||
|
```sh
|
||||||
sudo pacman-key --refresh-keys
|
sudo pacman-key --refresh-keys
|
||||||
|
```
|
||||||
|
|
||||||
If you have usigned keys, you can refresh with:
|
If you have usigned keys, you can refresh with:
|
||||||
|
|
||||||
@@ -48,7 +51,13 @@ sudo pacman -S archlinux-keyring
|
|||||||
List all orphaned packages:
|
List all orphaned packages:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo pacman -Qtdq
|
pacman -Qtdq
|
||||||
|
```
|
||||||
|
|
||||||
|
Removing a package:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo pacman -Rn <package_name>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Cleaning Config Files
|
## Cleaning Config Files
|
||||||
@@ -61,3 +70,4 @@ These changes must be merge manually.
|
|||||||
|
|
||||||
Install the `pacdiff` tool to make this easier, from the `pacman-contrib` package, then simply run `sudo pacdiff` to sort through the various mergers.
|
Install the `pacdiff` tool to make this easier, from the `pacman-contrib` package, then simply run `sudo pacdiff` to sort through the various mergers.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
29
distros/arch/pacman_extras.md
Normal file
29
distros/arch/pacman_extras.md
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
title: "pacman - Extras"
|
||||||
|
tags: [ "distros" ]
|
||||||
|
requirements: [ "pacman" ]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Unattended Actions
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pacman -Syu --noconfirm
|
||||||
|
```
|
||||||
|
|
||||||
|
## `pacman` and `yay` Text Colouring
|
||||||
|
|
||||||
|
Getting the colors is done by editing the `/etc/pacman.conf` and uncommenting the line `Color`.
|
||||||
|
|
||||||
|
By adding the line `ILoveCandy` you will unlock some terminal animations, like pacman eating dots while installing some package.
|
||||||
|
|
||||||
|
## Timid Installations
|
||||||
|
|
||||||
|
Want to try out software, but not sure if you want to keep it?
|
||||||
|
You can tell `pacman` that this is a dependency for another package:
|
||||||
|
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pacman -S --noconfirm --asdeps <weird music player>
|
||||||
|
```
|
||||||
|
|
||||||
|
When you [remove orphaned packages](pacman.md), the package will be automatically uninstalled.
|
||||||
22
distros/arch/yay_maintenance.md
Normal file
22
distros/arch/yay_maintenance.md
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
title: "Arch Maintenance with yay"
|
||||||
|
tags: [ "arch" ]
|
||||||
|
requirements: [ "Arch Maintenance" ]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Package Cache
|
||||||
|
|
||||||
|
Just like `pacman`
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ls ~/.cache/yay/ | wc -l
|
||||||
|
yay -Sc
|
||||||
|
```
|
||||||
|
|
||||||
|
Use `-Yc` to remove old dependencies:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
yay -Yc
|
||||||
|
ls ~/.cache/yay/ | wc -l
|
||||||
|
```
|
||||||
|
|
||||||
@@ -14,12 +14,27 @@ Say 'hello' to yourself:
|
|||||||
ansible --module-name=ping localhost
|
ansible --module-name=ping localhost
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Ansible takes a lot of information about each machine during setup:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
TMP=$(mktemp)
|
||||||
|
ansible --module-name=setup localhost | tee $TMP
|
||||||
|
less !$
|
||||||
|
```
|
||||||
|
|
||||||
|
If you have `jq`, you can pull out info:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sed -i 's/.*SUCC.*/{/' $TMP
|
||||||
|
jq '.ansible_facts.ansible_distribution' < $TMP
|
||||||
|
```
|
||||||
|
|
||||||
Upgrade through the package manager.
|
Upgrade through the package manager.
|
||||||
|
|
||||||
`packager=apt` (or `pacman` or `xbps`,...)
|
`packager=apt` (or `pacman` or `xbps`,...)
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
packager=apt
|
packager="$( jq -r '.ansible_facts.ansible_pkg_mgr' < $TMP )"
|
||||||
ansible --module-name=${packager} --args "upgrade=yes" localhost
|
ansible --module-name=${packager} --args "upgrade=yes" localhost
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -87,4 +102,8 @@ ansible-inventory --list -y -i
|
|||||||
ansible-vault view sec.yml --vault-pass-file pass.sh
|
ansible-vault view sec.yml --vault-pass-file pass.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
community.general.say voice=en_GB msg="Testing 123"
|
Install `espeak', then make the computer say something:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ansible --module-name=say --args "msg='testing'" localhost
|
||||||
|
```
|
||||||
|
|||||||
75
system/ansible/store_password.md
Normal file
75
system/ansible/store_password.md
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
---
|
||||||
|
title: "Store Host Password"
|
||||||
|
tags: [ "system", "ansible" ]
|
||||||
|
---
|
||||||
|
|
||||||
|
Make a hosts file with one host (your computer) and one variable, just to test:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
hosts_file=hosts
|
||||||
|
fort="$(fortune -s | head -1)"
|
||||||
|
cowvar=cowsays
|
||||||
|
|
||||||
|
echo "[cows]
|
||||||
|
$HOSTNAME $cowvar='${fort}'" > "${hosts_file}"
|
||||||
|
```
|
||||||
|
|
||||||
|
Now ansible should be able to show that '${cowvar}' in a debug message:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ansible -i "$hosts_file" -m debug -a "msg='{{ ${cowvar} }}'" $HOSTNAME
|
||||||
|
```
|
||||||
|
|
||||||
|
Now to convert the hosts file to yaml, because it's very fashionable:
|
||||||
|
|
||||||
|
|
||||||
|
```sh
|
||||||
|
yaml_hosts=hosts.yaml
|
||||||
|
ansible-inventory -i ${hosts_file} --list -y | tee "${yaml_hosts}"
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you should see where the `cowsays` variable goes.
|
||||||
|
You can safely place your `sudo` password next to that variable goes with `ansible-vault`, which will encrypt just that string.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pass="your password"
|
||||||
|
ansible-vault encrypt_string --name='ansible_sudo_pass' "${pass}"
|
||||||
|
```
|
||||||
|
|
||||||
|
If that works, you can add the password, but in `yaml` format.
|
||||||
|
You can do this manually, or use `gawk` to add ten spaces in front of the lines:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pass="your password"
|
||||||
|
ansible-vault encrypt_string --name='ansible_sudo_pass' "${pass}" | awk '{print " " $0}' >> "${yaml_hosts}"
|
||||||
|
```
|
||||||
|
|
||||||
|
Now to check that the inventory file works okay:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ansible-inventory -i ${yaml_hosts} --list -y
|
||||||
|
ansible -i "$hosts_file" -m debug -a "msg='{{ ${cowvar} }}'" $HOSTNAME
|
||||||
|
```
|
||||||
|
|
||||||
|
If that works, you can echo the debug message while becoming root.
|
||||||
|
Just add the `-J` flag so it will ask for the password:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ansible -i "${yaml_hosts}" -m debug -a "msg='{{ ${cowvar} }}'" $HOSTNAME --become -J
|
||||||
|
ansible -i "${yaml_hosts}" -m debug -a "msg={{ ansible_sudo_pass }}" $HOSTNAME --become -J
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you can update using Ansible.
|
||||||
|
|
||||||
|
For Arch Linux:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ansible -i "${yaml_hosts}" -m community.general.pacman -a 'upgrade=true update_cache=true' $HOSTNAME --become -J
|
||||||
|
```
|
||||||
|
|
||||||
|
For Debian:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ansible -i "${yaml_hosts}" -m ansible.builtin.apt -a 'upgrade=full' $HOSTNAME --become -J
|
||||||
|
```
|
||||||
|
|
||||||
225
virtualization/kubernetes/kubernetes_basics.md
Normal file
225
virtualization/kubernetes/kubernetes_basics.md
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
---
|
||||||
|
title: "Kubernetes Basics"
|
||||||
|
tags: [ "virtualization", "kubernetes" ]
|
||||||
|
requires: [ "Kubernetes Setup" ]
|
||||||
|
---
|
||||||
|
|
||||||
|
Install `kubectl`.
|
||||||
|
|
||||||
|
> **NB:** Debian requires manual installation.[^kubedeb]
|
||||||
|
|
||||||
|
[^kubedeb]: https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/
|
||||||
|
|
||||||
|
# Read
|
||||||
|
|
||||||
|
1. Check the namespace: `kubectl get namespaces`
|
||||||
|
1. Check the `${kube-system}` namespace: `kubectl get deployments.apps --namespace kube-system'
|
||||||
|
1. Check host computers: `kubectl get nodes`
|
||||||
|
1. Check pods: `kubectl get pods`
|
||||||
|
|
||||||
|
|
||||||
|
```tree
|
||||||
|
Namespaces
|
||||||
|
├── Node_1: minikube
|
||||||
|
│ ├── deployment_1: nginx
|
||||||
|
│ │ ├── pod_1
|
||||||
|
│ │ └── pod_2
|
||||||
|
│ ├── deployment_2: database
|
||||||
|
│ │ ├── pod_1
|
||||||
|
│ │ ├── pod_2
|
||||||
|
│ │ ├── pod_3
|
||||||
|
│ │ └── pod_4
|
||||||
|
│ ├── deployment_3: prometheus
|
||||||
|
│ └── deployment_4: idk probably yaml
|
||||||
|
└── Node_1: physical server
|
||||||
|
├── deployment_1: nginx
|
||||||
|
│ ├── pod_1
|
||||||
|
│ └── pod_2
|
||||||
|
├── deployment_2: database
|
||||||
|
│ ├── pod_1
|
||||||
|
│ ├── pod_2
|
||||||
|
│ ├── pod_3
|
||||||
|
│ └── pod_4
|
||||||
|
├── deployment_3: prometheus
|
||||||
|
└── deployment_4: Abandoned wiki
|
||||||
|
```
|
||||||
|
|
||||||
|
## More Information
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ kubectl get pod
|
||||||
|
|
||||||
|
NAME READY STATUS RESTARTS AGE
|
||||||
|
nginx-depl-68c944fcbc-2xbvq 1/1 Running 0 20m
|
||||||
|
|
||||||
|
$ kubectl describe pod nginx-depl-68c944fcbc-2xbvq
|
||||||
|
|
||||||
|
Name: nginx-depl-68c944fcbc-2xbvq
|
||||||
|
Namespace: default
|
||||||
|
Priority: 0
|
||||||
|
Service Account: default
|
||||||
|
Node: minikube/192.168.59.107
|
||||||
|
Start Time: Fri, 29 Aug 2025 19:26:29 +0200
|
||||||
|
Labels: app=nginx-depl
|
||||||
|
pod-template-hash=68c944fcbc
|
||||||
|
Annotations: <none>
|
||||||
|
Status: Running
|
||||||
|
IP: 10.244.0.3
|
||||||
|
IPs:
|
||||||
|
IP: 10.244.0.3
|
||||||
|
Controlled By: ReplicaSet/nginx-depl-68c944fcbc
|
||||||
|
Containers:
|
||||||
|
nginx:
|
||||||
|
Container ID: docker://aaa68e90ed9237dc0f98f9a21b0d7ddf3113188c62e72242d30cab4a43cbff98
|
||||||
|
Image: nginx
|
||||||
|
Image ID: docker-pullable://nginx@sha256:33e0bbc7ca9ecf108140af6288c7c9d1ecc77548cbfd3952fd8466a75edefe57
|
||||||
|
Port: <none>
|
||||||
|
Host Port: <none>
|
||||||
|
State: Running
|
||||||
|
Started: Fri, 29 Aug 2025 19:26:41 +0200
|
||||||
|
Ready: True
|
||||||
|
Restart Count: 0
|
||||||
|
Environment: <none>
|
||||||
|
Mounts:
|
||||||
|
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-9bgxx (ro)
|
||||||
|
Conditions:
|
||||||
|
Type Status
|
||||||
|
PodReadyToStartContainers True
|
||||||
|
Initialized True
|
||||||
|
Ready True
|
||||||
|
ContainersReady True
|
||||||
|
PodScheduled True
|
||||||
|
Volumes:
|
||||||
|
kube-api-access-9bgxx:
|
||||||
|
Type: Projected (a volume that contains injected data from multiple sources)
|
||||||
|
TokenExpirationSeconds: 3607
|
||||||
|
ConfigMapName: kube-root-ca.crt
|
||||||
|
Optional: false
|
||||||
|
DownwardAPI: true
|
||||||
|
QoS Class: BestEffort
|
||||||
|
Node-Selectors: <none>
|
||||||
|
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
|
||||||
|
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
|
||||||
|
Events:
|
||||||
|
Type Reason Age From Message
|
||||||
|
---- ------ ---- ---- -------
|
||||||
|
Normal Scheduled 24m default-scheduler Successfully assigned default/nginx-depl-68c944fcbc-2xbvq to minikube
|
||||||
|
Normal Pulling 24m kubelet Pulling image "nginx"
|
||||||
|
Normal Pulled 24m kubelet Successfully pulled image "nginx" in 11.204s (11.204s including waiting). Image size: 192385800 bytes.
|
||||||
|
Normal Created 24m kubelet Created container: nginx
|
||||||
|
Normal Started 24m kubelet Started container nginx
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Pod copies are called a 'replicaset'.
|
||||||
|
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ kubectl exec $POD_NAME -- env
|
||||||
|
|
||||||
|
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
HOSTNAME=stupendously-verbose-podish-nomenclature-jvguenaqbz-punenpgref
|
||||||
|
KUBERNETES_PORT_443_TCP_PORT=443
|
||||||
|
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
|
||||||
|
KUBERNETES_SERVICE_HOST=10.96.0.1
|
||||||
|
KUBERNETES_SERVICE_PORT=443
|
||||||
|
KUBERNETES_SERVICE_PORT_HTTPS=443
|
||||||
|
KUBERNETES_PORT=tcp://10.96.0.1:443
|
||||||
|
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
|
||||||
|
KUBERNETES_PORT_443_TCP_PROTO=tcp
|
||||||
|
NPM_CONFIG_LOGLEVEL=info
|
||||||
|
NODE_VERSION=6.3.1
|
||||||
|
HOME=/root
|
||||||
|
```
|
||||||
|
|
||||||
|
# Create
|
||||||
|
|
||||||
|
Create a 'deployment' of `nginx`.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
name="nginx-depl"
|
||||||
|
kubectl create deployment ${name} --image=nginx
|
||||||
|
kubectl get deployments
|
||||||
|
```
|
||||||
|
|
||||||
|
The command did not specify a namespace, so `default` is used.
|
||||||
|
|
||||||
|
# Update
|
||||||
|
|
||||||
|
Update a deployment, with `$EDITOR`.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl edit deployments.apps ${name}
|
||||||
|
```
|
||||||
|
|
||||||
|
This gives us far too much information:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
deployment.kubernetes.io/revision: "1"
|
||||||
|
|
||||||
|
[ ... ]
|
||||||
|
|
||||||
|
creationTimestamp: "2025-08-29T18:13:45Z"
|
||||||
|
generation: 3
|
||||||
|
labels:
|
||||||
|
app: nginx-depl
|
||||||
|
name: nginx-depl
|
||||||
|
namespace: default
|
||||||
|
resourceVersion: "17696"
|
||||||
|
uid: 8dec2925-5c34-4635-b82c-ba601cb3bef5
|
||||||
|
spec:
|
||||||
|
progressDeadlineSeconds: 600
|
||||||
|
replicas: 2
|
||||||
|
revisionHistoryLimit: 10
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: nginx-depl
|
||||||
|
|
||||||
|
[ ... ]
|
||||||
|
|
||||||
|
observedGeneration: 3
|
||||||
|
readyReplicas: 2
|
||||||
|
replicas: 2
|
||||||
|
updatedReplicas: 2
|
||||||
|
```
|
||||||
|
|
||||||
|
Pull out the information, without an `$EDITOR`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
file="webstuff"
|
||||||
|
kubectl get deployment ${name} -o yaml > ${webstuff}.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Enter the Pod
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ kubectl get pods
|
||||||
|
|
||||||
|
NAME READY STATUS RESTARTS AGE
|
||||||
|
nginx-depl-68c944fcbc-2xbvq 1/1 Running 0 31m
|
||||||
|
|
||||||
|
$ pod='nginx-depl-68c944fcbc-2xbvq'
|
||||||
|
$ kubectl exec -it ${pod} -- bash
|
||||||
|
|
||||||
|
root@nginx-depl-68c944fcbc-2xbvq:/# ls
|
||||||
|
bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var
|
||||||
|
boot docker-entrypoint.d etc lib media opt root sbin sys usr
|
||||||
|
root@nginx-depl-68c944fcbc-2xbvq:/#
|
||||||
|
exit
|
||||||
|
```
|
||||||
|
|
||||||
|
# Delete
|
||||||
|
|
||||||
|
Delete a deployment, and watch it leave:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
name=nginx-depl
|
||||||
|
kubectl delete deployments.apps nginx-depl && kubectl get deployments.apps
|
||||||
|
kubectl get deployments.apps
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
64
virtualization/kubernetes/kubernetes_explain.md
Normal file
64
virtualization/kubernetes/kubernetes_explain.md
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
---
|
||||||
|
title: "Kubernetes Docs"
|
||||||
|
tags: [ "virtualization", "kubernetes", "WTFM", "hosts", "DNS" ]
|
||||||
|
requires: [ "Kubernetes Basics" ]
|
||||||
|
---
|
||||||
|
|
||||||
|
`kubectl` provides easy high-level overviews:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl config view
|
||||||
|
kubectl cluster-info
|
||||||
|
```
|
||||||
|
|
||||||
|
Unfortunately, the documentation commands work less well.
|
||||||
|
|
||||||
|
# Kube-Explain
|
||||||
|
|
||||||
|
The `kubectl explain` resources cannot use tab-completion.
|
||||||
|
But you can find the same resources listed with `api-resources`, and use a fuzzy-finder, to get the same effect.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
t="$(kubectl api-resources | fzy | gawk '{print $1}')"
|
||||||
|
kubectl explain ${t}
|
||||||
|
```
|
||||||
|
|
||||||
|
The documentation is in a classic style, which could only be improved by deletion.
|
||||||
|
Take this fragment from `kubectl explain namespaces`:
|
||||||
|
|
||||||
|
```
|
||||||
|
DESCRIPTION:
|
||||||
|
Namespace provides a scope for Names. Use of multiple namespaces is
|
||||||
|
optional.
|
||||||
|
```
|
||||||
|
|
||||||
|
- Sentence 1: A 'name-space' is a space for names.
|
||||||
|
- Sentence 2: If you create a namespace, you will not receive an error due to not having a second namespace. This is also the case for deployments, variables, and files which begin with the letter 'P', but the writer was being paid per word.
|
||||||
|
|
||||||
|
Continuing...
|
||||||
|
|
||||||
|
```
|
||||||
|
metadata <ObjectMeta>
|
||||||
|
Standard object's metadata. More info:
|
||||||
|
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
```
|
||||||
|
|
||||||
|
So a namespace has metadata, which has something in diamond-brackets called `ObjectMeta`.
|
||||||
|
We should understand this as 'normal metadata for an object', and the author promises us more information.
|
||||||
|
But only a fool would trust that link, as the author's a hack, without even the flimsy excuse of being left alone with ChatGPT (the docs existed before LLMs became uncool).
|
||||||
|
|
||||||
|
Completing this morality tale, entitled '*Why Nobody Reads the Docs*', we arrive at the end of Kubernetes' namespace documentation:
|
||||||
|
|
||||||
|
```
|
||||||
|
status <NamespaceStatus>
|
||||||
|
Status describes the current status of a Namespace. More info:
|
||||||
|
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
|
||||||
|
```
|
||||||
|
|
||||||
|
Of course this is wrong.
|
||||||
|
The sentence should read:
|
||||||
|
|
||||||
|
```
|
||||||
|
'Status' describes the current status of a Namespace.
|
||||||
|
```
|
||||||
|
|
||||||
53
virtualization/kubernetes/proxy_api.md
Normal file
53
virtualization/kubernetes/proxy_api.md
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
---
|
||||||
|
title: "Proxy API"
|
||||||
|
tags: [ "virtualization", "kubernetes" ]
|
||||||
|
requires: [ "Kubernetes Basics" ]
|
||||||
|
---
|
||||||
|
|
||||||
|
Start the proxy:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl proxy &
|
||||||
|
```
|
||||||
|
|
||||||
|
Then curl the API server:
|
||||||
|
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl http://localhost:8001
|
||||||
|
```
|
||||||
|
|
||||||
|
Create a token:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export TOKEN=$(kubectl create token default)
|
||||||
|
|
||||||
|
kubectl create clusterrole api-access-root \
|
||||||
|
--verb=get --non-resource-url=/*
|
||||||
|
|
||||||
|
kubectl create clusterrolebinding api-access-root \
|
||||||
|
--clusterrole api-access-root --serviceaccount=default:default
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Retrieve the API Server endpoint:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export APISERVER=$(kubectl config view | grep https | \
|
||||||
|
cut -f 2- -d ":" | tr -d " ")
|
||||||
|
```
|
||||||
|
|
||||||
|
Confirm that the `APISERVER` variable stored the same IP as the Kubernetes control plane IP by issuing the following two commands and comparing their outputs:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
echo $APISERVER
|
||||||
|
|
||||||
|
https://192.168.99.100:8443
|
||||||
|
|
||||||
|
kubectl cluster-info
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
We can also get the certs straight from the list in `~/.kube/config`.
|
||||||
|
|
||||||
|
|
||||||
54
virtualization/kubernetes/setup.md
Normal file
54
virtualization/kubernetes/setup.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
---
|
||||||
|
title: "Kubernetes Setup"
|
||||||
|
tags: [ "virtualization", "kubernetes", "minikube", "docker" ]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Install `minikube`
|
||||||
|
Set up a practice environment with `minikube`, using either Docker or VirtualBox.
|
||||||
|
|
||||||
|
1. Install the driver (VirtualBox is a good choice).
|
||||||
|
1. Install `minikube`.
|
||||||
|
* Debian requires manual installation.[^minideb]
|
||||||
|
1. Check it works.
|
||||||
|
|
||||||
|
The installation takes a long time.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# driver=docker
|
||||||
|
driver=virtualbox
|
||||||
|
minikube start --driver=${driver}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Check `minikube`
|
||||||
|
|
||||||
|
Check it's all running:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
minikube kubectl -- get po -A
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
NAMESPACE NAME READY STATUS RESTARTS AGE
|
||||||
|
kube-system coredns-674b8bbfcf-l7582 1/1 Running 0 2m
|
||||||
|
kube-system etcd-minikube 1/1 Running 0 2m
|
||||||
|
kube-system kube-apiserver-minikube 1/1 Running 0 2m
|
||||||
|
kube-system kube-controller-manager-minikube 1/1 Running 0 2m
|
||||||
|
kube-system kube-proxy-4q977 1/1 Running 0 2m
|
||||||
|
kube-system kube-scheduler-minikube 1/1 Running 0 2m
|
||||||
|
kube-system storage-provisioner 1/1 Running 1 (2m ago) 2m
|
||||||
|
```
|
||||||
|
|
||||||
|
# Uninstall `minikube`
|
||||||
|
|
||||||
|
```sh
|
||||||
|
du -sh ~/.minikube
|
||||||
|
```
|
||||||
|
|
||||||
|
Minikube is huge!
|
||||||
|
|
||||||
|
```sh
|
||||||
|
minikube stop
|
||||||
|
rm -rf ~/.minikube
|
||||||
|
```
|
||||||
|
|
||||||
|
[^minideb]: https://minikube.sigs.k8s.io/docs/start/
|
||||||
71
vision/record_terminal.md
Normal file
71
vision/record_terminal.md
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
---
|
||||||
|
title: "Record a Terminal Session"
|
||||||
|
tags: [ "vision", "share" ]
|
||||||
|
---
|
||||||
|
|
||||||
|
Record a terminal command, then press 'Control + d' to exit.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
script --timing=time.log stat.txt
|
||||||
|
ls -a
|
||||||
|
ls -al
|
||||||
|
stat ~/.bashrc
|
||||||
|
^D
|
||||||
|
```
|
||||||
|
|
||||||
|
Replay the session:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
scriptreplay --timing=time.log stat.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
Try a bare command, without any timing:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
script -c 'top | lolcat' loltop
|
||||||
|
nl loltop
|
||||||
|
```
|
||||||
|
|
||||||
|
Has your terminal messed up?
|
||||||
|
Is the cursor hiding?
|
||||||
|
Reset it!
|
||||||
|
|
||||||
|
```sh
|
||||||
|
reset
|
||||||
|
```
|
||||||
|
If you can't see any keys, keep typing anyway: have faith in your terminal.
|
||||||
|
|
||||||
|
This `loltop` file will not play properly as it has no timings file.
|
||||||
|
But you can cheat the system and use your other timings file:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
scriptreplay --timing=time.log loltop
|
||||||
|
```
|
||||||
|
|
||||||
|
This will mostly not work well, but it shows how the timing file works:
|
||||||
|
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.033401 23
|
||||||
|
0.044513 8
|
||||||
|
0.000016 219
|
||||||
|
1.349324 114
|
||||||
|
0.179106 1
|
||||||
|
0.088790 1
|
||||||
|
0.072821 1
|
||||||
|
0.358337 2
|
||||||
|
0.000254 9
|
||||||
|
0.004720 52
|
||||||
|
0.000084 21
|
||||||
|
0.155462 671
|
||||||
|
```
|
||||||
|
|
||||||
|
I think it works like this?
|
||||||
|
|
||||||
|
| How long it took | to type *n* characters |
|
||||||
|
|:----------------:|:----------------------:|
|
||||||
|
| 0.033401 | 23 |
|
||||||
|
| 0.044513 | 8 |
|
||||||
|
| 0.000016 | 219 |
|
||||||
|
| 1.349324 | 114 |
|
||||||
|
|
||||||
@@ -51,7 +51,6 @@ Search packages:
|
|||||||
```sh
|
```sh
|
||||||
tlmgr search --global epstopdf
|
tlmgr search --global epstopdf
|
||||||
```
|
```
|
||||||
|
|
||||||
Can't find what you need?
|
Can't find what you need?
|
||||||
Search for a specific file instead:
|
Search for a specific file instead:
|
||||||
|
|
||||||
@@ -60,8 +59,16 @@ tlmgr search --global --file epstopdf-base.sty
|
|||||||
sudo tlmgr install epstopdf-pkg
|
sudo tlmgr install epstopdf-pkg
|
||||||
```
|
```
|
||||||
|
|
||||||
## Recommended Packages
|
Check how many unique licences LaTeX packages use:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
tlmgr info --list --json
|
||||||
|
jq -r '.[].cataloguedata.license' < tex.json | sort | uniq | wc -l
|
||||||
|
```
|
||||||
|
|
||||||
|
Please remember: the world does not need any more licences.
|
||||||
|
|
||||||
|
## Recommended Packages
|
||||||
|
|
||||||
```
|
```
|
||||||
latexmk
|
latexmk
|
||||||
|
|||||||
@@ -3,6 +3,13 @@ title: "vim basics"
|
|||||||
tags: [ "vim", "basic" ]
|
tags: [ "vim", "basic" ]
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Instant nano replacement
|
||||||
|
|
||||||
|
`vim -y` - will start vim but like other editors like nano, there will be syntax highlighting, etc
|
||||||
|
Keybind to exit this mode is `Ctrl+q`
|
||||||
|
|
||||||
|
## Steps
|
||||||
|
|
||||||
1. Insert text by pressing `a`.
|
1. Insert text by pressing `a`.
|
||||||
1. Stop inserting text by pressing `Ctrl+[`.
|
1. Stop inserting text by pressing `Ctrl+[`.
|
||||||
1. Exit with `ZZ`.
|
1. Exit with `ZZ`.
|
||||||
|
|||||||
Reference in New Issue
Block a user