Compare commits

...

20 Commits

Author SHA1 Message Date
7f9de785df record terminal with script 2025-10-31 17:20:37 +01:00
723024db0b ansible notes 2025-10-21 23:54:30 +02:00
8ec1d53ea4 arch: timid installations 2025-10-14 17:19:22 +02:00
8ef34f8a1f Merge remote-tracking branch 'soft/master' into dev 2025-10-14 16:07:02 +02:00
1dbc97209e split yay and pacman 2025-10-14 15:34:22 +02:00
594107c252 allow new article path 2025-10-12 08:01:00 +02:00
89238fa9eb measuring tex packages 2025-09-02 23:00:10 +02:00
57a1b027ed kube notes 2025-09-02 22:58:49 +02:00
e1fee5d4c2 add newsraft 2025-09-01 21:23:21 +02:00
2cff9f47ea [Vim] nano alternative 2025-08-31 22:45:22 +02:00
0a41f6b65a [Archlinux] pacman, yay, faillock 2025-08-31 22:42:20 +02:00
5feb513b38 add kubernetes proxy api 2025-08-29 22:08:16 +02:00
3063b65d34 kubectl explain: an affront to basic decency 2025-08-29 21:58:16 +02:00
35f2663330 add basic kubernetes commands 2025-08-29 21:48:16 +02:00
26ee7243e3 kubernetes setup 2025-08-29 15:14:25 +02:00
afcd5699a7 calm the makefile messages 2025-08-29 08:07:53 +02:00
399358d810 note how to set up with python readline 2025-08-29 07:49:26 +02:00
596a4a9746 ansible: store host password 2025-08-23 18:59:47 +02:00
af52292ef8 tempfs article 2025-08-22 16:18:28 +02:00
865b4a2da1 remove duplicate entry 2025-08-22 16:02:19 +02:00
21 changed files with 775 additions and 153 deletions

View File

@@ -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 ;\

View File

@@ -1,129 +0,0 @@
---
title: "cron"
tags: [ "basics", "time" ]
---
# Cronie
The `cronie` program is also known as `crond`.
## Install
```sh
sudo apt search -n ^cron
```
Once installed, search for the service name, and start it.
```sh
sudo systemctl list-unit-files | grep cron
sudo systemctl enable --now $NAME
```
## Usage
Show your current crontab:
```sh
crontab -l
```
You can put this in a file and edit it:
```sh
crontab -l > $filename
echo '39 3 */3 * * /bin/tar czf /tmp/etc_backup.tgz /etc/' >> $filename
```
Then apply that crontab:
```sh
crontab $filename
rm $filename
```
The `cron` program will check your syntax before adding the tab.
Your crontab file sits somewhere in `/var/spool/`.
Probably in `/var/spool/cron`.
## Syntax
`* * * * *`
These five points refer to:
`minute hour day month weekday`
So '3pm every Sunday' would be:
`0 15 * * 7`
Here 'Sunday' is indicated by "7", and '3pm' is 'the 15th hour'.
The minute is '0' (i.e. '0 minutes past three pm').
Doing the same thing, but only in February, would be:
`0 15 * 2 7`
### Variables
`cronie` doesn't know where you live, so to put something in your `$HOME` directory, you have to tell it:
```sh
echo "HOME=$HOME" > $filename
crontab -l >> $filename
crontab $filename
```
`cronie` doesn't know where anything lives, including programs.
You can give it your usual `$PATH` variable like this:
```sh
echo $PATH > $filename
crontab -l >> $filename
crontab $filename
```
Now instead of doing this
`40 */3 * * * /usr/bin/du -sh $HOME/* | sort -h > $HOME/sum.txt`
You can simply do this:
`40 */3 * * * du -sh $HOME/* | sort -h > $HOME/sum.txt`
## Run as Root
You can execute a script as root by putting it into a directory, instead of in the tab.
Look at the available cron directories:
```sh
ls -d /etc/cron.*
```
Make a script which runs daily:
```sh
f=apt_update.sh
echo '#!/bin/bash' > $f
echo 'apt update --yes' >> $f
chmod +x $f
sudo mv $f /etc/cron.daily/
```
### Testing with runparts
Run-parts runs all executable scripts in a directory.
```sh
run-parts /etc/cron.hourly
```
# Troubleshooting
### `date` Commands
Cron doesn't understand the `%` sign, so if you want to use `date +%R`, then it should be escaped with a backslash: `date +\%R`.

View File

@@ -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
View 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"
```

View File

@@ -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
```

View File

@@ -1,5 +1,5 @@
--- ---
title: "basic-install" title: "Install Arch"
tags: [ "arch" ] tags: [ "arch" ]
requires: [ "partitions", "time" ] requires: [ "partitions", "time" ]
--- ---

View 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>
```

View File

@@ -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

View File

@@ -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.

View 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.

View 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
```

View File

@@ -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
```

View 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
```

View File

@@ -0,0 +1,20 @@
---
title: "Clean Your Downloads"
tags: [ "system", "tmpfs" ]
---
'Downloads` directory always too full of crap?
Make it a temporary filesystem!
Everything will be deleted whenever you reboot.
```sh
rm -rf ~/Downloads # Be brave!
mkdir Downloads
cp /etc/fstab /tmp/
echo "tmpfs $HOME/Downloads tmpfs defaults,size=1G 0 0" | sudo tee -a /etc/fstab
sudo systemctl daemon-reload # Ignore this if you don't use systemd
sudo mount -a
mount | tail -1
```

View 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
```

View 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.
```

View 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`.

View 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
View 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 |

View File

@@ -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

View File

@@ -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`.